@firestitch/list 18.0.79 → 18.0.80

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.
@@ -23,6 +23,13 @@ export declare class FsBodyComponent {
23
23
  reorderMultiple: boolean;
24
24
  rowsContainer: any;
25
25
  headerTemplate: TemplateRef<any>;
26
+ /**
27
+ * Track rows by their underlying record id so that a reload (which creates
28
+ * fresh Row wrapper objects) reuses the existing DOM instead of destroying
29
+ * and recreating every row. Falls back to the row index when the data has
30
+ * no id (e.g. group/footer rows or id-less records) -> avoids NG0956.
31
+ */
32
+ trackByFn(index: number, row: Row): unknown;
26
33
  static ɵfac: i0.ɵɵFactoryDeclaration<FsBodyComponent, never>;
27
34
  static ɵcmp: i0.ɵɵComponentDeclaration<FsBodyComponent, "[fs-list-body]", never, { "rows": { "alias": "rows"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "hasFooter": { "alias": "hasFooter"; "required": false; }; "rowActionsRaw": { "alias": "rowActionsRaw"; "required": false; }; "groupActionsRaw": { "alias": "groupActionsRaw"; "required": false; }; "rowEvents": { "alias": "rowEvents"; "required": false; }; "rowClass": { "alias": "rowClass"; "required": false; }; "hasRowActions": { "alias": "hasRowActions"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "restoreMode": { "alias": "restoreMode"; "required": false; }; "rowRemoved": { "alias": "rowRemoved"; "required": false; }; "activeFiltersCount": { "alias": "activeFiltersCount"; "required": false; }; "reorderEnabled": { "alias": "reorderEnabled"; "required": false; }; "reorderPosition": { "alias": "reorderPosition"; "required": false; }; "reorderStrategy": { "alias": "reorderStrategy"; "required": false; }; "reorderMultiple": { "alias": "reorderMultiple"; "required": false; }; }, {}, ["headerTemplate"], never, true, never>;
28
35
  }
@@ -23,15 +23,25 @@ export class FsBodyComponent {
23
23
  reorderMultiple;
24
24
  rowsContainer;
25
25
  headerTemplate;
26
+ /**
27
+ * Track rows by their underlying record id so that a reload (which creates
28
+ * fresh Row wrapper objects) reuses the existing DOM instead of destroying
29
+ * and recreating every row. Falls back to the row index when the data has
30
+ * no id (e.g. group/footer rows or id-less records) -> avoids NG0956.
31
+ */
32
+ trackByFn(index, row) {
33
+ const id = row?.data?.id;
34
+ return id ?? index;
35
+ }
26
36
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: FsBodyComponent, isStandalone: true, selector: "[fs-list-body]", inputs: { rows: "rows", columns: "columns", hasFooter: "hasFooter", rowActionsRaw: "rowActionsRaw", groupActionsRaw: "groupActionsRaw", rowEvents: "rowEvents", rowClass: "rowClass", hasRowActions: "hasRowActions", selection: "selection", restoreMode: "restoreMode", rowRemoved: "rowRemoved", activeFiltersCount: "activeFiltersCount", reorderEnabled: "reorderEnabled", reorderPosition: "reorderPosition", reorderStrategy: "reorderStrategy", reorderMultiple: "reorderMultiple" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: FsRowComponent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "rowsContainer", first: true, predicate: ["rowsContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "@for (row of rows; track row; let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"], dependencies: [{ kind: "component", type: FsRowComponent, selector: "[fs-list-row]", inputs: ["row", "rowActionsRaw", "groupActionsRaw", "hasRowActions", "rowEvents", "rowClass", "restoreMode", "rowIndex", "columns", "selection", "rowRemoved", "activeFiltersCount", "reorderEnabled", "reorderPosition", "reorderStrategy", "reorderMultiple"] }, { kind: "directive", type: FsListDraggableRowDirective, selector: "[fsListDraggableRow]", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: FsBodyComponent, isStandalone: true, selector: "[fs-list-body]", inputs: { rows: "rows", columns: "columns", hasFooter: "hasFooter", rowActionsRaw: "rowActionsRaw", groupActionsRaw: "groupActionsRaw", rowEvents: "rowEvents", rowClass: "rowClass", hasRowActions: "hasRowActions", selection: "selection", restoreMode: "restoreMode", rowRemoved: "rowRemoved", activeFiltersCount: "activeFiltersCount", reorderEnabled: "reorderEnabled", reorderPosition: "reorderPosition", reorderStrategy: "reorderStrategy", reorderMultiple: "reorderMultiple" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: FsRowComponent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "rowsContainer", first: true, predicate: ["rowsContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "@for (row of rows; track trackByFn(i, row); let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"], dependencies: [{ kind: "component", type: FsRowComponent, selector: "[fs-list-row]", inputs: ["row", "rowActionsRaw", "groupActionsRaw", "hasRowActions", "rowEvents", "rowClass", "restoreMode", "rowIndex", "columns", "selection", "rowRemoved", "activeFiltersCount", "reorderEnabled", "reorderPosition", "reorderStrategy", "reorderMultiple"] }, { kind: "directive", type: FsListDraggableRowDirective, selector: "[fsListDraggableRow]", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
28
38
  }
29
39
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsBodyComponent, decorators: [{
30
40
  type: Component,
31
41
  args: [{ selector: '[fs-list-body]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
32
42
  FsRowComponent,
33
43
  FsListDraggableRowDirective,
34
- ], template: "@for (row of rows; track row; let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"] }]
44
+ ], template: "@for (row of rows; track trackByFn(i, row); let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"] }]
35
45
  }], propDecorators: { rows: [{
36
46
  type: Input
37
47
  }], columns: [{
@@ -71,4 +81,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
71
81
  type: ContentChild,
72
82
  args: [FsRowComponent, { read: TemplateRef, static: true }]
73
83
  }] } });
