@servicemind.tis/angular-smart-data-table 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -0
  3. package/fesm2022/servicemind.tis-angular-smart-data-table.mjs +3148 -0
  4. package/fesm2022/servicemind.tis-angular-smart-data-table.mjs.map +1 -0
  5. package/index.d.ts +5 -0
  6. package/lib/angular-smart-data-table.module.d.ts +38 -0
  7. package/lib/angular-smart-data-table.service.d.ts +6 -0
  8. package/lib/components/angular-columns-btn/angular-columns-btn.component.d.ts +39 -0
  9. package/lib/components/angular-smart-data-table/angular-smart-data-table.component.d.ts +205 -0
  10. package/lib/components/angular-smart-data-table-confirmation-dialog/angular-smart-data-table-confirmation-dialog.component.d.ts +10 -0
  11. package/lib/components/angular-smart-data-table-error-dialog/angular-smart-data-table-error-dialog.component.d.ts +10 -0
  12. package/lib/components/create-columns-template/create-columns-template.component.d.ts +42 -0
  13. package/lib/datasources/api.datasource.d.ts +18 -0
  14. package/lib/directives/scrolling/scrolling.directive.d.ts +11 -0
  15. package/lib/helpers/collection.helper.d.ts +92 -0
  16. package/lib/helpers/date-time.helper.d.ts +39 -0
  17. package/lib/helpers/filter-display.helper.d.ts +51 -0
  18. package/lib/helpers/query-params.helper.d.ts +47 -0
  19. package/lib/helpers/storage-helper.d.ts +3 -0
  20. package/lib/helpers/timeout-manager.helper.d.ts +72 -0
  21. package/lib/helpers/url.helper.d.ts +78 -0
  22. package/lib/helpers/validation.helper.d.ts +73 -0
  23. package/lib/interfaces/angular-selection-config.type.d.ts +16 -0
  24. package/lib/interfaces/data-not-found-config.type.d.ts +12 -0
  25. package/lib/interfaces/index.d.ts +4 -0
  26. package/lib/interfaces/smart-data-table-wrapper-columns-config.type.d.ts +38 -0
  27. package/lib/interfaces/url-config.type.d.ts +8 -0
  28. package/lib/pipes/angular-currency.pipe.d.ts +7 -0
  29. package/lib/pipes/angular-date-time-with-seconds.pipe.d.ts +7 -0
  30. package/lib/pipes/angular-date-time.pipe.d.ts +7 -0
  31. package/lib/pipes/angular-date.pipe.d.ts +7 -0
  32. package/lib/pipes/money.pipe.d.ts +9 -0
  33. package/lib/pipes/quantity.pipe.d.ts +9 -0
  34. package/lib/services/angular-helper.service.d.ts +17 -0
  35. package/lib/services/api.service.d.ts +11 -0
  36. package/lib/services/user-customization.service.d.ts +16 -0
  37. package/package.json +50 -0
  38. package/public-api.d.ts +4 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * TimeoutManager - A utility class for managing timeouts to prevent memory leaks
