commons-shared-web-ui 0.0.2 → 0.0.3

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.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { NgModule, EventEmitter, Output, Input, Component, HostListener, forwardRef } from '@angular/core';
2
+ import { NgModule, EventEmitter, Output, Input, Component, HostListener, forwardRef, inject, LOCALE_ID, ViewChildren } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
4
+ import { CommonModule, formatDate } from '@angular/common';
5
5
  import { MatCardModule } from '@angular/material/card';
6
6
  import * as i2$1 from '@angular/material/snack-bar';
7
7
  import { MatSnackBarModule } from '@angular/material/snack-bar';
@@ -44,7 +44,9 @@ import * as i1$2 from '@angular/forms';
44
44
  import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms';
45
45
  import * as i1$1 from '@angular/router';
46
46
  import * as i3 from '@angular/common/http';
47
- import { HttpClientModule } from '@angular/common/http';
47
+ import { HttpParams } from '@angular/common/http';
48
+ import { debounceTime, distinctUntilChanged, map, finalize, catchError } from 'rxjs/operators';
49
+ import { Subject, forkJoin, of } from 'rxjs';
48
50
 
49
51
  class MaterialModule {
50
52
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -1553,12 +1555,10 @@ class ConfigurableFormModule {
1553
1555
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigurableFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1554
1556
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: ConfigurableFormModule, imports: [CommonModule,
1555
1557
  ReactiveFormsModule,
1556
- HttpClientModule,
1557
1558
  MaterialModule,
1558
1559
  ConfigurableFormComponent], exports: [ConfigurableFormComponent] });
1559
1560
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigurableFormModule, imports: [CommonModule,
1560
1561
  ReactiveFormsModule,
1561
- HttpClientModule,
1562
1562
  MaterialModule,
1563
1563
  ConfigurableFormComponent] });
1564
1564
  }
@@ -1569,7 +1569,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1569
1569
  imports: [
1570
1570
  CommonModule,
1571
1571
  ReactiveFormsModule,
1572
- HttpClientModule,
1573
1572
  MaterialModule,
1574
1573
  ConfigurableFormComponent
1575
1574
  ],
@@ -2033,6 +2032,508 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
2033
2032
  }]
2034
2033
  }] });
2035
2034
 