74
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvYm9keS9ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50cy9ib2R5L2JvZHkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBQ0wsV0FBVyxFQUNYLFNBQVMsRUFDVCxnQkFBZ0IsR0FDakIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUlyRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBY3JELE1BQU0sT0FBTyxlQUFlO0lBRVYsSUFBSSxDQUFRO0lBQ1osT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUN2QixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLGFBQWEsR0FBVSxFQUFFLENBQUM7SUFDMUIsZUFBZSxHQUFVLEVBQUUsQ0FBQztJQUM1QixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ2YsUUFBUSxDQUFDO0lBQ1QsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0QixTQUFTLENBQXNCO0lBQy9CLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsVUFBVSxDQUFvQjtJQUM5QixrQkFBa0IsQ0FBUztJQUMzQixjQUFjLENBQVU7SUFDeEIsZUFBZSxDQUF5QjtJQUN4QyxlQUFlLENBQXlCO0lBQ3hDLGVBQWUsQ0FBVTtJQUdsQyxhQUFhLENBQUM7SUFHZCxjQUFjLENBQW1CO3VHQXZCN0IsZUFBZTsyRkFBZixlQUFlLG9sQkFzQlosY0FBYywyQkFBVSxXQUFXLHNJQUhiLGdCQUFnQiwyQ0NsRHRELHFxQkFxQkMseUtETUcsY0FBYywyVEFDZCwyQkFBMkI7OzJGQUdsQixlQUFlO2tCQVgzQixTQUFTOytCQUNFLGdCQUFnQixtQkFHVCx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxjQUFjO3dCQUNkLDJCQUEyQjtxQkFDNUI7OEJBSWUsSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxPQUFPO3NCQUF0QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsYUFBYTtzQkFBNUIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsUUFBUTtzQkFBdkIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLGtCQUFrQjtzQkFBakMsS0FBSztnQkFDVSxjQUFjO3NCQUE3QixLQUFLO2dCQUNVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBQ1UsZUFBZTtzQkFBOUIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUdDLGFBQWE7c0JBRG5CLFNBQVM7dUJBQUMsZUFBZSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSTdELGNBQWM7c0JBRHBCLFlBQVk7dUJBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgUmVvcmRlclBvc2l0aW9uLCBSZW9yZGVyU3RyYXRlZ3kgfSBmcm9tICcuLi8uLi9jbGFzc2VzL3Jlb3JkZXItY29udHJvbGxlcic7XG5pbXBvcnQgeyBTZWxlY3Rpb25Db250cm9sbGVyIH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy9zZWxlY3Rpb24tY29udHJvbGxlcic7XG5pbXBvcnQgeyBGc0xpc3REcmFnZ2FibGVSb3dEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2RyYWdnYWJsZS1yb3cvZHJhZ2dhYmxlLXJvdy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi5tb2RlbCc7XG5pbXBvcnQgeyBSb3cgfSBmcm9tICcuLi8uLi9tb2RlbHMvcm93JztcblxuaW1wb3J0IHsgRnNSb3dDb21wb25lbnQgfSBmcm9tICcuL3Jvdy9yb3cuY29tcG9uZW50JztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdbZnMtbGlzdC1ib2R5XScsXG4gIHRlbXBsYXRlVXJsOiAnLi9ib2R5LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYm9keS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZzUm93Q29tcG9uZW50LFxuICAgIEZzTGlzdERyYWdnYWJsZVJvd0RpcmVjdGl2ZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRnNCb2R5Q29tcG9uZW50IHtcblxuICBASW5wdXQoKSBwdWJsaWMgcm93czogUm93W107XG4gIEBJbnB1dCgpIHB1YmxpYyBjb2x1bW5zOiBDb2x1bW5bXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgaGFzRm9vdGVyID0gZmFsc2U7XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dBY3Rpb25zUmF3OiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgZ3JvdXBBY3Rpb25zUmF3OiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgcm93RXZlbnRzID0ge307XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dDbGFzcztcbiAgQElucHV0KCkgcHVibGljIGhhc1Jvd0FjdGlvbnMgPSBmYWxzZTtcbiAgQElucHV0KCkgcHVibGljIHNlbGVjdGlvbjogU2VsZWN0aW9uQ29udHJvbGxlcjtcbiAgQElucHV0KCkgcHVibGljIHJlc3RvcmVNb2RlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dSZW1vdmVkOiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgQElucHV0KCkgcHVibGljIGFjdGl2ZUZpbHRlcnNDb3VudDogbnVtYmVyO1xuICBASW5wdXQoKSBwdWJsaWMgcmVvcmRlckVuYWJsZWQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyUG9zaXRpb246IFJlb3JkZXJQb3NpdGlvbiB8IG51bGw7XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyU3RyYXRlZ3k6IFJlb3JkZXJTdHJhdGVneSB8IG51bGw7XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyTXVsdGlwbGU6IGJvb2xlYW47XG5cbiAgQFZpZXdDaGlsZCgncm93c0NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHB1YmxpYyByb3dzQ29udGFpbmVyO1xuXG4gIEBDb250ZW50Q2hpbGQoRnNSb3dDb21wb25lbnQsIHsgcmVhZDogVGVtcGxhdGVSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICBwdWJsaWMgaGVhZGVyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbn1cbiIsIkBmb3IgKHJvdyBvZiByb3dzOyB0cmFjayByb3c7IGxldCBpID0gJGluZGV4KSB7XG4gIDx0clxuICAgIGZzLWxpc3Qtcm93XG4gICAgZnNMaXN0RHJhZ2dhYmxlUm93XG4gICAgW3Jvd109XCJyb3dcIlxuICAgIFtyb3dJbmRleF09XCJpXCJcbiAgICBbY29sdW1uc109XCJjb2x1bW5zXCJcbiAgICBbcm93QWN0aW9uc1Jhd109XCJyb3dBY3Rpb25zUmF3XCJcbiAgICBbZ3JvdXBBY3Rpb25zUmF3XT1cImdyb3VwQWN0aW9uc1Jhd1wiXG4gICAgW2hhc1Jvd0FjdGlvbnNdPVwiaGFzUm93QWN0aW9uc1wiXG4gICAgW3Jvd0V2ZW50c109XCJyb3dFdmVudHNcIlxuICAgIFtyb3dDbGFzc109XCJyb3dDbGFzc1wiXG4gICAgW3NlbGVjdGlvbl09XCJzZWxlY3Rpb25cIlxuICAgIFtyZXN0b3JlTW9kZV09XCJyZXN0b3JlTW9kZVwiXG4gICAgW3Jvd1JlbW92ZWRdPVwicm93UmVtb3ZlZFwiXG4gICAgW2FjdGl2ZUZpbHRlcnNDb3VudF09XCJhY3RpdmVGaWx0ZXJzQ291bnRcIlxuICAgIFtyZW9yZGVyRW5hYmxlZF09XCJyZW9yZGVyRW5hYmxlZFwiXG4gICAgW3Jlb3JkZXJQb3NpdGlvbl09XCJyZW9yZGVyUG9zaXRpb25cIlxuICAgIFtyZW9yZGVyU3RyYXRlZ3ldPVwicmVvcmRlclN0cmF0ZWd5XCJcbiAgICBbcmVvcmRlck11bHRpcGxlXT1cInJlb3JkZXJNdWx0aXBsZVwiPlxuICA8L3RyPlxufSJdfQ==
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvYm9keS9ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50cy9ib2R5L2JvZHkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBQ0wsV0FBVyxFQUNYLFNBQVMsRUFDVCxnQkFBZ0IsR0FDakIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUlyRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBY3JELE1BQU0sT0FBTyxlQUFlO0lBRVYsSUFBSSxDQUFRO0lBQ1osT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUN2QixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLGFBQWEsR0FBVSxFQUFFLENBQUM7SUFDMUIsZUFBZSxHQUFVLEVBQUUsQ0FBQztJQUM1QixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ2YsUUFBUSxDQUFDO0lBQ1QsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0QixTQUFTLENBQXNCO0lBQy9CLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsVUFBVSxDQUFvQjtJQUM5QixrQkFBa0IsQ0FBUztJQUMzQixjQUFjLENBQVU7SUFDeEIsZUFBZSxDQUF5QjtJQUN4QyxlQUFlLENBQXlCO0lBQ3hDLGVBQWUsQ0FBVTtJQUdsQyxhQUFhLENBQUM7SUFHZCxjQUFjLENBQW1CO0lBRXhDOzs7OztPQUtHO0lBQ0ksU0FBUyxDQUFDLEtBQWEsRUFBRSxHQUFRO1FBQ3RDLE1BQU0sRUFBRSxHQUFJLEdBQUcsRUFBRSxJQUF5QixFQUFFLEVBQUUsQ0FBQztRQUUvQyxPQUFPLEVBQUUsSUFBSSxLQUFLLENBQUM7SUFDckIsQ0FBQzt1R0FuQ1UsZUFBZTsyRkFBZixlQUFlLG9sQkFzQlosY0FBYywyQkFBVSxXQUFXLHNJQUhiLGdCQUFnQiwyQ0NsRHRELG1yQkFxQkMseUtETUcsY0FBYywyVEFDZCwyQkFBMkI7OzJGQUdsQixlQUFlO2tCQVgzQixTQUFTOytCQUNFLGdCQUFnQixtQkFHVCx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxjQUFjO3dCQUNkLDJCQUEyQjtxQkFDNUI7OEJBSWUsSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxPQUFPO3NCQUF0QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsYUFBYTtzQkFBNUIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsUUFBUTtzQkFBdkIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLGtCQUFrQjtzQkFBakMsS0FBSztnQkFDVSxjQUFjO3NCQUE3QixLQUFLO2dCQUNVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBQ1UsZUFBZTtzQkFBOUIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUdDLGFBQWE7c0JBRG5CLFNBQVM7dUJBQUMsZUFBZSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSTdELGNBQWM7c0JBRHBCLFlBQVk7dUJBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgUmVvcmRlclBvc2l0aW9uLCBSZW9yZGVyU3RyYXRlZ3kgfSBmcm9tICcuLi8uLi9jbGFzc2VzL3Jlb3JkZXItY29udHJvbGxlcic7XG5pbXBvcnQgeyBTZWxlY3Rpb25Db250cm9sbGVyIH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy9zZWxlY3Rpb24tY29udHJvbGxlcic7XG5pbXBvcnQgeyBGc0xpc3REcmFnZ2FibGVSb3dEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2RyYWdnYWJsZS1yb3cvZHJhZ2dhYmxlLXJvdy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi5tb2RlbCc7XG5pbXBvcnQgeyBSb3cgfSBmcm9tICcuLi8uLi9tb2RlbHMvcm93JztcblxuaW1wb3J0IHsgRnNSb3dDb21wb25lbnQgfSBmcm9tICcuL3Jvdy9yb3cuY29tcG9uZW50JztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdbZnMtbGlzdC1ib2R5XScsXG4gIHRlbXBsYXRlVXJsOiAnLi9ib2R5LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYm9keS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZzUm93Q29tcG9uZW50LFxuICAgIEZzTGlzdERyYWdnYWJsZVJvd0RpcmVjdGl2ZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRnNCb2R5Q29tcG9uZW50IHtcblxuICBASW5wdXQoKSBwdWJsaWMgcm93czogUm93W107XG4gIEBJbnB1dCgpIHB1YmxpYyBjb2x1bW5zOiBDb2x1bW5bXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgaGFzRm9vdGVyID0gZmFsc2U7XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dBY3Rpb25zUmF3OiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgZ3JvdXBBY3Rpb25zUmF3OiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgcm93RXZlbnRzID0ge307XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dDbGFzcztcbiAgQElucHV0KCkgcHVibGljIGhhc1Jvd0FjdGlvbnMgPSBmYWxzZTtcbiAgQElucHV0KCkgcHVibGljIHNlbGVjdGlvbjogU2VsZWN0aW9uQ29udHJvbGxlcjtcbiAgQElucHV0KCkgcHVibGljIHJlc3RvcmVNb2RlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHB1YmxpYyByb3dSZW1vdmVkOiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgQElucHV0KCkgcHVibGljIGFjdGl2ZUZpbHRlcnNDb3VudDogbnVtYmVyO1xuICBASW5wdXQoKSBwdWJsaWMgcmVvcmRlckVuYWJsZWQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyUG9zaXRpb246IFJlb3JkZXJQb3NpdGlvbiB8IG51bGw7XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyU3RyYXRlZ3k6IFJlb3JkZXJTdHJhdGVneSB8IG51bGw7XG4gIEBJbnB1dCgpIHB1YmxpYyByZW9yZGVyTXVsdGlwbGU6IGJvb2xlYW47XG5cbiAgQFZpZXdDaGlsZCgncm93c0NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHB1YmxpYyByb3dzQ29udGFpbmVyO1xuXG4gIEBDb250ZW50Q2hpbGQoRnNSb3dDb21wb25lbnQsIHsgcmVhZDogVGVtcGxhdGVSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICBwdWJsaWMgaGVhZGVyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLyoqXG4gICAqIFRyYWNrIHJvd3MgYnkgdGhlaXIgdW5kZXJseWluZyByZWNvcmQgaWQgc28gdGhhdCBhIHJlbG9hZCAod2hpY2ggY3JlYXRlc1xuICAgKiBmcmVzaCBSb3cgd3JhcHBlciBvYmplY3RzKSByZXVzZXMgdGhlIGV4aXN0aW5nIERPTSBpbnN0ZWFkIG9mIGRlc3Ryb3lpbmdcbiAgICogYW5kIHJlY3JlYXRpbmcgZXZlcnkgcm93LiBGYWxscyBiYWNrIHRvIHRoZSByb3cgaW5kZXggd2hlbiB0aGUgZGF0YSBoYXNcbiAgICogbm8gaWQgKGUuZy4gZ3JvdXAvZm9vdGVyIHJvd3Mgb3IgaWQtbGVzcyByZWNvcmRzKSAtPiBhdm9pZHMgTkcwOTU2LlxuICAgKi9cbiAgcHVibGljIHRyYWNrQnlGbihpbmRleDogbnVtYmVyLCByb3c6IFJvdyk6IHVua25vd24ge1xuICAgIGNvbnN0IGlkID0gKHJvdz8uZGF0YSBhcyB7IGlkPzogdW5rbm93biB9KT8uaWQ7XG5cbiAgICByZXR1cm4gaWQgPz8gaW5kZXg7XG4gIH1cblxufVxuIiwiQGZvciAocm93IG9mIHJvd3M7IHRyYWNrIHRyYWNrQnlGbihpLCByb3cpOyBsZXQgaSA9ICRpbmRleCkge1xuICA8dHJcbiAgICBmcy1saXN0LXJvd1xuICAgIGZzTGlzdERyYWdnYWJsZVJvd1xuICAgIFtyb3ddPVwicm93XCJcbiAgICBbcm93SW5kZXhdPVwiaVwiXG4gICAgW2NvbHVtbnNdPVwiY29sdW1uc1wiXG4gICAgW3Jvd0FjdGlvbnNSYXddPVwicm93QWN0aW9uc1Jhd1wiXG4gICAgW2dyb3VwQWN0aW9uc1Jhd109XCJncm91cEFjdGlvbnNSYXdcIlxuICAgIFtoYXNSb3dBY3Rpb25zXT1cImhhc1Jvd0FjdGlvbnNcIlxuICAgIFtyb3dFdmVudHNdPVwicm93RXZlbnRzXCJcbiAgICBbcm93Q2xhc3NdPVwicm93Q2xhc3NcIlxuICAgIFtzZWxlY3Rpb25dPVwic2VsZWN0aW9uXCJcbiAgICBbcmVzdG9yZU1vZGVdPVwicmVzdG9yZU1vZGVcIlxuICAgIFtyb3dSZW1vdmVkXT1cInJvd1JlbW92ZWRcIlxuICAgIFthY3RpdmVGaWx0ZXJzQ291bnRdPVwiYWN0aXZlRmlsdGVyc0NvdW50XCJcbiAgICBbcmVvcmRlckVuYWJsZWRdPVwicmVvcmRlckVuYWJsZWRcIlxuICAgIFtyZW9yZGVyUG9zaXRpb25dPVwicmVvcmRlclBvc2l0aW9uXCJcbiAgICBbcmVvcmRlclN0cmF0ZWd5XT1cInJlb3JkZXJTdHJhdGVneVwiXG4gICAgW3Jlb3JkZXJNdWx0aXBsZV09XCJyZW9yZGVyTXVsdGlwbGVcIj5cbiAgPC90cj5cbn0iXX0=
@@ -2552,15 +2552,25 @@ class FsBodyComponent {
2552
2552
  reorderMultiple;
2553
2553
  rowsContainer;
2554
2554
  headerTemplate;
2555
+ /**
2556
+ * Track rows by their underlying record id so that a reload (which creates
2557
+ * fresh Row wrapper objects) reuses the existing DOM instead of destroying
2558
+ * and recreating every row. Falls back to the row index when the data has
2559
+ * no id (e.g. group/footer rows or id-less records) -> avoids NG0956.
2560
+ */
2561
+ trackByFn(index, row) {
2562
+ const id = row?.data?.id;
2563
+ return id ?? index;
2564
+ }
2555
2565
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2556
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: FsBodyComponent, isStandalone: true, selector: "[fs-list-body]", inputs: { rows: "rows", columns: "columns", hasFooter: "hasFooter", rowActionsRaw: "rowActionsRaw", groupActionsRaw: "groupActionsRaw", rowEvents: "rowEvents", rowClass: "rowClass", hasRowActions: "hasRowActions", selection: "selection", restoreMode: "restoreMode", rowRemoved: "rowRemoved", activeFiltersCount: "activeFiltersCount", reorderEnabled: "reorderEnabled", reorderPosition: "reorderPosition", reorderStrategy: "reorderStrategy", reorderMultiple: "reorderMultiple" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: FsRowComponent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "rowsContainer", first: true, predicate: ["rowsContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "@for (row of rows; track row; let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"], dependencies: [{ kind: "component", type: FsRowComponent, selector: "[fs-list-row]", inputs: ["row", "rowActionsRaw", "groupActionsRaw", "hasRowActions", "rowEvents", "rowClass", "restoreMode", "rowIndex", "columns", "selection", "rowRemoved", "activeFiltersCount", "reorderEnabled", "reorderPosition", "reorderStrategy", "reorderMultiple"] }, { kind: "directive", type: FsListDraggableRowDirective, selector: "[fsListDraggableRow]", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2566
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: FsBodyComponent, isStandalone: true, selector: "[fs-list-body]", inputs: { rows: "rows", columns: "columns", hasFooter: "hasFooter", rowActionsRaw: "rowActionsRaw", groupActionsRaw: "groupActionsRaw", rowEvents: "rowEvents", rowClass: "rowClass", hasRowActions: "hasRowActions", selection: "selection", restoreMode: "restoreMode", rowRemoved: "rowRemoved", activeFiltersCount: "activeFiltersCount", reorderEnabled: "reorderEnabled", reorderPosition: "reorderPosition", reorderStrategy: "reorderStrategy", reorderMultiple: "reorderMultiple" }, queries: [{ propertyName: "headerTemplate", first: true, predicate: FsRowComponent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "rowsContainer", first: true, predicate: ["rowsContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "@for (row of rows; track trackByFn(i, row); let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"], dependencies: [{ kind: "component", type: FsRowComponent, selector: "[fs-list-row]", inputs: ["row", "rowActionsRaw", "groupActionsRaw", "hasRowActions", "rowEvents", "rowClass", "restoreMode", "rowIndex", "columns", "selection", "rowRemoved", "activeFiltersCount", "reorderEnabled", "reorderPosition", "reorderStrategy", "reorderMultiple"] }, { kind: "directive", type: FsListDraggableRowDirective, selector: "[fsListDraggableRow]", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2557
2567
  }
2558
2568
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsBodyComponent, decorators: [{
2559
2569
  type: Component,
2560
2570
  args: [{ selector: '[fs-list-body]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2561
2571
  FsRowComponent,
2562
2572
  FsListDraggableRowDirective,
2563
- ], template: "@for (row of rows; track row; let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"] }]
2573
+ ], template: "@for (row of rows; track trackByFn(i, row); let i = $index) {\n <tr\n fs-list-row\n fsListDraggableRow\n [row]=\"row\"\n [rowIndex]=\"i\"\n [columns]=\"columns\"\n [rowActionsRaw]=\"rowActionsRaw\"\n [groupActionsRaw]=\"groupActionsRaw\"\n [hasRowActions]=\"hasRowActions\"\n [rowEvents]=\"rowEvents\"\n [rowClass]=\"rowClass\"\n [selection]=\"selection\"\n [restoreMode]=\"restoreMode\"\n [rowRemoved]=\"rowRemoved\"\n [activeFiltersCount]=\"activeFiltersCount\"\n [reorderEnabled]=\"reorderEnabled\"\n [reorderPosition]=\"reorderPosition\"\n [reorderStrategy]=\"reorderStrategy\"\n [reorderMultiple]=\"reorderMultiple\">\n </tr>\n}", styles: [":host.drag-hidden .drag-col{opacity:0!important;cursor:default}:host.disabled{opacity:.4;pointer-events:none}\n"] }]
2564
2574
  }], propDecorators: { rows: [{
2565
2575
  type: Input
2566
2576
  }], columns: [{