3
+ *
4
+ * This class provides a centralized way to create, track, and clean up setTimeout calls.
5
+ * It automatically handles cleanup when component is destroyed to prevent memory leaks.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * export class MyComponent implements OnDestroy {
10
+ * private timeoutManager = new TimeoutManager();
11
+ *
12
+ * someMethod() {
13
+ * this.timeoutManager.createTimeout(() => {
14
+ * console.log('Delayed execution');
15
+ * }, 1000);
16
+ * }
17
+ *
18
+ * ngOnDestroy() {
19
+ * this.timeoutManager.clearAll(); // Clean up all pending timeouts
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ export declare class TimeoutManager {
25
+ private activeTimeouts;
26
+ /**
27
+ * Creates a tracked timeout that will be automatically cleaned up
28
+ * @param callback - Function to execute after delay
29
+ * @param delay - Delay in milliseconds
30
+ * @returns The timeout ID (same as setTimeout return value)
31
+ */
32
+ createTimeout(callback: () => void, delay: number): ReturnType<typeof setTimeout>;
33
+ /**
34
+ * Manually clear a specific timeout
35
+ * @param timeoutId - The timeout ID returned from createTimeout
36
+ */
37
+ clearTimeout(timeoutId: ReturnType<typeof setTimeout>): void;
38
+ /**
39
+ * Clear all pending timeouts
40
+ * This should be called in ngOnDestroy to prevent memory leaks
41
+ */
42
+ clearAll(): void;
43
+ /**
44
+ * Get the number of active (pending) timeouts
45
+ * Useful for debugging and testing
46
+ */
47
+ get activeCount(): number;
48
+ /**
49
+ * Check if a specific timeout is still active
50
+ * @param timeoutId - The timeout ID to check
51
+ */
52
+ isActive(timeoutId: ReturnType<typeof setTimeout>): boolean;
53
+ }
54
+ /**
55
+ * Static helper functions for one-off timeout usage
56
+ * Use the TimeoutManager class for more comprehensive timeout management
57
+ */
58
+ export declare class TimeoutHelper {
59
+ /**
60
+ * Create a single tracked timeout with external cleanup responsibility
61
+ * @param callback - Function to execute after delay
62
+ * @param delay - Delay in milliseconds
63
+ * @param trackingSet - Set to track the timeout for cleanup
64
+ * @returns The timeout ID
65
+ */
66
+ static createTrackedTimeout(callback: () => void, delay: number, trackingSet: Set<ReturnType<typeof setTimeout>>): ReturnType<typeof setTimeout>;
67
+ /**
68
+ * Clear all timeouts in a tracking set
69
+ * @param trackingSet - Set containing timeout IDs to clear
70
+ */
71
+ static clearAllTimeouts(trackingSet: Set<ReturnType<typeof setTimeout>>): void;
72
+ }
@@ -0,0 +1,78 @@
1
+ import { Location } from '@angular/common';
2
+ import { Router } from '@angular/router';
3
+ /**
4
+ * Centralized URL and navigation utility helper.
5
+ * Provides common functions for URL manipulation and navigation.
6
+ */
7
+ export declare class UrlHelper {
8
+ /**
9
+ * Extracts the home URL from current window location
10
+ * @returns Home URL path
11
+ */
12
+ static getHomeUrl(): string;
13
+ /**
14
+ * Safely navigates to a URL if it's valid
15
+ * @param router - Angular Router instance
16
+ * @param url - URL to navigate to
17
+ * @returns Promise<boolean> - Navigation result
18
+ */
19
+ static safeNavigate(router: Router, url: string): Promise<boolean> | null;
20
+ /**
21
+ * Updates the browser URL without navigation using Location service
22
+ * @param location - Angular Location service
23
+ * @param baseUrl - Base URL path
24
+ * @param queryString - Query string parameters
25
+ */
26
+ static updateUrl(location: Location, baseUrl: string, queryString: string): void;
27
+ /**
28
+ * Builds a complete URL with query parameters
29
+ * @param baseUrl - Base URL path
30
+ * @param queryParams - URLSearchParams object
31
+ * @returns Complete URL string
32
+ */
33
+ static buildUrl(baseUrl: string, queryParams: URLSearchParams): string;
34
+ /**
35
+ * Gets the base URL without query parameters
36
+ * @param router - Angular Router instance
37
+ * @returns Base URL string
38
+ */
39
+ static getBaseUrl(router: Router): string;
40
+ /**
41
+ * Checks if current URL differs from generated URL
42
+ * @param generatedUrl - Generated URL to compare
43
+ * @returns True if URLs are different
44
+ */
45
+ static hasUrlChanged(generatedUrl: string): boolean;
46
+ /**
47
+ * Extracts query parameters from a URL string
48
+ * @param url - Full URL string
49
+ * @returns URLSearchParams object
50
+ */
51
+ static extractQueryParams(url: string): URLSearchParams | null;
52
+ /**
53
+ * Handles button click actions (URL navigation or callback execution)
54
+ * @param router - Angular Router instance
55
+ * @param config - Button configuration object
56
+ * @param primaryUrlKey - Primary URL property name (default: 'btnUrl')
57
+ * @param primaryClickKey - Primary click handler property name (default: 'btnClick')
58
+ */
59
+ static handleButtonClick(router: Router, config: any, primaryUrlKey?: string, primaryClickKey?: string): void;
60
+ /**
61
+ * Handles secondary button click actions
62
+ * @param router - Angular Router instance
63
+ * @param config - Button configuration object
64
+ */
65
+ static handleSecondaryButtonClick(router: Router, config: any): void;
66
+ /**
67
+ * Validates if a URL string is properly formatted
68
+ * @param url - URL to validate
69
+ * @returns True if URL is valid
70
+ */
71
+ static isValidUrl(url: string): boolean;
72
+ /**
73
+ * Safely encodes URL parameters
74
+ * @param value - Value to encode
75
+ * @returns Encoded string
76
+ */
77
+ static encodeParam(value: any): string;
78
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Centralized validation utility helper for common validation tasks.
3
+ * Provides reusable validation functions to avoid code duplication.
4
+ */
5
+ export declare class ValidationHelper {
6
+ /**
7
+ * Checks if a value is not null, undefined, or empty string
8
+ * @param value - Value to check
9
+ * @returns True if value has content
10
+ */
11
+ static hasValue(value: any): boolean;
12
+ /**
13
+ * Checks if any values in an object are non-empty
14
+ * @param obj - Object to check
15
+ * @returns True if any value is non-empty
16
+ */
17
+ static hasNonEmptyValue(obj: any): boolean;
18
+ /**
19
+ * Checks if a form has any non-empty values
20
+ * @param formData - Form data object
21
+ * @returns True if form has any data
22
+ */
23
+ static hasFormData(formData: any): boolean;
24
+ /**
25
+ * Validates if an array has items
26
+ * @param array - Array to check
27
+ * @returns True if array exists and has items
28
+ */
29
+ static hasItems(array: any[]): boolean;
30
+ /**
31
+ * Checks if a URL is valid
32
+ * @param url - URL string to validate
33
+ * @returns True if URL is valid
34
+ */
35
+ static isValidUrl(url: string): boolean;
36
+ /**
37
+ * Validates if a string is a valid number
38
+ * @param value - Value to check
39
+ * @returns True if value is a valid number
40
+ */
41
+ static isValidNumber(value: any): boolean;
42
+ /**
43
+ * Checks if an object has a specific property with a valid value
44
+ * @param obj - Object to check
45
+ * @param property - Property name
46
+ * @returns True if property exists and has a value
47
+ */
48
+ static hasProperty(obj: any, property: string): boolean;
49
+ /**
50
+ * Validates if a selection model row has the required key
51
+ * @param row - Row object
52
+ * @param keyName - Key property name
53
+ * @returns True if row has the key property with a value
54
+ */
55
+ static hasRowKey(row: any, keyName: string): boolean;
56
+ /**
57
+ * Checks if a filter value should be processed (not null, empty, or invalid)
58
+ * @param value - Filter value
59
+ * @returns True if filter value is valid for processing
60
+ */
61
+ static isValidFilterValue(value: any): boolean;
62
+ /**
63
+ * Validates pagination parameters
64
+ * @param pageIndex - Page index
65
+ * @param pageSize - Page size
66
+ * @returns Object with validation results
67
+ */
68
+ static validatePagination(pageIndex: any, pageSize: any): {
69
+ isValid: boolean;
70
+ pageIndex: number;
71
+ pageSize: number;
72
+ };
73
+ }
@@ -0,0 +1,16 @@
1
+ export type SelectedFilterDisplayValueType = {
2
+ value: any | any[] | null;
3
+ labelKey?: string | number | null;
4
+ valueKey: any | null;
5
+ formControlName: string;
6
+ formControlType: 'input' | 'radio' | 'date' | 'date-time' | 'toggle' | 'checkbox' | 'chip' | 'select' | 'search-select';
7
+ isSingleValue?: boolean;
8
+ selectedObjData?: any;
9
+ };
10
+ export type SelectedFilterDisplayValuesType = SelectedFilterDisplayValueType[];
11
+ export type AnyKeyValueObject = Record<string, any>;
12
+ export type SelectedFiltersGroupedValuesType = {
13
+ formControlName: string;
14
+ formControlType: string;
15
+ arrValues: SelectedFilterDisplayValueType[];
16
+ };
@@ -0,0 +1,12 @@
1
+ export type DataNotFoundConfig = {
2
+ title: string;
3
+ desc?: string;
4
+ /** Optional custom icon/image URL. If provided, this image will be displayed instead of the default SVG. */
5
+ iconUrl?: string | null;
6
+ btnText?: string | null;
7
+ btnUrl?: string | null;
8
+ btnClick?: null | ((rec: any, event?: MouseEvent) => void);
9
+ secondBtnText?: string | null;
10
+ secondBtnUrl?: string | null;
11
+ secondBtnClick?: null | ((rec: any, event?: MouseEvent) => void);
12
+ };
@@ -0,0 +1,4 @@
1
+ export * from './smart-data-table-wrapper-columns-config.type';
2
+ export * from './angular-selection-config.type';
3
+ export * from './data-not-found-config.type';
4
+ export * from './url-config.type';
@@ -0,0 +1,38 @@
1
+ import { TemplateRef } from "@angular/core";
2
+ export interface SmartTableWrapperColumnsConfig {
3
+ name: string;
4
+ columnName?: string;
5
+ columnDef?: string;
6
+ type: 'string' | 'number' | 'quantity' | 'money' | 'date' | 'date-time' | 'date-time-with-seconds' | 'action' | 'expand';
7
+ align?: 'left' | 'right' | 'center' | null;
8
+ serverKeyCode: string;
9
+ valueKey?: string;
10
+ template?: TemplateRef<any>;
11
+ sort: boolean;
12
+ clickFn?: (rec: any, event?: MouseEvent) => void;
13
+ /** Function that returns routerLink value - enables right-click "Open in new tab" */
14
+ linkFn?: (row: any) => string | any[];
15
+ filterFormKey?: string;
16
+ transformQueryParamFn?: Function;
17
+ }
18
+ /**
19
+ * Maps column value types to their custom format strings.
20
+ * - For 'date' / 'date-time' / 'date-time-with-seconds': Luxon format string (e.g. 'yyyy/MM/dd', 'dd-MM-yyyy HH:mm')
21
+ * - For 'quantity': Angular DecimalPipe digitsInfo string (e.g. '1.2-2', '1.0-0')
22
+ * - For 'money': number of decimal places (e.g. '4', '0')
23
+ * - For 'number': Angular DecimalPipe digitsInfo string
24
+ * - For 'string': unused (reserved for future use)
25
+ *
26
+ * Example:
27
+ * {
28
+ * 'date': 'yyyy/MM/dd',
29
+ * 'date-time': 'dd-MM-yyyy HH:mm',
30
+ * 'money': '2',
31
+ * 'quantity': '1.4-4',
32
+ * 'number': '1.1-1'
33
+ * }
34
+ */
35
+ export type ColumnValueTypeFormats = Partial<Record<'number' | 'quantity' | 'money' | 'date' | 'date-time' | 'date-time-with-seconds', string>>;
36
+ export interface SmartTableWrapperRowsConfig {
37
+ backgroundApplyFunction?: (row: any) => string | null;
38
+ }
@@ -0,0 +1,8 @@
1
+ export interface ColumnCustomizationUrlConfig {
2
+ list: string;
3
+ add: string;
4
+ update: string;
5
+ delete: string;
6
+ getSelectedTemplate: string;
7
+ updateSelectedTemplate: string;
8
+ }
@@ -0,0 +1,7 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AngularCurrencyPipe implements PipeTransform {
4
+ transform(value: number | string | null | undefined, decimals?: number | string): string;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<AngularCurrencyPipe, never>;
6
+ static ɵpipe: i0.ɵɵPipeDeclaration<AngularCurrencyPipe, "angularCurrency", false>;
7
+ }
@@ -0,0 +1,7 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AngularDateTimeWithSecondsPipe implements PipeTransform {
4
+ transform(value: unknown, format?: string): string;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<AngularDateTimeWithSecondsPipe, never>;
6
+ static ɵpipe: i0.ɵɵPipeDeclaration<AngularDateTimeWithSecondsPipe, "angularDateTimeWithSeconds", false>;
7
+ }
@@ -0,0 +1,7 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AngularDateTimePipe implements PipeTransform {
4
+ transform(value: unknown, format?: string): string;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<AngularDateTimePipe, never>;
6
+ static ɵpipe: i0.ɵɵPipeDeclaration<AngularDateTimePipe, "angularDateTime", false>;
7
+ }
@@ -0,0 +1,7 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class AngularDatePipe implements PipeTransform {
4
+ transform(value: unknown, format?: string): string;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<AngularDatePipe, never>;
6
+ static ɵpipe: i0.ɵɵPipeDeclaration<AngularDatePipe, "angularDate", false>;
7
+ }
@@ -0,0 +1,9 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class Money implements PipeTransform {
4
+ decimalPoints: number;
5
+ transform(value: number | string): any;
6
+ roundNumber(number: number, decimals?: number): number;
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<Money, never>;
8
+ static ɵpipe: i0.ɵɵPipeDeclaration<Money, "money", false>;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class Quantity implements PipeTransform {
4
+ decimalPoints: number;
5
+ transform(value: number | string): any;
6
+ roundNumber(number: number, decimals?: number): number;
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<Quantity, never>;
8
+ static ɵpipe: i0.ɵɵPipeDeclaration<Quantity, "qty", false>;
9
+ }
@@ -0,0 +1,17 @@
1
+ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
2
+ import { MatDialog, MatDialogRef } from '@angular/material/dialog';
3
+ import { MatSnackBar, MatSnackBarRef, TextOnlySnackBar } from '@angular/material/snack-bar';
4
+ import { AngularSmartDataTableErrorDialogComponent } from '../components/angular-smart-data-table-error-dialog/angular-smart-data-table-error-dialog.component';
5
+ import * as i0 from "@angular/core";
6
+ export declare class AngularHelperService {
7
+ private snackBar;
8
+ private dialog;
9
+ private http;
10
+ constructor(snackBar: MatSnackBar, dialog: MatDialog, http: HttpClient);
11
+ showHttpErrorMsg(error: HttpErrorResponse, duration?: number): MatDialogRef<AngularSmartDataTableErrorDialogComponent, any> | MatSnackBarRef<TextOnlySnackBar>;
12
+ showSuccessMsg(message: string, title: string, duration?: number): void;
13
+ showErrorMsg(message: string, title: string, duration?: number): void;
14
+ sortArrayByOrder(A: string[], B: string[]): string[];
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<AngularHelperService, never>;
16
+ static ɵprov: i0.ɵɵInjectableDeclaration<AngularHelperService>;
17
+ }
@@ -0,0 +1,11 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ export declare class ApiService {
5
+ private http;
6
+ private token;
7
+ constructor(http: HttpClient);
8
+ getList(apiUrl: string, currentPage?: number, limit?: number, search?: string, filters?: object, sortFilter?: object): Observable<any>;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<ApiService, never>;
10
+ static ɵprov: i0.ɵɵInjectableDeclaration<ApiService>;
11
+ }
@@ -0,0 +1,16 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ export declare class UserCustomizationService {
5
+ private http;
6
+ private token;
7
+ constructor(http: HttpClient);
8
+ getColumnsTemplates(url: string, listComponent: string): Observable<any>;
9
+ addColumnsTemplate(url: string, body: any): Observable<any>;
10
+ updateColumnsTemplate(url: string, body: any): Observable<any>;
11
+ deleteColumnsTemplate(url: string, body: any): Observable<any>;
12
+ getSelectedColumnsTemplate(url: string, listComponent: string): Observable<any>;
13
+ updateSelectedColumnsTemplate(url: string, body: any): Observable<any>;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserCustomizationService, never>;
15
+ static ɵprov: i0.ɵɵInjectableDeclaration<UserCustomizationService>;
16
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@servicemind.tis/angular-smart-data-table",
3
+ "version": "1.0.0",
4
+ "description": "Configurable Angular Material data table with server-side pagination, sorting, URL-synced filters, column customization, and custom cell templates.",
5
+ "keywords": [
6
+ "angular",
7
+ "angular-material",
8
+ "data-table",
9
+ "datatable",
10
+ "table",
11
+ "pagination",
12
+ "sorting",
13
+ "filtering",
14
+ "column-customization"
15
+ ],
16
+ "author": "Thai Informatics System",
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/Thai-Informatics-System/angular-smart-data-table.git"
21
+ },
22
+ "homepage": "https://github.com/Thai-Informatics-System/angular-smart-data-table#readme",
23
+ "bugs": {
24
+ "url": "https://github.com/Thai-Informatics-System/angular-smart-data-table/issues"
25
+ },
26
+ "peerDependencies": {
27
+ "@angular/common": "^19.2.0",
28
+ "@angular/core": "^19.2.0",
29
+ "@angular/material": "^19.2.8",
30
+ "@angular/cdk": "^19.2.8"
31
+ },
32
+ "dependencies": {
33
+ "tslib": "^2.3.0"
34
+ },
35
+ "sideEffects": false,
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "module": "fesm2022/servicemind.tis-angular-smart-data-table.mjs",
40
+ "typings": "index.d.ts",
41
+ "exports": {
42
+ "./package.json": {
43
+ "default": "./package.json"
44
+ },
45
+ ".": {
46
+ "types": "./index.d.ts",
47
+ "default": "./fesm2022/servicemind.tis-angular-smart-data-table.mjs"
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,4 @@
1
+ export * from './lib/angular-smart-data-table.service';
2
+ export * from './lib/angular-smart-data-table.module';
3
+ export * from './lib/components/angular-smart-data-table/angular-smart-data-table.component';
4
+ export * from './lib/interfaces';