Skip to content

Repository files navigation

Angular Smart Data Table

@servicemind.tis/angular-smart-data-table is an Angular component library that provides a highly configurable and reusable smart table component for enterprise applications.


🌟 Features

  • Customizable columns and templates
  • Filter form integration with URL syncing
  • Column customization templates with API integration
  • Internationalization support (e.g., Transloco)
  • Custom row background styling
  • Built-in pagination and sorting
  • Dynamic slot and template injection for full control

🚀 Installation

npm install @servicemind.tis/angular-smart-data-table

Peer Dependencies

npm install @angular/material @angular/cdk

🔧 Usage Example

app.component.html

<ng-container *transloco="let t; read: 'serviceManagement.serviceRequestListComponent'">
  <angular-smart-data-table
    #mainTableWrapper
    [columnCustomizationUrlConfig]="columnCustomizationUrlConfig"
    [t]="t"
    componentName="cm-service-request"
    [mainTitle]="t('list')"
    [breadcrumbs]="[{url: '/admin/service-management/cases', name: t('breadcrumb')}]"
    [columnsCodeMapping]="columnsCodeMapping"
    [searchPlaceholder]="t('searchPlaceholder')"
    [loadDataApiBaseUrl]="loadDataApiBaseUrl"
    [(pageSize)]="pageSize"
    [(pageIndex)]="pageIndex"
    [hideHeader]="true"
    [rowsConfig]="rowsConfig"
    [filterFormGroup]="filterFormGroup"
    [keepFilterInUrl]="false"
    [dataNotFoundConfig]="{
        title: t('noDataFound'),
        desc: t('noDataFoundDescription'),
        btnText: t('addNew'),
        btnUrl: '/admin/service-management/cases/add'
    }"
  >
    <!-- Custom slots like filter buttons, filter section, templates, etc. -->
  </angular-smart-data-table>
</ng-container>

app.component.ts

import { Component, TemplateRef, ViewChild } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import {
  SmartTableWrapperColumnsConfig,
  SmartTableWrapperRowsConfig,
  AngularSmartDataTableComponent,
  ColumnCustomizationUrlConfig
} from 'angular-smart-data-table';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  @ViewChild('mainTableWrapper') tableListViewWrapperComponent!: AngularSmartDataTableComponent;

  columnsCodeMapping: SmartTableWrapperColumnsConfig[] = [
    { name: 'action', serverKeyCode: 'action', type: 'action', sort: false, template: this.actionColumnTemplate },
    { name: 'description', serverKeyCode: 'description', type: 'string', sort: true, template: this.descriptionColumnTemplate },
    { name: 'sourceOfRequest', serverKeyCode: 'sourceOfRequest', type: 'string', template: this.sourceOfReColumnTemplate },
    { name: 'status', serverKeyCode: 'cmStatusId', type: 'string', template: this.statusColumnTemplate },
    // Add more columns as needed...
  ];

  @ViewChild('actionColumnTemplate') set actionColumnTemplate(tpl: TemplateRef<any>) {
    this.setColumnTemplate('action', tpl);
  }
  @ViewChild('descriptionColumnTemplate') set descriptionColumnTemplate(tpl: TemplateRef<any>) {
    this.setColumnTemplate('description', tpl);
  }
  @ViewChild('sourceOfReColumnTemplate') set sourceOfReColumnTemplate(tpl: TemplateRef<any>) {
    this.setColumnTemplate('sourceOfRequest', tpl);
  }
  @ViewChild('statusColumnTemplate') set statusColumnTemplate(tpl: TemplateRef<any>) {
    this.setColumnTemplate('status', tpl);
  }

  filterFormGroup!: FormGroup;
  isShowFilter = false;
  pageSize = 10;
  pageIndex = 0;
  loadDataApiBaseUrl = 'https://mocki.io/v1/2f34e933-74dc-4433-83ac-b66991f7e472';
  columnCustomizationUrlConfig: ColumnCustomizationUrlConfig = {
    list: '/user-customization/get-columns-templates',
    add: '/user-customization/add-columns-template',
    update: '/user-customization/update-columns-template',
    delete: '/user-customization/delete-columns-template',
    getSelectedTemplate: '/user-customization/get-selected-columns-template',
    updateSelectedTemplate: '/user-customization/update-selected-columns-template'
  };

  rowsConfig: SmartTableWrapperRowsConfig = {
    backgroundApplyFunction: (row: any) => row.viewsCount === 0 ? '#f2f6fc' : null
  };

  ngOnInit() {
    this.filterFormGroup = new FormGroup({
      type: new FormControl(null)
    });
  }

  setColumnTemplate(name: string, template: TemplateRef<any>) {
    const col = this.columnsCodeMapping.find(c => c.name === name);
    if (col) col.template = template;
    this.columnsCodeMapping = [...this.columnsCodeMapping];
  }

  filterRecords() {
    this.tableListViewWrapperComponent.filterRecords();
    this.changeFilterVisibility();
  }

  changeFilterVisibility() {
    this.isShowFilter = !this.isShowFilter;
    this.tableListViewWrapperComponent.isShowFilter = this.isShowFilter;
  }

  onReset() {
    this.filterFormGroup.reset();
    this.filterRecords();
  }
}