2035
+ class SmartTableComponent {
2036
+ http;
2037
+ router;
2038
+ cdr;
2039
+ ngZone;
2040
+ config;
2041
+ action = new EventEmitter();
2042
+ topAction = new EventEmitter(); // For top bar buttons
2043
+ filterChange = new EventEmitter();
2044
+ rowSelect = new EventEmitter();
2045
+ data = [];
2046
+ totalItems = 0;
2047
+ currentPage = 1;
2048
+ loading = false;
2049
+ // State
2050
+ activeSort = { key: '', direction: 'ASC' };
2051
+ activeFilters = {};
2052
+ searchTerm = '';
2053
+ selectedRows = [];
2054
+ stickyColumnStyles = {};
2055
+ hasStickyColumns = false;
2056
+ searchSubject = new Subject();
2057
+ stickyHeaders;
2058
+ resizeObserver = null;
2059
+ locale = inject(LOCALE_ID);
2060
+ constructor(http, router, cdr, ngZone) {
2061
+ this.http = http;
2062
+ this.router = router;
2063
+ this.cdr = cdr;
2064
+ this.ngZone = ngZone;
2065
+ // Debounce search input
2066
+ this.searchSubject.pipe(debounceTime(this.config?.searchConfig?.debounceTime || 300), distinctUntilChanged()).subscribe(term => {
2067
+ this.searchTerm = term;
2068
+ this.currentPage = 1;
2069
+ this.loadData();
2070
+ });
2071
+ }
2072
+ ngOnInit() {
2073
+ if (this.config) {
2074
+ if (this.config.sortBy) {
2075
+ this.activeSort.key = this.config.sortBy;
2076
+ }
2077
+ if (this.config.orderBy) {
2078
+ this.activeSort.direction = this.config.orderBy;
2079
+ }
2080
+ this.loadFilterOptions();
2081
+ this.loadData();
2082
+ }
2083
+ }
2084
+ ngOnChanges(changes) {
2085
+ if (changes['config'] && !changes['config'].firstChange) {
2086
+ this.loadFilterOptions();
2087
+ this.loadData();
2088
+ setTimeout(() => this.calculateStickyPositions());
2089
+ }
2090
+ }
2091
+ ngAfterViewInit() {
2092
+ this.setupResizeObserver();
2093
+ }
2094
+ ngOnDestroy() {
2095
+ if (this.resizeObserver) {
2096
+ this.resizeObserver.disconnect();
2097
+ }
2098
+ }
2099
+ setupResizeObserver() {
2100
+ if (this.resizeObserver) {
2101
+ this.resizeObserver.disconnect();
2102
+ }
2103
+ this.resizeObserver = new ResizeObserver(() => {
2104
+ this.ngZone.run(() => {
2105
+ this.calculateStickyPositions();
2106
+ });
2107
+ });
2108
+ if (this.stickyHeaders) {
2109
+ this.stickyHeaders.changes.subscribe(() => {
2110
+ this.observeHeaders();
2111
+ // Also recalculate immediately
2112
+ setTimeout(() => this.calculateStickyPositions());
2113
+ });
2114
+ this.observeHeaders();
2115
+ }
2116
+ }
2117
+ observeHeaders() {
2118
+ if (!this.resizeObserver || !this.stickyHeaders)
2119
+ return;
2120
+ this.stickyHeaders.forEach(header => {
2121
+ this.resizeObserver.observe(header.nativeElement);
2122
+ });
2123
+ }
2124
+ loadData() {
2125
+ if (!this.config?.apiUrl)
2126
+ return;
2127
+ this.loading = true;
2128
+ let params;
2129
+ // --- Query Params Construction ---
2130
+ if (this.config.queryParamsConfig) {
2131
+ const qpConfig = this.config.queryParamsConfig;
2132
+ const pageKey = qpConfig.pageKey || 'page';
2133
+ const sizeKey = qpConfig.sizeKey || 'pageSize';
2134
+ const pageIndex = this.currentPage + (qpConfig.pageIndexOffset || 0);
2135
+ let paramsObj = {
2136
+ [pageKey]: pageIndex.toString(),
2137
+ [sizeKey]: (this.config.pagination?.pageSize || 10).toString()
2138
+ };
2139
+ if (this.activeSort.key)
2140
+ paramsObj['sortBy'] = this.activeSort.key;
2141
+ // Note: Some APIs might use different keys for sort/order, can be extended later if needed
2142
+ if (this.activeSort.direction)
2143
+ paramsObj['orderBy'] = this.activeSort.direction;
2144
+ // Search Handling
2145
+ if (this.searchTerm) {
2146
+ const searchConfig = this.config.searchConfig;
2147
+ const searchKey = searchConfig?.searchKey || 'search';
2148
+ if (searchConfig?.handling === 'nested_string' && qpConfig.nestedStringConfig) {
2149
+ // Will be handled in nested string construction below
2150
+ }
2151
+ else {
2152
+ paramsObj[searchKey] = this.searchTerm;
2153
+ }
2154
+ }
2155
+ // Filter Handling (and Search if nested)
2156
+ if (qpConfig.filterHandling === 'nested_string' && qpConfig.nestedStringConfig) {
2157
+ const { paramName, baseValue, separator, assignment } = qpConfig.nestedStringConfig;
2158
+ let nestedString = baseValue || '';
2159
+ const assign = assignment || '=';
2160
+ // Add Filters
2161
+ Object.keys(this.activeFilters).forEach(key => {
2162
+ if (this.activeFilters[key]) {
2163
+ const prefix = nestedString ? separator : '';
2164
+ nestedString += `${prefix}${key}${assign}${this.activeFilters[key]}`;
2165
+ }
2166
+ });
2167
+ // Add Search if nested
2168
+ if (this.searchTerm && this.config.searchConfig?.handling === 'nested_string') {
2169
+ const searchKey = this.config.searchConfig.searchKey || 'SEARCH_TERM';
2170
+ const prefix = nestedString ? separator : '';
2171
+ nestedString += `${prefix}${searchKey}${assign}${this.searchTerm}`;
2172
+ }
2173
+ paramsObj[paramName] = nestedString;
2174
+ }
2175
+ else {
2176
+ // Standard handling
2177
+ Object.keys(this.activeFilters).forEach(key => {
2178
+ if (this.activeFilters[key])
2179
+ paramsObj[key] = this.activeFilters[key];
2180
+ });
2181
+ }
2182
+ params = new HttpParams({ fromObject: paramsObj });
2183
+ }
2184
+ else {
2185
+ // --- Default Behavior (Backward Compatibility) ---
2186
+ let paramsObj = {};
2187
+ if (this.config.pagination?.enabled) {
2188
+ paramsObj['page'] = this.currentPage;
2189
+ paramsObj['pageSize'] = this.config.pagination.pageSize;
2190
+ }
2191
+ if (this.activeSort.key) {
2192
+ paramsObj['sortBy'] = this.activeSort.key;
2193
+ paramsObj['orderBy'] = this.activeSort.direction;
2194
+ }
2195
+ if (this.searchTerm) {
2196
+ const searchKey = this.config.searchConfig?.searchKey || 'search';
2197
+ paramsObj[searchKey] = this.searchTerm;
2198
+ }
2199
+ Object.keys(this.activeFilters).forEach(key => {
2200
+ if (this.activeFilters[key]) {
2201
+ paramsObj[key] = this.activeFilters[key];
2202
+ }
2203
+ });
2204
+ // Custom Request Params Mapper (if provided)
2205
+ if (this.config.requestParams) {
2206
+ const customParams = this.config.requestParams(this.currentPage, this.config.pagination?.pageSize || 10, this.activeSort.key, this.activeSort.direction, this.searchTerm, this.activeFilters);
2207
+ if (customParams instanceof HttpParams) {
2208
+ // If function returns HttpParams, use it directly (caveat: might lose previous params if not careful in mapper)
2209
+ params = customParams;
2210
+ }
2211
+ else {
2212
+ paramsObj = { ...paramsObj, ...customParams };
2213
+ params = new HttpParams({ fromObject: paramsObj });
2214
+ }
2215
+ }
2216
+ else {
2217
+ params = new HttpParams({ fromObject: paramsObj });
2218
+ }
2219
+ }
2220
+ // --- Data Fetching ---
2221
+ // Check for separate count API
2222
+ const totalCountConfig = this.config.pagination?.totalCountConfig;
2223
+ let request$; // Observable
2224
+ if (totalCountConfig?.source === 'separate' && totalCountConfig.apiUrl) {
2225
+ request$ = forkJoin({
2226
+ data: this.http.get(this.config.apiUrl, { params }),
2227
+ count: this.http.get(totalCountConfig.apiUrl, { params })
2228
+ }).pipe(map(({ data, count }) => {
2229
+ const dataPath = this.config.dataResponsePath !== undefined ? this.config.dataResponsePath : '';
2230
+ return {
2231
+ data: this.getValueByPath(data, dataPath),
2232
+ total: this.getValueByPath(count, totalCountConfig.responsePath || '')
2233
+ };
2234
+ }));
2235
+ }
2236
+ else {
2237
+ request$ = this.http.get(this.config.apiUrl, { params }).pipe(map(response => {
2238
+ const dataPath = this.config.dataResponsePath !== undefined ? this.config.dataResponsePath : '';
2239
+ const totalPath = totalCountConfig?.responsePath || '';
2240
+ return {
2241
+ data: this.getValueByPath(response, dataPath),
2242
+ // If source is 'same', try to get total from response, else default 0
2243
+ total: totalCountConfig ? this.getValueByPath(response, totalPath) : 0
2244
+ };
2245
+ }));
2246
+ }
2247
+ request$.pipe(finalize(() => this.loading = false), catchError(err => {
2248
+ console.error('Table Data Fetch Error', err);
2249
+ return of({ data: [], total: 0 });
2250
+ }))
2251
+ .subscribe((result) => {
2252
+ this.data = result.data || [];
2253
+ if (this.config.pagination) {
2254
+ this.totalItems = result.total || 0;
2255
+ }
2256
+ // Dynamic Column Generation
2257
+ if (!this.config.columns || this.config.columns.length === 0) {
2258
+ if (this.data.length > 0) {
2259
+ this.config.columns = Object.keys(this.data[0]).map(key => ({
2260
+ key: key,
2261
+ label: this.toTitleCase(key),
2262
+ type: 'text',
2263
+ sortable: false,
2264
+ editable: false
2265
+ }));
2266
+ }
2267
+ }
2268
+ });
2269
+ }
2270
+ // --- Actions ---
2271
+ onPageChange(page) {
2272
+ this.currentPage = page;
2273
+ this.loadData();
2274
+ }
2275
+ onPageSizeChange(size) {
2276
+ if (this.config.pagination) {
2277
+ this.config.pagination.pageSize = size;
2278
+ this.currentPage = 1; // Reset to first page
2279
+ this.loadData();
2280
+ }
2281
+ }
2282
+ onSort(col) {
2283
+ if (!col.sortable)
2284
+ return;
2285
+ if (this.activeSort.key === col.key) {
2286
+ this.activeSort.direction = this.activeSort.direction === 'ASC' ? 'DESC' : 'ASC';
2287
+ }
2288
+ else {
2289
+ this.activeSort.key = col.key;
2290
+ this.activeSort.direction = 'ASC';
2291
+ }
2292
+ this.loadData();
2293
+ }
2294
+ onSearch(event) {
2295
+ const value = event.target.value;
2296
+ this.searchSubject.next(value);
2297
+ }
2298
+ onFilterChange(key, event) {
2299
+ const value = event.target.value;
2300
+ this.activeFilters[key] = value;
2301
+ this.currentPage = 1;
2302
+ this.filterChange.emit({ key, value });
2303
+ this.loadData();
2304
+ }
2305
+ onAction(action, row) {
2306
+ if (action.type === 'callback' && action.callback) {
2307
+ action.callback(row);
2308
+ }
2309
+ if (action.type === 'route' && action.route) {
2310
+ const url = this.replaceParams(action.route, row);
2311
+ this.router.navigateByUrl(url);
2312
+ return;
2313
+ }
2314
+ if (action.type === 'api') {
2315
+ if (action.confirmationNeeded) {
2316
+ const message = action.confirmationMessage || this.config.labels?.defaultConfirmationMessage || 'Are you sure?';
2317
+ if (!confirm(message))
2318
+ return;
2319
+ }
2320
+ this.action.emit({ action, row });
2321
+ }
2322
+ else {
2323
+ this.action.emit({ action, row });
2324
+ }
2325
+ }
2326
+ onTopAction(action) {
2327
+ if (action.type === 'callback' && action.callback) {
2328
+ action.callback(null); // No row for top action
2329
+ }
2330
+ this.topAction.emit(action);
2331
+ }
2332
+ // --- Selection ---
2333
+ onSelectAll(event) {
2334
+ const checked = event.target.checked;
2335
+ this.data.forEach(row => row.selected = checked);
2336
+ this.updateSelectedRows();
2337
+ }
2338
+ onRowSelect(row) {
2339
+ this.updateSelectedRows();
2340
+ }
2341
+ updateSelectedRows() {
2342
+ this.selectedRows = this.data.filter(row => row.selected);
2343
+ this.rowSelect.emit(this.selectedRows);
2344
+ }
2345
+ // --- Helpers ---
2346
+ getCellValue(row, col) {
2347
+ // Support nested properties via labelPath or key
2348
+ const path = col.labelPath || col.key;
2349
+ let val = this.getValueByPath(row, path);
2350
+ // Formatting (Date, etc.)
2351
+ if (col.type === 'date' && val) {
2352
+ if (col.dateFormat) {
2353
+ try {
2354
+ return formatDate(val, col.dateFormat, this.locale);
2355
+ }
2356
+ catch (e) {
2357
+ console.warn('Invalid date format or value', val, col.dateFormat);
2358
+ return val;
2359
+ }
2360
+ }
2361
+ return new Date(val).toLocaleDateString();
2362
+ }
2363
+ return val;
2364
+ }
2365
+ getBadgeClass(row, col) {
2366
+ const val = this.getCellValue(row, col);
2367
+ const strVal = String(val);
2368
+ // Config approach
2369
+ if (col.badgeConfig && col.badgeConfig[strVal]) {
2370
+ return `badge-${col.badgeConfig[strVal]}`;
2371
+ }
2372
+ // Default Logic
2373
+ const status = strVal.toLowerCase();
2374
+ if (['active', 'completed', 'success', 'approved'].includes(status))
2375
+ return 'badge-success';
2376
+ if (['pending', 'in progress', 'waiting'].includes(status))
2377
+ return 'badge-warning';
2378
+ if (['rejected', 'failed', 'error', 'deleted'].includes(status))
2379
+ return 'badge-danger';
2380
+ if (['draft', 'inactive'].includes(status))
2381
+ return 'badge-neutral';
2382
+ return 'badge-info'; // default
2383
+ }
2384
+ getSortIcon(key) {
2385
+ if (this.activeSort.key !== key)
2386
+ return 'fa-sort';
2387
+ return this.activeSort.direction === 'ASC' ? 'fa-sort-up' : 'fa-sort-down';
2388
+ }
2389
+ replaceParams(template, row) {
2390
+ return template.replace(/:([a-zA-Z0-9_]+)/g, (_, key) => row[key] || '');
2391
+ }
2392
+ loadFilterOptions() {
2393
+ if (!this.config.filters)
2394
+ return;
2395
+ this.config.filters.forEach(filter => {
2396
+ if (filter.apiUrl && !filter.options) {
2397
+ this.http.get(filter.apiUrl).subscribe({
2398
+ next: (response) => {
2399
+ const data = filter.dataPath ? this.getValueByPath(response, filter.dataPath) : response;
2400
+ if (!Array.isArray(data)) {
2401
+ console.error(`Filter data for ${filter.key} is not an array`, data);
2402
+ return;
2403
+ }
2404
+ filter.options = data.map((item) => {
2405
+ const label = filter.labelPath ? this.getValueByPath(item, filter.labelPath) :
2406
+ (filter.labelKey ? item[filter.labelKey] : item.label || item.name);
2407
+ const value = filter.valuePath ? this.getValueByPath(item, filter.valuePath) :
2408
+ (filter.valueKey ? item[filter.valueKey] : item.value || item.code);
2409
+ return { label, value };
2410
+ });
2411
+ // Auto-populate matching column options
2412
+ if (this.config.columns) {
2413
+ const matchingColumn = this.config.columns.find(col => col.key === filter.key);
2414
+ if (matchingColumn && matchingColumn.dataType === 'select' && !matchingColumn.options) {
2415
+ matchingColumn.options = filter.options;
2416
+ }
2417
+ }
2418
+ },
2419
+ error: (err) => console.error(`Failed to load filter options for ${filter.key}:`, err)
2420
+ });
2421
+ }
2422
+ });
2423
+ }
2424
+ getValueByPath(obj, path) {
2425
+ if (!path || path === '')
2426
+ return obj;
2427
+ return path.split('.').reduce((acc, part) => {
2428
+ const match = part.match(/(\w+)\[(\d+)\]/);
2429
+ if (match) {
2430
+ return acc?.[match[1]]?.[parseInt(match[2])];
2431
+ }
2432
+ return acc?.[part];
2433
+ }, obj);
2434
+ }
2435
+ calculateStickyPositions() {
2436
+ // We calculate positions based on rendered widths
2437
+ if (!this.stickyHeaders || this.stickyHeaders.length === 0)
2438
+ return;
2439
+ this.stickyColumnStyles = {};
2440
+ let leftOffset = 0;
2441
+ this.hasStickyColumns = false;
2442
+ // Default sticky columns count is 3 if not specified
2443
+ const stickyCount = this.config.stickyColumnCount !== undefined ? this.config.stickyColumnCount : 3;
2444
+ // Checkbox width handling
2445
+ if (this.config.selectable) {
2446
+ const firstSticky = this.config.columns.find((c, i) => i < stickyCount || c.sticky);
2447
+ if (firstSticky) {
2448
+ // We can try to measure checkbox col if needed, but usually fixed 40px
2449
+ // Or better, if we have a checkbox col ref, assume 40px for now as it is fixed in CSS
2450
+ leftOffset = 40;
2451
+ }
2452
+ }
2453
+ const headerElements = this.stickyHeaders.toArray();
2454
+ this.config.columns.forEach((col, index) => {
2455
+ if (col.sticky || index < stickyCount) {
2456
+ col.sticky = true;
2457
+ this.hasStickyColumns = false; // Reset to true only after we set styles? No, wait.
2458
+ // Actually property is used in template to add class 'sticky-col'
2459
+ // but we need to update Styles based on previous cols widths
2460
+ // Find corresponding header element
2461
+ // Note: headerElements corresponds to columns indices
2462
+ const headerEl = headerElements[index]?.nativeElement;
2463
+ if (headerEl) {
2464
+ // Set style for current column
2465
+ this.stickyColumnStyles[col.key] = {
2466
+ left: `${leftOffset}px`
2467
+ // We DO NOT set width here, allowing it to be dynamic/auto
2468
+ };
2469
+ // Add THIS column's width to offset for the NEXT column
2470
+ // use getBoundingClientRect or offsetWidth
2471
+ leftOffset += headerEl.offsetWidth;
2472
+ }
2473
+ this.hasStickyColumns = true;
2474
+ }
2475
+ });
2476
+ this.cdr.detectChanges();
2477
+ }
2478
+ toTitleCase(str) {
2479
+ return str
2480
+ .replace(/([A-Z])/g, ' $1') // insert space before capital letters
2481
+ .replace(/^./, (str) => str.toUpperCase()) // capitalize the first letter
2482
+ .trim(); // remove any leading/trailing whitespace
2483
+ }
2484
+ get columnCount() {
2485
+ return this.config.columns.length;
2486
+ }
2487
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableComponent, deps: [{ token: i3.HttpClient }, { token: i1$1.Router }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2488
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SmartTableComponent, isStandalone: false, selector: "lib-smart-table", inputs: { config: "config" }, outputs: { action: "action", topAction: "topAction", filterChange: "filterChange", rowSelect: "rowSelect" }, viewQueries: [{ propertyName: "stickyHeaders", predicate: ["stickyHeader"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" [class.sticky-col]=\"col.sticky\" [ngStyle]=\"stickyColumnStyles[col.key]\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </div>\n <!-- Alternatively use specific icons if needed, but button component is requested -->\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n</div>\n", styles: [".smart-table-wrapper{font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:auto;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.no-data{text-align:center;padding:2rem;color:var(--st-no-data-color, #888)}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PaginationComponent, selector: "lib-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "pageSizeOptions", "theme", "labels"], outputs: ["pageChange", "itemsPerPageChange"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon"] }] });
2489
+ }
2490
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableComponent, decorators: [{
2491
+ type: Component,
2492
+ args: [{ selector: 'lib-smart-table', standalone: false, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" [class.sticky-col]=\"col.sticky\" [ngStyle]=\"stickyColumnStyles[col.key]\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </div>\n <!-- Alternatively use specific icons if needed, but button component is requested -->\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n</div>\n", styles: [".smart-table-wrapper{font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:auto;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.no-data{text-align:center;padding:2rem;color:var(--st-no-data-color, #888)}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
2493
+ }], ctorParameters: () => [{ type: i3.HttpClient }, { type: i1$1.Router }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { config: [{
2494
+ type: Input
2495
+ }], action: [{
2496
+ type: Output
2497
+ }], topAction: [{
2498
+ type: Output
2499
+ }], filterChange: [{
2500
+ type: Output
2501
+ }], rowSelect: [{
2502
+ type: Output
2503
+ }], stickyHeaders: [{
2504
+ type: ViewChildren,
2505
+ args: ['stickyHeader']
2506
+ }] } });
2507
+
2508
+ class SmartTableModule {
2509
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2510
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, declarations: [SmartTableComponent], imports: [CommonModule,
2511
+ FormsModule,
2512
+ PaginationModule,
2513
+ ButtonModule], exports: [SmartTableComponent] });
2514
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, imports: [CommonModule,
2515
+ FormsModule,
2516
+ PaginationModule,
2517
+ ButtonModule] });
2518
+ }
2519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, decorators: [{
2520
+ type: NgModule,
2521
+ args: [{
2522
+ declarations: [
2523
+ SmartTableComponent
2524
+ ],
2525
+ imports: [
2526
+ CommonModule,
2527
+ FormsModule,
2528
+ PaginationModule,
2529
+ ButtonModule
2530
+ ],
2531
+ exports: [
2532
+ SmartTableComponent
2533
+ ]
2534
+ }]
2535
+ }] });
2536
+
2036
2537
  /*
2037
2538
  * Public API Surface of shared-ui
2038
2539
  */
@@ -2041,5 +2542,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
2041
2542
  * Generated bundle index. Do not edit.
2042
2543
  */
2043
2544
 
2044
- export { AlertComponent, AlertModule, ButtonComponent, ButtonModule, CardType1Component, CardType2Component, CardsModule, ConfigurableFormComponent, configurableForm_examples as ConfigurableFormExamples, ConfigurableFormModule, ConfirmationModalComponent, ConfirmationModalModule, DEFAULT_ITEMS_PER_PAGE, DEFAULT_PAGE_SIZE_OPTIONS, FilterSidebarComponent, FilterSidebarModule, MaterialModule, NAV_ORIENTATION_DEFAULT, NAV_VARIANT_DEFAULT, NavComponent, NavModule, PAGINATION_THEME_DARK, PAGINATION_THEME_DEFAULT, PaginationComponent, PaginationModule, SharedUiModule, SummaryCardComponent, SummaryCardModule, clearLocalStorage, clearSessionStorage, getLocalStorageItem, getSessionStorageItem, removeLocalStorageItem, removeSessionStorageItem, setLocalStorageItem, setSessionStorageItem };
2545
+ export { AlertComponent, AlertModule, ButtonComponent, ButtonModule, CardType1Component, CardType2Component, CardsModule, ConfigurableFormComponent, configurableForm_examples as ConfigurableFormExamples, ConfigurableFormModule, ConfirmationModalComponent, ConfirmationModalModule, DEFAULT_ITEMS_PER_PAGE, DEFAULT_PAGE_SIZE_OPTIONS, FilterSidebarComponent, FilterSidebarModule, MaterialModule, NAV_ORIENTATION_DEFAULT, NAV_VARIANT_DEFAULT, NavComponent, NavModule, PAGINATION_THEME_DARK, PAGINATION_THEME_DEFAULT, PaginationComponent, PaginationModule, SharedUiModule, SmartTableComponent, SmartTableModule, SummaryCardComponent, SummaryCardModule, clearLocalStorage, clearSessionStorage, getLocalStorageItem, getSessionStorageItem, removeLocalStorageItem, removeSessionStorageItem, setLocalStorageItem, setSessionStorageItem };
2045
2546
  //# sourceMappingURL=commons-shared-web-ui.mjs.map