tips-mat-table

tips-mat-table is an Angular component for presenting large and complex data with a lightning fast performance (at least 10x faster) and excellent level of control over the presentation.

Usage no npm install needed!

<script type="module">
  import tipsMatTable from 'https://cdn.skypack.dev/tips-mat-table';
</script>

README

tips-mat-table

Dynamic tables built with Angular Material.

Online Demo

Version(1.0.0-alpha): https://stackblitz.com/edit/angular-ivy-d1dy7p

Getting Started

A full demo can be found on the github repository.

Install with npm:

npm i tips-mat-table

After installation include TipsMatTableModule in your module imports:

import { TipsMatTableModule } from 'tips-mat-table';
...
imports: [
    TipsMatTableModule
  ],
...

Column types are defined as follow:

export interface AbstractField {
  index?: number;
  name: string; // The key of the data
  type?: "text" | "number" | "date" | "category"; // Type of data in the field
  width?: number; // width of column
  header?: string; // The title of the column
  print?: boolean; // disply in printing view by defualt is true
  isKey?: boolean;
  inlineEdit?: boolean;
  display?: "visible" | "hiden" | "prevent-hidden"; // Hide and visible this column
  sticky?: "start" | "end" | "none"; // sticky this column to start or end
  filter?: "client-side" | "server-side" | "none";
  sort?: "client-side" | "server-side" | "none";
  cellClass?: string; // Apply a class to a cell, class name must be in the data
  classNames?: string;
  rowClass?: string | AtClassFunc;
  customSortFunction?: AtSortFunc<R>;
  customFilterFunction?: AtSortFunc<R>;
  toPrint?: ToPrint;
  toExport?: ToExport;
  inputFieldConfig?: InputFieldConfig;
  btnGroupConfig?: BtnGroupConfig;
}

Source data must be an TableVirtualScrollDataSource:

let data = [
  { "row": 1, "name": "Element #4", "weight": "65 KG", "color": "Magenta", "brand": "Zanjan Benz", "type": "Van" }, ...];

this.dataSource = new BehaviorSubject<any[]>(data);

In the HTML add the selector:

<tips-mat-table
  tableName="Tips Mat Table"
  [columns]="fields"
  [dataSource]="dataSourcequot;
  [pending]="pending"
  [tableSetting]="tableSetting"
  [rowContextMenuItems]="contextMenuItems"
  [rowActionMenuItems]="contextMenuItems"
  [toolbarItems]="toolbarItems"
  [pagination]="pagination"
  [rowSelectionMode]="rowSelectionMode"
  [rowSelectionModel]="selectionModel"
  (onTableEvent)="tableEvent($event)"
>
</tips-mat-table>

Inputs:

columns = Column definitions dataSource = Table data in BehaviorSubject pending = pending progress on table rowSelectionMode = active selection row ('single' | 'multi' | 'none') rowSelectionModel = new SelectionModel() from Angular Material Select pagination = configuration for pagination. eg: { pageIndex: 0, pageSize: 10, pageSizeOptions: [ 5, 10, 100, 1000], length:30 } tableSetting = many general setting of table include styles and features configuration rowContextMenuItems = a menu that shown in right click rowActionMenuItems = a menu that shown in end of the row in ActionMenu toolbarItems = at the footer of table, with right configuration it can be very usefull

onTableEvent = all the events of table witch included in TableEvents enum can be listen from this event

this.rowActionMenuItems = [
  {
    name: "Edit",
    text: "Edit",
    color: "primary",
    icon: "edit",
    disabled: false,
    visible: true,
  },
  {
    name: "Delete",
    text: "Delete Record",
    color: "warn",
    icon: "delete",
    disabled: false,
    visible: true,
  },
];

For more examples run the demo application.

How to add international

to support new language you must declare new class and implement LanguagePack for example this is persian language:

import { MatPaginatorIntl } from "@angular/material/paginator";
import {
  FilterLabels,
  LanguagePack,
  MenuLabels,
  TableLabels,
} from "tips-mat-table";
export class PersionLanguage implements LanguagePack {
  constructor() {}