🧠 Key Interfaces

SmartTableWrapperColumnsConfig

export interface SmartTableWrapperColumnsConfig {
    name: string;
    type: 'string' | 'number' | 'quantity' | 'money' | 'date' | 'date-time' | 'date-time-with-seconds' | 'action';
    align?: 'left' | 'right' | 'center' | null;
    serverKeyCode: string;
    valueKey?: string;
    template?: TemplateRef<any>;
    sort: boolean;
    clickFn?: (rec: any, event?: MouseEvent) => void;
    filterFormKey?: string;
    transformQueryParamFn?: Function;
}

SmartTableWrapperRowsConfig

export interface SmartTableWrapperRowsConfig {
    backgroundApplyFunction?: (row: any) => string | null;
}

SelectedFilterDisplayValueType

export type SelectedFilterDisplayValueType = {
    value: any | any[] | null;
    labelKey?: string | number | null;
    valueKey: any | null;
    formControlName: string;
    formControlType: 'input' | 'radio' | 'date' | 'date-time' | 'toggle' | 'checkbox' | 'chip' | 'select' | 'search-select';
    isSingleValue?: boolean;
    selectedObjData?: any;
};

SelectedFilterDisplayValuesType

export type SelectedFilterDisplayValuesType = SelectedFilterDisplayValueType[];

AnyKeyValueObject

export type AnyKeyValueObject = Record<string, any>;

SelectedFiltersGroupedValuesType

export type SelectedFiltersGroupedValuesType = {
    formControlName: string;
    formControlType: string;
    arrValues: SelectedFilterDisplayValueType[];
};

ColumnCustomizationUrlConfig

export interface ColumnCustomizationUrlConfig {
    list: string;
    add: string;
    update: string;
    delete: string;
    getSelectedTemplate: string;
    updateSelectedTemplate: string;
}

DataNotFoundConfig

export type DataNotFoundConfig = {
    title: string;
    desc: string;
    btnText?: string | null;
    btnUrl?: string | null;
    btnClick?: null | ((rec: any, event?: MouseEvent) => void);
    secondBtnText?: string | null;
    secondBtnUrl?: string | null;
    secondBtnClick?: null | ((rec: any, event?: MouseEvent) => void);
};

📦 Module Setup

Make sure to import AngularSmartDataTableModule and necessary Angular Material modules in your app module or standalone components.


🤝 Contributing

  1. Clone the repo
  2. Run npm install
  3. Use the demo app to test (projects/ directory)
  4. Submit a PR or issue with details

🚀 Publishing to npm

git tag v1.0.0
git push origin v1.0.0

GitHub Actions will build and publish to npm automatically if configured.


📬 Support / Questions

For bugs, suggestions, or feature requests, please open an issue on the GitHub repository.


Made with ❤️ by Thai Informatic Systems Co. Ltd

About

Configurable Angular Material data table — server-side pagination, sorting, URL-synced filters, column customization, custom cell templates.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages