ng-fusion-ui 0.7.53 → 0.7.55
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.
|
@@ -1901,6 +1901,10 @@ class FuTableComponent {
|
|
|
1901
1901
|
* Options for page size selection in the paginator.
|
|
1902
1902
|
*/
|
|
1903
1903
|
this.pageSizeOptions = input([5, 10, 15, 20]);
|
|
1904
|
+
/**
|
|
1905
|
+
* Initial page size for the paginator.
|
|
1906
|
+
*/
|
|
1907
|
+
this.initPageSize = input(10);
|
|
1904
1908
|
/**
|
|
1905
1909
|
* Index of the currently expanded row.
|
|
1906
1910
|
*
|
|
@@ -1966,7 +1970,7 @@ class FuTableComponent {
|
|
|
1966
1970
|
this.searchTerm = signal('');
|
|
1967
1971
|
this.originalData = signal([]);
|
|
1968
1972
|
this.pageIndex = signal(0);
|
|
1969
|
-
this.pageSize =
|
|
1973
|
+
this.pageSize = linkedSignal(() => this.initPageSize());
|
|
1970
1974
|
this.editingRowIndex = signal(null);
|
|
1971
1975
|
this.pendingSaveRowIndex = signal(null);
|
|
1972
1976
|
this.originalRowSnapshot = signal(null);
|
|
@@ -2145,6 +2149,12 @@ class FuTableComponent {
|
|
|
2145
2149
|
});
|
|
2146
2150
|
});
|
|
2147
2151
|
this.activeCell = null;
|
|
2152
|
+
this.isMobileScreen = signal(window.innerWidth < 900);
|
|
2153
|
+
}
|
|
2154
|
+
onResize(event) {
|
|
2155
|
+
const screenWidth = event.target.innerWidth;
|
|
2156
|
+
const smallScreen = screenWidth < 900;
|
|
2157
|
+
this.isMobileScreen.set(smallScreen);
|
|
2148
2158
|
}
|
|
2149
2159
|
ngOnChanges(changes) {
|
|
2150
2160
|
if (changes['dataSource']) {
|
|
@@ -2610,7 +2620,7 @@ class FuTableComponent {
|
|
|
2610
2620
|
}));
|
|
2611
2621
|
}
|
|
2612
2622
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2613
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: FuTableComponent, isStandalone: true, selector: "fu-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, columnsConfig: { classPropertyName: "columnsConfig", publicName: "columnsConfig", isSignal: true, isRequired: false, transformFunction: null }, configPanel: { classPropertyName: "configPanel", publicName: "configPanel", isSignal: true, isRequired: false, transformFunction: null }, filterPanel: { classPropertyName: "filterPanel", publicName: "filterPanel", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disablePaginator: { classPropertyName: "disablePaginator", publicName: "disablePaginator", isSignal: true, isRequired: false, transformFunction: null }, resetQuery: { classPropertyName: "resetQuery", publicName: "resetQuery", isSignal: true, isRequired: false, transformFunction: null }, resetQueryOnInit: { classPropertyName: "resetQueryOnInit", publicName: "resetQueryOnInit", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, stickyFirstColumn: { classPropertyName: "stickyFirstColumn", publicName: "stickyFirstColumn", isSignal: true, isRequired: false, transformFunction: null }, stickyLastColumn: { classPropertyName: "stickyLastColumn", publicName: "stickyLastColumn", isSignal: true, isRequired: false, transformFunction: null }, rowState: { classPropertyName: "rowState", publicName: "rowState", isSignal: true, isRequired: false, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowStyle: { classPropertyName: "rowStyle", publicName: "rowStyle", isSignal: true, isRequired: false, transformFunction: null }, rowHoverEffect: { classPropertyName: "rowHoverEffect", publicName: "rowHoverEffect", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, expandIndex: { classPropertyName: "expandIndex", publicName: "expandIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dataSource: "dataSourceChange", rowState: "rowStateChange", expandIndex: "expandIndexChange", onQueryChanged: "onQueryChanged", onCellEdited: "onCellEdited", onColReorder: "onColReorder", onRowEditComplete: "onRowEditComplete", onRowSelect: "onRowSelect", onRowDelete: "onRowDelete" }, queries: [{ propertyName: "toolbarTemplate", first: true, predicate: FuTableToolbarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "sidebarTemplate", first: true, predicate: FuTableSidebarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "noDataTemplate", first: true, predicate: FuTableNoDataTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "expandRowTemplate", first: true, predicate: FuTableExpandRowTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cellContextMenuTemplate", first: true, predicate: FuTableCellContextMenuTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"fu-new-table-wrapper\">\r\n @if (filterPanel()) {\r\n <div class=\"fu-search\">\r\n <input\r\n type=\"search\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [value]=\"searchTerm()\"\r\n (input)=\"onSearch($any($event.target).value)\"\r\n />\r\n <div class=\"fu-search-nav\">\r\n <button fuTButton (click)=\"prevMatch()\">\r\n {{ intl.previous() }}\r\n </button>\r\n <button fuTButton (click)=\"nextMatch()\">\r\n {{ intl.next() }}\r\n </button>\r\n @if (searchMatches().length > 0) {\r\n <span class=\"fu-match-counter\">\r\n {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (toolbarTemplate()) {\r\n <div class=\"fu-table-toolbar\">\r\n <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fu-table-layout\"\r\n [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n >\r\n <div\r\n #scrollContainer\r\n class=\"fu-table-scroll\"\r\n [class.fu-scrollable]=\"scrollableConfig()\"\r\n [style.max-height.vh]=\"scrollHeightConfig()\"\r\n >\r\n <table\r\n class=\"fu-table\"\r\n [class.fu-table--responsive]=\"responsiveConfig()\"\r\n [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n >\r\n <thead>\r\n <tr>\r\n @if (expandRowTemplate()) {\r\n <th class=\"fu-expand-header\"></th>\r\n }\r\n <!-- -->\r\n @for (col of visibleColumns(); track $index) {\r\n <th\r\n (click)=\"onSort(col, $event)\"\r\n [class.fu-sortable]=\"col.isSortable()\"\r\n [style.width]=\"col.width()\"\r\n >\r\n <div class=\"fu-th-content\">\r\n @if (col.columnHeaderTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"fu-header-main\">\r\n <span\r\n class=\"fu-header-txt\"\r\n [class.has-desc]=\"!!col.description()\"\r\n [fuTooltip]=\"col.description() || ''\"\r\n >\r\n {{ col.header() }}\r\n </span>\r\n\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n </span>\r\n }\r\n <!-- -->\r\n @if (col.columnHeaderAddonTemplate()) {\r\n <span class=\"fu-header-addon\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n </span>\r\n }\r\n </div>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (initialLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n } @else {\r\n <!-- -->\r\n @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n @if (rowsLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n } @else {\r\n <tr\r\n [class.fu-cell-success]=\"\r\n rowStates.get(rowIndex) === 'success' && !loading()\r\n \"\r\n [class.fu-cell-error]=\"\r\n rowStates.get(rowIndex) === 'error' && !loading()\r\n \"\r\n [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n [attr.data-row-index]=\"rowIndex\"\r\n [class]=\"resolvedRowClasses()[rowIndex]\"\r\n (animationend)=\"onEditAnimationEnd()\"\r\n (click)=\"onRowClick(row, $event)\"\r\n >\r\n @if (expandRowTemplate()) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n <!-- -->\r\n @for (\r\n col of visibleColumns();\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n @let isMatch =\r\n activeMatchKey() === rowIndex + ':' + col.field();\r\n @let cellValue = col.accessor(row);\r\n\r\n @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n } @else {\r\n <td\r\n #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n [cdkContextMenuTriggerData]=\"{\r\n value: cellValue,\r\n row,\r\n colIndex: colIndex,\r\n rowIndex: rowIndex,\r\n trigger: contextTrigger,\r\n }\"\r\n [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n (cdkContextMenuOpened)=\"\r\n activeCell = col.field() + '-' + rowIndex\r\n \"\r\n (cdkContextMenuClosed)=\"activeCell = null\"\r\n [class.fu-context-open]=\"\r\n activeCell === col.field() + '-' + rowIndex\r\n \"\r\n [class.fu-cell-pending]=\"\r\n pendingSaveRowIndex() === rowIndex && loading()\r\n \"\r\n [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n [class.fu-cell-sorting]=\"\r\n col.isSortable() && col.sortDirection() !== null\r\n \"\r\n [class.fu-active-match]=\"isMatch\"\r\n [style]=\"\r\n col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n \"\r\n >\r\n <div class=\"fu-header-text\">\r\n {{ col.description() || col.header() }}\r\n </div>\r\n\r\n @if (col.columnCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: cellValue,\r\n row: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n searchable: col.searchable(),\r\n activeMatch: isMatch,\r\n }\"\r\n }\r\n />\r\n } @else if (col.columnActionsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n row: row,\r\n index: rowIndex,\r\n editing: editingRowIndex() === rowIndex,\r\n expanded: expandIndex() === rowIndex,\r\n startEdit: startEditRow.bind(this),\r\n saveEdit: saveEditRow.bind(this),\r\n cancelEdit: cancelEditRow.bind(this),\r\n toggleExpand: toggleExpand.bind(this),\r\n deleteRow: deleteRow.bind(this),\r\n }\"\r\n }\r\n />\r\n } @else {\r\n <fu-cell\r\n [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n [type]=\"col.type()\"\r\n [searchTerm]=\"searchTerm()\"\r\n [editable]=\"col.editable()\"\r\n [searchable]=\"col.searchable()\"\r\n [value]=\"cellValue\"\r\n [activeMatch]=\"isMatch\"\r\n [editing]=\"editingRowIndex() === rowIndex\"\r\n (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n />\r\n }\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n\r\n @if (expandIndex() === rowIndex) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n }\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n } @empty {\r\n <tr class=\"fu-no-data-row\">\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n @if (configPanel() || sidebarTemplate()) {\r\n <div\r\n class=\"fu-sidebar\"\r\n [class.fu-open]=\"isSidebarOpen()\"\r\n (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n >\r\n @if (isSidebarOpen()) {\r\n <!-- Sidebar content -->\r\n <div class=\"fu-content\">\r\n @if (isColumnsOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n } @else if (isLayoutOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n } @else if (isCustomOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fu-handle\">\r\n @if (configPanel()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n (click)=\"toggleColumnsPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n />\r\n </svg>\r\n </button>\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n (click)=\"toggleLayoutPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n @if (sidebarTemplate()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n (click)=\"toggleCustomPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (paginator()) {\r\n <div class=\"fu-paginator\">\r\n <div class=\"fu-paginator-entries\">\r\n {{ entriesLabel() }}\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"prevPage()\"\r\n [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m14 7l-5 5l5 5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"fu-page-info\">\r\n {{ intl.pageLabel() }}\r\n\r\n <input\r\n class=\"fu-page-jump\"\r\n #pageInput\r\n [min]=\"1\"\r\n [max]=\"totalPages()\"\r\n [value]=\"pageIndex() + 1\"\r\n (input)=\"adjustWidth(pageInput)\"\r\n (change)=\"jumpToPage(pageInput)\"\r\n [disabled]=\"totalPages() === 0\"\r\n [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n />\r\n <span [style.margin-left.px]=\"4\">/</span>\r\n <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"nextPage()\"\r\n [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m10 17l5-5l-5-5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n @for (size of pageSizeOptions(); track size) {\r\n <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template\r\n #cellContextMenu\r\n let-value=\"value\"\r\n let-row=\"row\"\r\n let-colIndex=\"colIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-trigger=\"trigger\"\r\n>\r\n <div cdkMenu class=\"fu-context-menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellContextMenuTemplate()!;\r\n context: { value, row, colIndex, rowIndex, trigger }\r\n \"\r\n />\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n @for (\r\n i of [].constructor(skeletonRowCount());\r\n let rowIndex = $index;\r\n track rowIndex\r\n ) {\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n <span class=\"fu-sort-icon\">\r\n @if (!direction) {\r\n <svg\r\n class=\"fu-sort-icon-default\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'asc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'desc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n />\r\n </svg>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n <div class=\"fu-config-sidebar\">\r\n <div class=\"fu-config-item\">\r\n <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n <input\r\n id=\"stickyHeader\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyHeaderConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n <input\r\n id=\"stickyFirstColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyFirstColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n <input\r\n id=\"stickyLastColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyLastColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n <div class=\"fu-columns-panel\">\r\n <div class=\"fu-column-search\">\r\n <input\r\n class=\"fu-column-search-input\"\r\n type=\"text\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [(ngModel)]=\"searchColTerm\"\r\n />\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectAllChecked()\"\r\n [indeterminate]=\"selectAllIndeterminate()\"\r\n (change)=\"toggleFilteredSelection($event)\"\r\n [disabled]=\"filteredTotalCount() === 0\"\r\n [style.marginRight.px]=\"8\"\r\n />\r\n </div>\r\n\r\n <div\r\n class=\"fu-drag-lock fu-drag-list\"\r\n cdkDropList\r\n cdkDropListOrientation=\"vertical\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n <div\r\n class=\"fu-column-item\"\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n cdkDragBoundary=\".fu-drag-lock\"\r\n [cdkDragDisabled]=\"!col.reorderable()\"\r\n >\r\n <span\r\n class=\"fu-drag-handle\"\r\n cdkDragHandle\r\n [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n >\u2630</span\r\n >\r\n\r\n @if (col.description()) {\r\n <div class=\"fu-column-item-label\">\r\n <span class=\"fu-label\">{{ col.header() }}</span>\r\n <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n </div>\r\n } @else {\r\n <div class=\"fu-column-default\">\r\n <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n col.header()\r\n }}</span>\r\n </div>\r\n }\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"col.visible()\"\r\n [disabled]=\"\r\n !col.hideable() || (visibleCount() === 3 && col.visible())\r\n \"\r\n (change)=\"toggleVisibility(col)\"\r\n />\r\n\r\n <ng-template cdkDragPreview>\r\n <div class=\"fu-drag-preview\">\r\n <svg\r\n class=\"fu-drag-icon\"\r\n width=\"16px\"\r\n height=\"16px\"\r\n fill=\"currentColor\"\r\n viewBox=\"0 0 25 25\"\r\n >\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n ></path>\r\n </svg>\r\n <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fu-column-meta\">\r\n {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n {{ intl.visible() }}\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:207px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FuCellComponent, selector: "fu-cell", inputs: ["value", "id", "type", "editing", "editable", "searchTerm", "activeMatch", "loading", "searchable"], outputs: ["valueChange", "cellValueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i3.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: FuClickOutsideDirective, selector: "[fuClickOutside]", outputs: ["fuClickOutside"] }, { kind: "directive", type: FuTooltipDirective, selector: "[fuTooltip]", inputs: ["fuTooltip"] }, { kind: "directive", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: ["cdkContextMenuTriggerFor", "cdkContextMenuPosition", "cdkContextMenuTriggerData", "cdkContextMenuDisabled"], outputs: ["cdkContextMenuOpened", "cdkContextMenuClosed"], exportAs: ["cdkContextMenuTriggerFor"] }, { kind: "directive", type: FuTButtonDirective, selector: "button[fuTButton], a[fuTButton]", inputs: ["variant", "severity", "loading", "disabled"] }, { kind: "directive", type: CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }] }); }
|
|
2623
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: FuTableComponent, isStandalone: true, selector: "fu-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, columnsConfig: { classPropertyName: "columnsConfig", publicName: "columnsConfig", isSignal: true, isRequired: false, transformFunction: null }, configPanel: { classPropertyName: "configPanel", publicName: "configPanel", isSignal: true, isRequired: false, transformFunction: null }, filterPanel: { classPropertyName: "filterPanel", publicName: "filterPanel", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disablePaginator: { classPropertyName: "disablePaginator", publicName: "disablePaginator", isSignal: true, isRequired: false, transformFunction: null }, resetQuery: { classPropertyName: "resetQuery", publicName: "resetQuery", isSignal: true, isRequired: false, transformFunction: null }, resetQueryOnInit: { classPropertyName: "resetQueryOnInit", publicName: "resetQueryOnInit", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, stickyFirstColumn: { classPropertyName: "stickyFirstColumn", publicName: "stickyFirstColumn", isSignal: true, isRequired: false, transformFunction: null }, stickyLastColumn: { classPropertyName: "stickyLastColumn", publicName: "stickyLastColumn", isSignal: true, isRequired: false, transformFunction: null }, rowState: { classPropertyName: "rowState", publicName: "rowState", isSignal: true, isRequired: false, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowStyle: { classPropertyName: "rowStyle", publicName: "rowStyle", isSignal: true, isRequired: false, transformFunction: null }, rowHoverEffect: { classPropertyName: "rowHoverEffect", publicName: "rowHoverEffect", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, initPageSize: { classPropertyName: "initPageSize", publicName: "initPageSize", isSignal: true, isRequired: false, transformFunction: null }, expandIndex: { classPropertyName: "expandIndex", publicName: "expandIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dataSource: "dataSourceChange", rowState: "rowStateChange", expandIndex: "expandIndexChange", onQueryChanged: "onQueryChanged", onCellEdited: "onCellEdited", onColReorder: "onColReorder", onRowEditComplete: "onRowEditComplete", onRowSelect: "onRowSelect", onRowDelete: "onRowDelete" }, host: { listeners: { "window:resize": "onResize($event)" } }, queries: [{ propertyName: "toolbarTemplate", first: true, predicate: FuTableToolbarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "sidebarTemplate", first: true, predicate: FuTableSidebarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "noDataTemplate", first: true, predicate: FuTableNoDataTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "expandRowTemplate", first: true, predicate: FuTableExpandRowTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cellContextMenuTemplate", first: true, predicate: FuTableCellContextMenuTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"fu-new-table-wrapper\">\r\n @if (filterPanel()) {\r\n <div class=\"fu-search\">\r\n <input\r\n type=\"search\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [value]=\"searchTerm()\"\r\n (input)=\"onSearch($any($event.target).value)\"\r\n />\r\n <div class=\"fu-search-nav\">\r\n <button fuTButton (click)=\"prevMatch()\">\r\n {{ intl.previous() }}\r\n </button>\r\n <button fuTButton (click)=\"nextMatch()\">\r\n {{ intl.next() }}\r\n </button>\r\n @if (searchMatches().length > 0) {\r\n <span class=\"fu-match-counter\">\r\n {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (toolbarTemplate()) {\r\n <div class=\"fu-table-toolbar\">\r\n <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fu-table-layout\"\r\n [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n >\r\n <div\r\n #scrollContainer\r\n class=\"fu-table-scroll\"\r\n [class.fu-scrollable]=\"scrollableConfig()\"\r\n [style.max-height.vh]=\"scrollHeightConfig()\"\r\n >\r\n <table\r\n class=\"fu-table\"\r\n [class.fu-table--responsive]=\"responsiveConfig()\"\r\n [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n >\r\n <thead>\r\n <tr>\r\n @if (expandRowTemplate()) {\r\n <th class=\"fu-expand-header\"></th>\r\n }\r\n <!-- -->\r\n @for (col of visibleColumns(); track $index) {\r\n <th\r\n (click)=\"onSort(col, $event)\"\r\n [class.fu-sortable]=\"col.isSortable()\"\r\n [style.width]=\"col.width()\"\r\n >\r\n <div class=\"fu-th-content\">\r\n @if (col.columnHeaderTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"fu-header-main\">\r\n <span\r\n class=\"fu-header-txt\"\r\n [class.has-desc]=\"!!col.description()\"\r\n [fuTooltip]=\"col.description() || ''\"\r\n >\r\n {{ col.header() }}\r\n </span>\r\n\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n </span>\r\n }\r\n <!-- -->\r\n @if (col.columnHeaderAddonTemplate()) {\r\n <span class=\"fu-header-addon\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n </span>\r\n }\r\n </div>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (initialLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n } @else {\r\n <!-- -->\r\n @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n @if (rowsLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n } @else {\r\n <tr\r\n [class.fu-cell-success]=\"\r\n rowStates.get(rowIndex) === 'success' && !loading()\r\n \"\r\n [class.fu-cell-error]=\"\r\n rowStates.get(rowIndex) === 'error' && !loading()\r\n \"\r\n [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n [attr.data-row-index]=\"rowIndex\"\r\n [class]=\"resolvedRowClasses()[rowIndex]\"\r\n (animationend)=\"onEditAnimationEnd()\"\r\n (click)=\"onRowClick(row, $event)\"\r\n >\r\n @if (\r\n (expandRowTemplate() && !isMobileScreen()) ||\r\n (expandRowTemplate() &&\r\n isMobileScreen() &&\r\n !responsiveConfig())\r\n ) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n <!-- -->\r\n @for (\r\n col of visibleColumns();\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n @let isMatch =\r\n activeMatchKey() === rowIndex + ':' + col.field();\r\n @let cellValue = col.accessor(row);\r\n\r\n @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n } @else {\r\n <td\r\n #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n [cdkContextMenuTriggerData]=\"{\r\n value: cellValue,\r\n row,\r\n colIndex: colIndex,\r\n rowIndex: rowIndex,\r\n trigger: contextTrigger,\r\n }\"\r\n [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n (cdkContextMenuOpened)=\"\r\n activeCell = col.field() + '-' + rowIndex\r\n \"\r\n (cdkContextMenuClosed)=\"activeCell = null\"\r\n [class.fu-context-open]=\"\r\n activeCell === col.field() + '-' + rowIndex\r\n \"\r\n [class.fu-cell-pending]=\"\r\n pendingSaveRowIndex() === rowIndex && loading()\r\n \"\r\n [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n [class.fu-cell-sorting]=\"\r\n col.isSortable() && col.sortDirection() !== null\r\n \"\r\n [class.fu-active-match]=\"isMatch\"\r\n [style]=\"\r\n col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n \"\r\n >\r\n <div class=\"fu-header-text\">\r\n {{ col.description() || col.header() }}\r\n </div>\r\n\r\n @if (col.columnCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: cellValue,\r\n row: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n searchable: col.searchable(),\r\n activeMatch: isMatch,\r\n }\"\r\n }\r\n />\r\n } @else if (col.columnActionsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n row: row,\r\n index: rowIndex,\r\n editing: editingRowIndex() === rowIndex,\r\n expanded: expandIndex() === rowIndex,\r\n startEdit: startEditRow.bind(this),\r\n saveEdit: saveEditRow.bind(this),\r\n cancelEdit: cancelEditRow.bind(this),\r\n toggleExpand: toggleExpand.bind(this),\r\n deleteRow: deleteRow.bind(this),\r\n }\"\r\n }\r\n />\r\n } @else {\r\n <fu-cell\r\n [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n [type]=\"col.type()\"\r\n [searchTerm]=\"searchTerm()\"\r\n [editable]=\"col.editable()\"\r\n [searchable]=\"col.searchable()\"\r\n [value]=\"cellValue\"\r\n [activeMatch]=\"isMatch\"\r\n [editing]=\"editingRowIndex() === rowIndex\"\r\n (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n />\r\n }\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n\r\n @if (\r\n expandRowTemplate() && isMobileScreen() && responsiveConfig()\r\n ) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n\r\n @if (expandIndex() === rowIndex) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n }\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n } @empty {\r\n <tr class=\"fu-no-data-row\">\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n @if (configPanel() || sidebarTemplate()) {\r\n <div\r\n class=\"fu-sidebar\"\r\n [class.fu-open]=\"isSidebarOpen()\"\r\n (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n >\r\n @if (isSidebarOpen()) {\r\n <!-- Sidebar content -->\r\n <div class=\"fu-content\">\r\n @if (isColumnsOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n } @else if (isLayoutOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n } @else if (isCustomOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fu-handle\">\r\n @if (configPanel()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n (click)=\"toggleColumnsPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n />\r\n </svg>\r\n </button>\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n (click)=\"toggleLayoutPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n @if (sidebarTemplate()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n (click)=\"toggleCustomPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (paginator()) {\r\n <div class=\"fu-paginator\">\r\n <div class=\"fu-paginator-entries\">\r\n {{ entriesLabel() }}\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"prevPage()\"\r\n [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m14 7l-5 5l5 5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"fu-page-info\">\r\n {{ intl.pageLabel() }}\r\n\r\n <input\r\n class=\"fu-page-jump\"\r\n #pageInput\r\n [min]=\"1\"\r\n [max]=\"totalPages()\"\r\n [value]=\"pageIndex() + 1\"\r\n (input)=\"adjustWidth(pageInput)\"\r\n (change)=\"jumpToPage(pageInput)\"\r\n [disabled]=\"totalPages() === 0\"\r\n [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n />\r\n <span [style.margin-left.px]=\"4\">/</span>\r\n <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"nextPage()\"\r\n [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m10 17l5-5l-5-5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n @for (size of pageSizeOptions(); track size) {\r\n <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template\r\n #cellContextMenu\r\n let-value=\"value\"\r\n let-row=\"row\"\r\n let-colIndex=\"colIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-trigger=\"trigger\"\r\n>\r\n <div cdkMenu class=\"fu-context-menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellContextMenuTemplate()!;\r\n context: { value, row, colIndex, rowIndex, trigger }\r\n \"\r\n />\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n @for (\r\n i of [].constructor(skeletonRowCount());\r\n let rowIndex = $index;\r\n track rowIndex\r\n ) {\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n <span class=\"fu-sort-icon\">\r\n @if (!direction) {\r\n <svg\r\n class=\"fu-sort-icon-default\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'asc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'desc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n />\r\n </svg>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n <div class=\"fu-config-sidebar\">\r\n <div class=\"fu-config-item\">\r\n <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n </div>\r\n\r\n @if (scrollHeight()) {\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n <input\r\n id=\"stickyHeader\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyHeaderConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n }\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n <input\r\n id=\"stickyFirstColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyFirstColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n <input\r\n id=\"stickyLastColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyLastColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n <div class=\"fu-columns-panel\">\r\n <div class=\"fu-column-search\">\r\n <input\r\n class=\"fu-column-search-input\"\r\n type=\"text\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [(ngModel)]=\"searchColTerm\"\r\n />\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectAllChecked()\"\r\n [indeterminate]=\"selectAllIndeterminate()\"\r\n (change)=\"toggleFilteredSelection($event)\"\r\n [disabled]=\"filteredTotalCount() === 0\"\r\n [style.marginRight.px]=\"8\"\r\n />\r\n </div>\r\n\r\n <div\r\n class=\"fu-drag-lock fu-drag-list\"\r\n cdkDropList\r\n cdkDropListOrientation=\"vertical\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n <div\r\n class=\"fu-column-item\"\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n cdkDragBoundary=\".fu-drag-lock\"\r\n [cdkDragDisabled]=\"!col.reorderable()\"\r\n >\r\n <span\r\n class=\"fu-drag-handle\"\r\n cdkDragHandle\r\n [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n >\u2630</span\r\n >\r\n\r\n @if (col.description()) {\r\n <div class=\"fu-column-item-label\">\r\n <span class=\"fu-label\">{{ col.header() }}</span>\r\n <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n </div>\r\n } @else {\r\n <div class=\"fu-column-default\">\r\n <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n col.header()\r\n }}</span>\r\n </div>\r\n }\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"col.visible()\"\r\n [disabled]=\"\r\n !col.hideable() || (visibleCount() === 3 && col.visible())\r\n \"\r\n (change)=\"toggleVisibility(col)\"\r\n />\r\n\r\n <ng-template cdkDragPreview>\r\n <div class=\"fu-drag-preview\">\r\n <svg\r\n class=\"fu-drag-icon\"\r\n width=\"16px\"\r\n height=\"16px\"\r\n fill=\"currentColor\"\r\n viewBox=\"0 0 25 25\"\r\n >\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n ></path>\r\n </svg>\r\n <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fu-column-meta\">\r\n {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n {{ intl.visible() }}\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden;min-height:255px}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:200px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative;background-color:var(--fu-table-bg)}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1;width:136px}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FuCellComponent, selector: "fu-cell", inputs: ["value", "id", "type", "editing", "editable", "searchTerm", "activeMatch", "loading", "searchable"], outputs: ["valueChange", "cellValueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i3.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: FuClickOutsideDirective, selector: "[fuClickOutside]", outputs: ["fuClickOutside"] }, { kind: "directive", type: FuTooltipDirective, selector: "[fuTooltip]", inputs: ["fuTooltip"] }, { kind: "directive", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: ["cdkContextMenuTriggerFor", "cdkContextMenuPosition", "cdkContextMenuTriggerData", "cdkContextMenuDisabled"], outputs: ["cdkContextMenuOpened", "cdkContextMenuClosed"], exportAs: ["cdkContextMenuTriggerFor"] }, { kind: "directive", type: FuTButtonDirective, selector: "button[fuTButton], a[fuTButton]", inputs: ["variant", "severity", "loading", "disabled"] }, { kind: "directive", type: CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }] }); }
|
|
2614
2624
|
}
|
|
2615
2625
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableComponent, decorators: [{
|
|
2616
2626
|
type: Component,
|
|
@@ -2624,8 +2634,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
2624
2634
|
CdkContextMenuTrigger,
|
|
2625
2635
|
FuTButtonDirective,
|
|
2626
2636
|
CdkMenu,
|
|
2627
|
-
], template: "<div class=\"fu-new-table-wrapper\">\r\n @if (filterPanel()) {\r\n <div class=\"fu-search\">\r\n <input\r\n type=\"search\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [value]=\"searchTerm()\"\r\n (input)=\"onSearch($any($event.target).value)\"\r\n />\r\n <div class=\"fu-search-nav\">\r\n <button fuTButton (click)=\"prevMatch()\">\r\n {{ intl.previous() }}\r\n </button>\r\n <button fuTButton (click)=\"nextMatch()\">\r\n {{ intl.next() }}\r\n </button>\r\n @if (searchMatches().length > 0) {\r\n <span class=\"fu-match-counter\">\r\n {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (toolbarTemplate()) {\r\n <div class=\"fu-table-toolbar\">\r\n <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fu-table-layout\"\r\n [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n >\r\n <div\r\n #scrollContainer\r\n class=\"fu-table-scroll\"\r\n [class.fu-scrollable]=\"scrollableConfig()\"\r\n [style.max-height.vh]=\"scrollHeightConfig()\"\r\n >\r\n <table\r\n class=\"fu-table\"\r\n [class.fu-table--responsive]=\"responsiveConfig()\"\r\n [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n >\r\n <thead>\r\n <tr>\r\n @if (expandRowTemplate()) {\r\n <th class=\"fu-expand-header\"></th>\r\n }\r\n <!-- -->\r\n @for (col of visibleColumns(); track $index) {\r\n <th\r\n (click)=\"onSort(col, $event)\"\r\n [class.fu-sortable]=\"col.isSortable()\"\r\n [style.width]=\"col.width()\"\r\n >\r\n <div class=\"fu-th-content\">\r\n @if (col.columnHeaderTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"fu-header-main\">\r\n <span\r\n class=\"fu-header-txt\"\r\n [class.has-desc]=\"!!col.description()\"\r\n [fuTooltip]=\"col.description() || ''\"\r\n >\r\n {{ col.header() }}\r\n </span>\r\n\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n </span>\r\n }\r\n <!-- -->\r\n @if (col.columnHeaderAddonTemplate()) {\r\n <span class=\"fu-header-addon\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n </span>\r\n }\r\n </div>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (initialLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n } @else {\r\n <!-- -->\r\n @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n @if (rowsLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n } @else {\r\n <tr\r\n [class.fu-cell-success]=\"\r\n rowStates.get(rowIndex) === 'success' && !loading()\r\n \"\r\n [class.fu-cell-error]=\"\r\n rowStates.get(rowIndex) === 'error' && !loading()\r\n \"\r\n [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n [attr.data-row-index]=\"rowIndex\"\r\n [class]=\"resolvedRowClasses()[rowIndex]\"\r\n (animationend)=\"onEditAnimationEnd()\"\r\n (click)=\"onRowClick(row, $event)\"\r\n >\r\n @if (expandRowTemplate()) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n <!-- -->\r\n @for (\r\n col of visibleColumns();\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n @let isMatch =\r\n activeMatchKey() === rowIndex + ':' + col.field();\r\n @let cellValue = col.accessor(row);\r\n\r\n @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n } @else {\r\n <td\r\n #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n [cdkContextMenuTriggerData]=\"{\r\n value: cellValue,\r\n row,\r\n colIndex: colIndex,\r\n rowIndex: rowIndex,\r\n trigger: contextTrigger,\r\n }\"\r\n [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n (cdkContextMenuOpened)=\"\r\n activeCell = col.field() + '-' + rowIndex\r\n \"\r\n (cdkContextMenuClosed)=\"activeCell = null\"\r\n [class.fu-context-open]=\"\r\n activeCell === col.field() + '-' + rowIndex\r\n \"\r\n [class.fu-cell-pending]=\"\r\n pendingSaveRowIndex() === rowIndex && loading()\r\n \"\r\n [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n [class.fu-cell-sorting]=\"\r\n col.isSortable() && col.sortDirection() !== null\r\n \"\r\n [class.fu-active-match]=\"isMatch\"\r\n [style]=\"\r\n col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n \"\r\n >\r\n <div class=\"fu-header-text\">\r\n {{ col.description() || col.header() }}\r\n </div>\r\n\r\n @if (col.columnCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: cellValue,\r\n row: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n searchable: col.searchable(),\r\n activeMatch: isMatch,\r\n }\"\r\n }\r\n />\r\n } @else if (col.columnActionsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n row: row,\r\n index: rowIndex,\r\n editing: editingRowIndex() === rowIndex,\r\n expanded: expandIndex() === rowIndex,\r\n startEdit: startEditRow.bind(this),\r\n saveEdit: saveEditRow.bind(this),\r\n cancelEdit: cancelEditRow.bind(this),\r\n toggleExpand: toggleExpand.bind(this),\r\n deleteRow: deleteRow.bind(this),\r\n }\"\r\n }\r\n />\r\n } @else {\r\n <fu-cell\r\n [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n [type]=\"col.type()\"\r\n [searchTerm]=\"searchTerm()\"\r\n [editable]=\"col.editable()\"\r\n [searchable]=\"col.searchable()\"\r\n [value]=\"cellValue\"\r\n [activeMatch]=\"isMatch\"\r\n [editing]=\"editingRowIndex() === rowIndex\"\r\n (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n />\r\n }\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n\r\n @if (expandIndex() === rowIndex) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n }\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n } @empty {\r\n <tr class=\"fu-no-data-row\">\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n @if (configPanel() || sidebarTemplate()) {\r\n <div\r\n class=\"fu-sidebar\"\r\n [class.fu-open]=\"isSidebarOpen()\"\r\n (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n >\r\n @if (isSidebarOpen()) {\r\n <!-- Sidebar content -->\r\n <div class=\"fu-content\">\r\n @if (isColumnsOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n } @else if (isLayoutOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n } @else if (isCustomOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fu-handle\">\r\n @if (configPanel()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n (click)=\"toggleColumnsPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n />\r\n </svg>\r\n </button>\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n (click)=\"toggleLayoutPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n @if (sidebarTemplate()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n (click)=\"toggleCustomPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (paginator()) {\r\n <div class=\"fu-paginator\">\r\n <div class=\"fu-paginator-entries\">\r\n {{ entriesLabel() }}\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"prevPage()\"\r\n [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m14 7l-5 5l5 5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"fu-page-info\">\r\n {{ intl.pageLabel() }}\r\n\r\n <input\r\n class=\"fu-page-jump\"\r\n #pageInput\r\n [min]=\"1\"\r\n [max]=\"totalPages()\"\r\n [value]=\"pageIndex() + 1\"\r\n (input)=\"adjustWidth(pageInput)\"\r\n (change)=\"jumpToPage(pageInput)\"\r\n [disabled]=\"totalPages() === 0\"\r\n [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n />\r\n <span [style.margin-left.px]=\"4\">/</span>\r\n <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"nextPage()\"\r\n [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m10 17l5-5l-5-5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n @for (size of pageSizeOptions(); track size) {\r\n <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template\r\n #cellContextMenu\r\n let-value=\"value\"\r\n let-row=\"row\"\r\n let-colIndex=\"colIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-trigger=\"trigger\"\r\n>\r\n <div cdkMenu class=\"fu-context-menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellContextMenuTemplate()!;\r\n context: { value, row, colIndex, rowIndex, trigger }\r\n \"\r\n />\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n @for (\r\n i of [].constructor(skeletonRowCount());\r\n let rowIndex = $index;\r\n track rowIndex\r\n ) {\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n <span class=\"fu-sort-icon\">\r\n @if (!direction) {\r\n <svg\r\n class=\"fu-sort-icon-default\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'asc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'desc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n />\r\n </svg>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n <div class=\"fu-config-sidebar\">\r\n <div class=\"fu-config-item\">\r\n <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n <input\r\n id=\"stickyHeader\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyHeaderConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n <input\r\n id=\"stickyFirstColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyFirstColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n <input\r\n id=\"stickyLastColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyLastColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n <div class=\"fu-columns-panel\">\r\n <div class=\"fu-column-search\">\r\n <input\r\n class=\"fu-column-search-input\"\r\n type=\"text\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [(ngModel)]=\"searchColTerm\"\r\n />\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectAllChecked()\"\r\n [indeterminate]=\"selectAllIndeterminate()\"\r\n (change)=\"toggleFilteredSelection($event)\"\r\n [disabled]=\"filteredTotalCount() === 0\"\r\n [style.marginRight.px]=\"8\"\r\n />\r\n </div>\r\n\r\n <div\r\n class=\"fu-drag-lock fu-drag-list\"\r\n cdkDropList\r\n cdkDropListOrientation=\"vertical\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n <div\r\n class=\"fu-column-item\"\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n cdkDragBoundary=\".fu-drag-lock\"\r\n [cdkDragDisabled]=\"!col.reorderable()\"\r\n >\r\n <span\r\n class=\"fu-drag-handle\"\r\n cdkDragHandle\r\n [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n >\u2630</span\r\n >\r\n\r\n @if (col.description()) {\r\n <div class=\"fu-column-item-label\">\r\n <span class=\"fu-label\">{{ col.header() }}</span>\r\n <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n </div>\r\n } @else {\r\n <div class=\"fu-column-default\">\r\n <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n col.header()\r\n }}</span>\r\n </div>\r\n }\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"col.visible()\"\r\n [disabled]=\"\r\n !col.hideable() || (visibleCount() === 3 && col.visible())\r\n \"\r\n (change)=\"toggleVisibility(col)\"\r\n />\r\n\r\n <ng-template cdkDragPreview>\r\n <div class=\"fu-drag-preview\">\r\n <svg\r\n class=\"fu-drag-icon\"\r\n width=\"16px\"\r\n height=\"16px\"\r\n fill=\"currentColor\"\r\n viewBox=\"0 0 25 25\"\r\n >\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n ></path>\r\n </svg>\r\n <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fu-column-meta\">\r\n {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n {{ intl.visible() }}\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:207px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"] }]
|
|
2628
|
-
}], ctorParameters: () => [{ type: i0.Injector }]
|
|
2637
|
+
], template: "<div class=\"fu-new-table-wrapper\">\r\n @if (filterPanel()) {\r\n <div class=\"fu-search\">\r\n <input\r\n type=\"search\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [value]=\"searchTerm()\"\r\n (input)=\"onSearch($any($event.target).value)\"\r\n />\r\n <div class=\"fu-search-nav\">\r\n <button fuTButton (click)=\"prevMatch()\">\r\n {{ intl.previous() }}\r\n </button>\r\n <button fuTButton (click)=\"nextMatch()\">\r\n {{ intl.next() }}\r\n </button>\r\n @if (searchMatches().length > 0) {\r\n <span class=\"fu-match-counter\">\r\n {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (toolbarTemplate()) {\r\n <div class=\"fu-table-toolbar\">\r\n <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"fu-table-layout\"\r\n [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n >\r\n <div\r\n #scrollContainer\r\n class=\"fu-table-scroll\"\r\n [class.fu-scrollable]=\"scrollableConfig()\"\r\n [style.max-height.vh]=\"scrollHeightConfig()\"\r\n >\r\n <table\r\n class=\"fu-table\"\r\n [class.fu-table--responsive]=\"responsiveConfig()\"\r\n [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n >\r\n <thead>\r\n <tr>\r\n @if (expandRowTemplate()) {\r\n <th class=\"fu-expand-header\"></th>\r\n }\r\n <!-- -->\r\n @for (col of visibleColumns(); track $index) {\r\n <th\r\n (click)=\"onSort(col, $event)\"\r\n [class.fu-sortable]=\"col.isSortable()\"\r\n [style.width]=\"col.width()\"\r\n >\r\n <div class=\"fu-th-content\">\r\n @if (col.columnHeaderTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n } @else {\r\n <span class=\"fu-header-main\">\r\n <span\r\n class=\"fu-header-txt\"\r\n [class.has-desc]=\"!!col.description()\"\r\n [fuTooltip]=\"col.description() || ''\"\r\n >\r\n {{ col.header() }}\r\n </span>\r\n\r\n @if (col.isSortable()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"defaultSortIcon\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: col.sortDirection(),\r\n }\"\r\n />\r\n }\r\n </span>\r\n }\r\n <!-- -->\r\n @if (col.columnHeaderAddonTemplate()) {\r\n <span class=\"fu-header-addon\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n [ngTemplateOutletContext]=\"{ index: $index }\"\r\n />\r\n </span>\r\n }\r\n </div>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (initialLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n } @else {\r\n <!-- -->\r\n @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n @if (rowsLoading()) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n } @else {\r\n <tr\r\n [class.fu-cell-success]=\"\r\n rowStates.get(rowIndex) === 'success' && !loading()\r\n \"\r\n [class.fu-cell-error]=\"\r\n rowStates.get(rowIndex) === 'error' && !loading()\r\n \"\r\n [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n [attr.data-row-index]=\"rowIndex\"\r\n [class]=\"resolvedRowClasses()[rowIndex]\"\r\n (animationend)=\"onEditAnimationEnd()\"\r\n (click)=\"onRowClick(row, $event)\"\r\n >\r\n @if (\r\n (expandRowTemplate() && !isMobileScreen()) ||\r\n (expandRowTemplate() &&\r\n isMobileScreen() &&\r\n !responsiveConfig())\r\n ) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n <!-- -->\r\n @for (\r\n col of visibleColumns();\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n @let isMatch =\r\n activeMatchKey() === rowIndex + ':' + col.field();\r\n @let cellValue = col.accessor(row);\r\n\r\n @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n } @else {\r\n <td\r\n #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n [cdkContextMenuTriggerData]=\"{\r\n value: cellValue,\r\n row,\r\n colIndex: colIndex,\r\n rowIndex: rowIndex,\r\n trigger: contextTrigger,\r\n }\"\r\n [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n (cdkContextMenuOpened)=\"\r\n activeCell = col.field() + '-' + rowIndex\r\n \"\r\n (cdkContextMenuClosed)=\"activeCell = null\"\r\n [class.fu-context-open]=\"\r\n activeCell === col.field() + '-' + rowIndex\r\n \"\r\n [class.fu-cell-pending]=\"\r\n pendingSaveRowIndex() === rowIndex && loading()\r\n \"\r\n [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n [class.fu-cell-sorting]=\"\r\n col.isSortable() && col.sortDirection() !== null\r\n \"\r\n [class.fu-active-match]=\"isMatch\"\r\n [style]=\"\r\n col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n \"\r\n >\r\n <div class=\"fu-header-text\">\r\n {{ col.description() || col.header() }}\r\n </div>\r\n\r\n @if (col.columnCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: cellValue,\r\n row: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n searchable: col.searchable(),\r\n activeMatch: isMatch,\r\n }\"\r\n }\r\n />\r\n } @else if (col.columnActionsTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n row: row,\r\n index: rowIndex,\r\n editing: editingRowIndex() === rowIndex,\r\n expanded: expandIndex() === rowIndex,\r\n startEdit: startEditRow.bind(this),\r\n saveEdit: saveEditRow.bind(this),\r\n cancelEdit: cancelEditRow.bind(this),\r\n toggleExpand: toggleExpand.bind(this),\r\n deleteRow: deleteRow.bind(this),\r\n }\"\r\n }\r\n />\r\n } @else {\r\n <fu-cell\r\n [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n [type]=\"col.type()\"\r\n [searchTerm]=\"searchTerm()\"\r\n [editable]=\"col.editable()\"\r\n [searchable]=\"col.searchable()\"\r\n [value]=\"cellValue\"\r\n [activeMatch]=\"isMatch\"\r\n [editing]=\"editingRowIndex() === rowIndex\"\r\n (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n />\r\n }\r\n </td>\r\n }\r\n }\r\n </tr>\r\n }\r\n\r\n @if (\r\n expandRowTemplate() && isMobileScreen() && responsiveConfig()\r\n ) {\r\n <td\r\n class=\"fu-expand-cell\"\r\n [style]=\"resolvedRowStyles()[rowIndex]\"\r\n [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n (click)=\"toggleExpand(rowIndex, $event)\"\r\n >\r\n <span class=\"fu-icon\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n />\r\n </svg>\r\n </span>\r\n </td>\r\n }\r\n\r\n @if (expandIndex() === rowIndex) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n searchTerm: searchTerm(),\r\n }\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n } @empty {\r\n <tr class=\"fu-no-data-row\">\r\n <td [attr.colspan]=\"columns().length + 1\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n />\r\n </td>\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n @if (configPanel() || sidebarTemplate()) {\r\n <div\r\n class=\"fu-sidebar\"\r\n [class.fu-open]=\"isSidebarOpen()\"\r\n (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n >\r\n @if (isSidebarOpen()) {\r\n <!-- Sidebar content -->\r\n <div class=\"fu-content\">\r\n @if (isColumnsOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n } @else if (isLayoutOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n } @else if (isCustomOpen()) {\r\n <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fu-handle\">\r\n @if (configPanel()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n (click)=\"toggleColumnsPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n />\r\n </svg>\r\n </button>\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n (click)=\"toggleLayoutPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n @if (sidebarTemplate()) {\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n (click)=\"toggleCustomPanel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (paginator()) {\r\n <div class=\"fu-paginator\">\r\n <div class=\"fu-paginator-entries\">\r\n {{ entriesLabel() }}\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"prevPage()\"\r\n [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m14 7l-5 5l5 5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"fu-page-info\">\r\n {{ intl.pageLabel() }}\r\n\r\n <input\r\n class=\"fu-page-jump\"\r\n #pageInput\r\n [min]=\"1\"\r\n [max]=\"totalPages()\"\r\n [value]=\"pageIndex() + 1\"\r\n (input)=\"adjustWidth(pageInput)\"\r\n (change)=\"jumpToPage(pageInput)\"\r\n [disabled]=\"totalPages() === 0\"\r\n [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n />\r\n <span [style.margin-left.px]=\"4\">/</span>\r\n <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n </div>\r\n\r\n <button\r\n fuTButton\r\n variant=\"icon\"\r\n (click)=\"nextPage()\"\r\n [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"1.5\"\r\n d=\"m10 17l5-5l-5-5\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n @for (size of pageSizeOptions(); track size) {\r\n <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n</div>\r\n\r\n<ng-template\r\n #cellContextMenu\r\n let-value=\"value\"\r\n let-row=\"row\"\r\n let-colIndex=\"colIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-trigger=\"trigger\"\r\n>\r\n <div cdkMenu class=\"fu-context-menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellContextMenuTemplate()!;\r\n context: { value, row, colIndex, rowIndex, trigger }\r\n \"\r\n />\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n @for (\r\n i of [].constructor(skeletonRowCount());\r\n let rowIndex = $index;\r\n track rowIndex\r\n ) {\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n <tr class=\"fu-skeleton-row\">\r\n @for (\r\n j of [].constructor(skeletonColumnCount());\r\n let colIndex = $index;\r\n track colIndex\r\n ) {\r\n <td>\r\n <div class=\"fu-skeleton-cell\"></div>\r\n </td>\r\n }\r\n </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n <span class=\"fu-sort-icon\">\r\n @if (!direction) {\r\n <svg\r\n class=\"fu-sort-icon-default\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'asc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (direction === 'desc') {\r\n <svg\r\n class=\"fu-sort-icon-active\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n />\r\n </svg>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n <div class=\"fu-config-sidebar\">\r\n <div class=\"fu-config-item\">\r\n <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n </div>\r\n\r\n @if (scrollHeight()) {\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n <input\r\n id=\"stickyHeader\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyHeaderConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n }\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n <input\r\n id=\"stickyFirstColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyFirstColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n\r\n <div class=\"fu-config-item\">\r\n <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n <input\r\n id=\"stickyLastColumn\"\r\n type=\"checkbox\"\r\n [(ngModel)]=\"stickyLastColumnConfig\"\r\n [disabled]=\"!scrollableConfig()\"\r\n />\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n <div class=\"fu-columns-panel\">\r\n <div class=\"fu-column-search\">\r\n <input\r\n class=\"fu-column-search-input\"\r\n type=\"text\"\r\n [placeholder]=\"intl.searchPlaceholder()\"\r\n [(ngModel)]=\"searchColTerm\"\r\n />\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"selectAllChecked()\"\r\n [indeterminate]=\"selectAllIndeterminate()\"\r\n (change)=\"toggleFilteredSelection($event)\"\r\n [disabled]=\"filteredTotalCount() === 0\"\r\n [style.marginRight.px]=\"8\"\r\n />\r\n </div>\r\n\r\n <div\r\n class=\"fu-drag-lock fu-drag-list\"\r\n cdkDropList\r\n cdkDropListOrientation=\"vertical\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n <div\r\n class=\"fu-column-item\"\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n cdkDragBoundary=\".fu-drag-lock\"\r\n [cdkDragDisabled]=\"!col.reorderable()\"\r\n >\r\n <span\r\n class=\"fu-drag-handle\"\r\n cdkDragHandle\r\n [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n >\u2630</span\r\n >\r\n\r\n @if (col.description()) {\r\n <div class=\"fu-column-item-label\">\r\n <span class=\"fu-label\">{{ col.header() }}</span>\r\n <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n </div>\r\n } @else {\r\n <div class=\"fu-column-default\">\r\n <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n col.header()\r\n }}</span>\r\n </div>\r\n }\r\n\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"col.visible()\"\r\n [disabled]=\"\r\n !col.hideable() || (visibleCount() === 3 && col.visible())\r\n \"\r\n (change)=\"toggleVisibility(col)\"\r\n />\r\n\r\n <ng-template cdkDragPreview>\r\n <div class=\"fu-drag-preview\">\r\n <svg\r\n class=\"fu-drag-icon\"\r\n width=\"16px\"\r\n height=\"16px\"\r\n fill=\"currentColor\"\r\n viewBox=\"0 0 25 25\"\r\n >\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n ></path>\r\n </svg>\r\n <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fu-column-meta\">\r\n {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n {{ intl.visible() }}\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden;min-height:255px}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:200px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative;background-color:var(--fu-table-bg)}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1;width:136px}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"] }]
|
|
2638
|
+
}], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { onResize: [{
|
|
2639
|
+
type: HostListener,
|
|
2640
|
+
args: ['window:resize', ['$event']]
|
|
2641
|
+
}] } });
|
|
2629
2642
|
|
|
2630
2643
|
/**
|
|
2631
2644
|
* Defines a custom cell template for a `fu-column`.
|