  menuLabels: MenuLabels = {
    saveData: "ذخیره داده ها ",
    columnSetting: "تنظیمات ستون ها ",
    saveTableSetting: "ذخیره  تنظیمات جدول",
    clearFilter: "فیلتر را پاک کنید",
    jsonFile: "Json فایل",
    csvFile: "CSV فایل",
    printTable: "چاپ جدول",
    filterMode: "نوع فیلتر",
    filterLocalMode: "محلی",
    filterServerMode: "سرور",
    sortMode: "حالت مرتب سازی",
    sortLocalMode: "سمت کاربر",
    sortServerMode: "سمت سرور",
    printMode: "حالت چاپ",
    printYesMode: "بله",
    printNoMode: "خیر",
    pinMode: "حالت پین ",
    pinNoneMode: "هیچ کدام",
    pinStartMode: "شروع",
    pinEndMode: "پایان",
  };

  paginatorLabels: MatPaginatorIntl = {
    changes: null,
    itemsPerPageLabel: "ایتم های هر صفحه:",
    nextPageLabel: "صفحه بعدی:",
    previousPageLabel: "صفحه قبلی:",
    firstPageLabel: "اولین صفحه:",
    lastPageLabel: "آخرین صفحه:",
    getRangeLabel: (page: number, pageSize: number, length: number) => {
      if (length === 0 || pageSize === 0) {
        return `0 از ${length}`;
      }
      length = Math.max(length, 0);
      const startIndex = page * pageSize;
      const endIndex =
        startIndex < length
          ? Math.min(startIndex + pageSize, length)
          : startIndex + pageSize;
      return `${startIndex + 1} - ${endIndex} از ${length}`;
    },
  };

  tableLabels: TableLabels = {
    NoData: "هیچ رکوردی پیدا نشد",
  };

  filterLabels: FilterLabels = {
    Clear: "پاک کردن",
    Search: "جستجو",
    And: "و",
    Or: "یا",
    /* Text Compare */
    Text: "متن",
    TextContains: "دربرگرفتن",
    TextEmpty: "خالی بودن",
    TextStartsWith: "شروع شدن با",
    TextEndsWith: " پایان گرفتن با",
    TextEquals: "مساوی بودن",
    TextNotEmpty: "خالی نبودن",
    /* Number Compare */
    Number: "تعداد",
    NumberEquals: "مساوی",
    NumberNotEquals: "مساوی نبودن",
    NumberGreaterThan: " بزرگ تر از",
    NumberLessThan: "کم تر از ",
    NumberEmpty: "خالی بودن",
    NumberNotEmpty: "خالی نبودن",
    /* Category List Compare */
    CategoryContains: "در برگرفتن",
    CategoryNotContains: "در بر نگرفتن",
    /* Boolean Compare */
    /* Date Compare */
  };
}

and passed this class to grid so :

providers: [{ provide: TableIntl, useFactory: languageIntl }];

And

export function languageIntl() {
  return new PersionLanguage();
}

Table Events

you can use this switch to handle all events from onTableEvent (remove those you dont need :))

export enum TableEvents {
  MasterSelectionChange = "MasterSelectionChange",
  RowSelectionChange = "RowSelectionChange",
  RowActionMenu = "RowActionMenu",
  ReloadData = "ReloadData",
  RowClick = "RowClick",
  CellClick = "CellClick",
  DblRowClick = "DblRowClick",
  DblCellClick = "DblCellClick",
  BeforContextMenuOpen = "BeforContextMenuOpen",
  BeforActionMenuOpen = "BeforActionMenuOpen",
  ContextMenuClick = "ContextMenuClick",
  SortChanged = "SortChanged",
  FormFieldCellEvent = "FormFieldCellEvent",
  validatonChange = "validatonChange",
  settingChange = "settingChange",
  ToolbarItemEvent = "ToolbarItemEvent",
  PaginationEvent = "PaginationEvent",
  BtnGroupCellEvent = "BtnGroupCellEvent",
}

FormField Cell

you can also add rows with a inline form or just edit a cell with giving this config to you column definition

export interface InputFieldConfig {
  // neccesseries
  id: string;
  fieldType: FormElementType;
  //view related
  icon?: string;
  label?: string;
  class?: string;
  styles?: any;
  appearance?: MatFormFieldAppearance;
  floatLabel?: FloatLabelType;
  hideRequiredMarker?: boolean;
  hideClearBtn?: boolean;
  convertor?: (id: any, row: any, column: any) => string;
  //model related
  // startMode?: boolean;
  //validators
  min?: any;
  max?: any;
  inputType?: InputType;
  //field states
  disabled?: boolean;
  required?: boolean;
  readonly?: boolean;
  defaultValue?: any;
  //messages
  hint?: string;
  error?: string;
  placeholder?: string;
  //events
  blur?: (event: any) => void;
  click?: (event: any) => void;
  input?: (event: any) => void;
  keyup?: (event: any) => void;
  change?: (event: any) => void;
  //for select field
  options?: Observable<Partial<{ value: any, label: string }>[]>;
  onSelectItem?: (item: any) => void;
  valueProp?: string;
  labelProp?: string;
  multiple?: boolean;
  // + for auto-complete field
  endTyping?: (searched: any) => void;
  // + for multi-column-autocomplete
  columnsConfig?: ColumnConfig[];
  onRowEvent?: (event: any) => void; //(not fully developed yet!)
  onFooterEvent?: (event: any) => void; //(not fully developed yet!)
}

this is all the types that we support until now

export type FormElementType =
  | "input" // simple input
  | "select"
  | "auto-complete"
  | "datepicker"
  | "mc-auto-complete"; //select with multi column (not fully developed yet!)

Button Group Cell

you can have one cell with many mat-icon-button to do some actions on row, it will give you the event with row and action

export interface BtnGroupConfig {
  click?: (event: any) => void;
  btnConfigs?: CellBtnConfig[];
}

export interface CellBtnConfig {
  id: string;
  tooltip?: string;
  showMode?: "edit" | "show" | "always";
  color?: ThemePalette;
  icon?: string;
  styles?: any;
  disabledFn?: (row: any) => boolean;
}

Toolbar Buttons

you can have one diffrent types of buttons with custom styles and config

export interface ToolbarItem {
  id: any;
  tooltip?: string; //used as title too
  disabled?: boolean;
  hidden?: boolean;
  styles?: any;
  icon?: string;
  btnType?:
    | "mat-button"
    | "mat-raised-button"
    | "mat-flat-button"
    | "mat-stroked-button"
    | "mat-icon-button"
    | "mat-fab"
    | "mat-mini-fab"; //default
}

additional Setting with TableSetting

you can customize your table on many aspects to suit your needs and desires with the Power implemented in TableSetting

export interface TableSetting {
  direction?: Direction;
  columnSetting?: AbstractField[];
  visibaleActionMenu?: VisibleActionMenu;
  stickyActionMenu?: boolean;
  visibleTableMenu?: boolean;
  alternativeRowStyle?: any;
  normalRowStyle?: any;
  rowStyle?: any;
  enableContextMenu?: boolean;
  headerStyles?: DmtHeaderStyles;
  ActionMenuMode?: "hover" | "menu";
  tableBackgroundColor?: string;
  paginatorLabels?: DmtpaginatorLabels;
  defaultWidth?: number;
  minWidth?: number;
  headerHeight?: number;
  rowHeight?: number;
  showNoData?: boolean;
  showReload?: boolean;
  printConfig?: PrintConfig;
  tableName?: string;
  showPagination?: boolean;
}

and you can specifically style headers with DmtHeaderStyles

export interface DmtHeaderStyles {
  headerFontSize?: string;
  headerColor?: string;
  headerJustify?: "center" | "flex-start" | "flex-end";
  headerBackgroundColor?: string;
}