@sd-angular/core 19.0.42 → 19.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
1
  import * as i0 from "@angular/core";
2
2
  export declare class SdSectionItem {
3
+ /** Left column text. Optional when the left column is projected through `[itemLeft]`. */
3
4
  label: import("@angular/core").InputSignal<string>;
4
5
  labelWidth: import("@angular/core").InputSignalWithTransform<string, string | null | undefined>;
5
6
  static ɵfac: i0.ɵɵFactoryDeclaration<SdSectionItem, never>;
6
- static ɵcmp: i0.ɵɵComponentDeclaration<SdSectionItem, "sd-section-item", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "labelWidth": { "alias": "labelWidth"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
7
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdSectionItem, "sd-section-item", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelWidth": { "alias": "labelWidth"; "required": false; "isSignal": true; }; }, {}, never, ["[itemLeft]", "*"], true, never>;
7
8
  }
@@ -0,0 +1,20 @@
1
+ import { SdTableItem } from '../../models/table-item.model';
2
+ import { SdTableOptionSelector } from '../../models/table-option-selector.model';
3
+ export interface SdSelectionActionKeys {
4
+ /** Key (hash) các action dòng được dùng: action con trước, rồi key action cha khi có ít nhất một con hiện. */
5
+ keys: string[];
6
+ /** Tập con của `keys` thuộc action `isGrouped` (hoặc action cha có con `isGrouped`). */
7
+ grouped: string[];
8
+ }
9
+ /** Tính các action của selector mà dòng được dùng (bỏ action có `hidden` trả về true). Không ghi gì vào dòng. */
10
+ export declare const resolveSelectionActionKeys: <T>(row: SdTableItem<T>, selection?: SdTableOptionSelector<T>) => SdSelectionActionKeys;
11
+ /**
12
+ * Ghi `meta.selector.actions` cho mọi dòng TRƯỚC khi bảng phát danh sách chọn mới (NSP-5934).
13
+ *
14
+ * why: pipe thuần `selectionDisabled` của một dòng so action của dòng đó với action của các dòng đã chọn. Trước đây
15
+ * action của một dòng chỉ được ghi khi ô checkbox của chính dòng đó render (pipe `selectionVisible`). Khi
16
+ * `preserveSelection` khôi phục dòng đã chọn thành object mới sau reload, object đó còn `actions = []` lúc các dòng
17
+ * đứng trên nó render, nên các dòng này bị khoá và pipe thuần không tính lại. Chuẩn bị trước cho mọi dòng thì kết quả
18
+ * không còn phụ thuộc thứ tự render.
19
+ */
20
+ export declare const prepareSelectionActions: <T>(rows: SdTableItem<T>[], selection?: SdTableOptionSelector<T>) => void;
@@ -43,18 +43,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
43
43
  }], ctorParameters: () => [] });
44
44
 
45
45
  class SdSectionItem {
46
- label = input.required();
46
+ /** Left column text. Optional when the left column is projected through `[itemLeft]`. */
47
+ label = input('');
47
48
  labelWidth = input('150px', {
48
49
  transform: (val) => {
49
50
  return val || '150px';
50
51
  },
51
52
  });
52
53
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSectionItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
53
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdSectionItem, isStandalone: true, selector: "sd-section-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\">{{ label() }}</div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>", styles: [":host{width:100%;display:block}.c-item{display:flex;flex-direction:row;align-items:center;column-gap:8px;padding:8px 16px;border-bottom:1px solid #f2f2f2}\n"] });
54
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdSectionItem, isStandalone: true, selector: "sd-section-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\"><ng-content select=\"[itemLeft]\">{{ label() }}</ng-content></div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>", styles: [":host{width:100%;display:block}.c-item{display:flex;flex-direction:row;align-items:center;column-gap:8px;padding:8px 16px;border-bottom:1px solid #f2f2f2}\n"] });
54
55
  }
55
56
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSectionItem, decorators: [{
56
57
  type: Component,
57
- args: [{ selector: 'sd-section-item', standalone: true, template: "<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\">{{ label() }}</div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>", styles: [":host{width:100%;display:block}.c-item{display:flex;flex-direction:row;align-items:center;column-gap:8px;padding:8px 16px;border-bottom:1px solid #f2f2f2}\n"] }]
58
+ args: [{ selector: 'sd-section-item', standalone: true, template: "<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\"><ng-content select=\"[itemLeft]\">{{ label() }}</ng-content></div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>", styles: [":host{width:100%;display:block}.c-item{display:flex;flex-direction:row;align-items:center;column-gap:8px;padding:8px 16px;border-bottom:1px solid #f2f2f2}\n"] }]
58
59
  }] });
59
60
 
60
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-components-section.mjs","sources":["../../../projects/sd-angular/components/section/src/section.component.ts","../../../projects/sd-angular/components/section/src/section.component.html","../../../projects/sd-angular/components/section/src/section-item/section-item.component.ts","../../../projects/sd-angular/components/section/src/section-item/section-item.component.html","../../../projects/sd-angular/components/section/sd-angular-core-components-section.ts"],"sourcesContent":["/* eslint-disable @angular-eslint/no-input-rename */\nimport { booleanAttribute, Component, computed, effect, ElementRef, inject, input, model } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Color } from '@sdcorejs/utils/models';\n\n@Component({\n selector: 'sd-section',\n templateUrl: './section.component.html',\n styleUrl: './section.component.scss',\n imports: [MatIconModule],\n})\nexport class SdSection {\n #el = inject(ElementRef);\n\n title = input<string | undefined | null>(undefined);\n subTitle = input<string | undefined | null>(undefined);\n icon = input<string | undefined | null>(undefined);\n iconColor = input<Color>('primary', { alias: 'iconColor' });\n\n collapsed = model<boolean>(false, { alias: 'collapsed' });\n collapsible = input(false, { transform: booleanAttribute });\n\n /** @deprecated Use `collapsible` instead. */\n collapsable = input(false, { transform: booleanAttribute });\n\n readonly isCollapsible = computed(() => this.collapsible() || this.collapsable());\n\n hideHeader = input(false, { transform: booleanAttribute });\n noPaddingBody = input(false, { transform: booleanAttribute });\n\n constructor() {\n effect(() => {\n if (this.title()) {\n this.#el.nativeElement.removeAttribute('title');\n }\n });\n }\n\n toggleCollapse = () => {\n if (this.isCollapsible()) {\n this.collapsed.set(!this.collapsed());\n } else {\n if (this.collapsed()) {\n this.collapsed.set(false);\n }\n }\n };\n}\n","@let _hideHeader = hideHeader();\n@let _isCollapsible = isCollapsible();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _icon = icon();\n@let _iconColor = iconColor();\n@let _noPaddingBody = noPaddingBody();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (_icon) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ _icon }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_isCollapsible) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- Nếu header bị ẩn thì không cần border top -->\n <div [class.p-16]=\"!_noPaddingBody\" [class.c-no-padding-body]=\"_noPaddingBody\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'sd-section-item',\n templateUrl: './section-item.component.html',\n styleUrl: 'section-item.component.scss',\n standalone: true,\n})\nexport class SdSectionItem {\n label = input.required<string>();\n labelWidth = input<string, string | null | undefined>('150px', {\n transform: (val: any): string => {\n return val || '150px';\n },\n });\n}\n","<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\">{{ label() }}</div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-components-section.mjs","sources":["../../../projects/sd-angular/components/section/src/section.component.ts","../../../projects/sd-angular/components/section/src/section.component.html","../../../projects/sd-angular/components/section/src/section-item/section-item.component.ts","../../../projects/sd-angular/components/section/src/section-item/section-item.component.html","../../../projects/sd-angular/components/section/sd-angular-core-components-section.ts"],"sourcesContent":["/* eslint-disable @angular-eslint/no-input-rename */\nimport { booleanAttribute, Component, computed, effect, ElementRef, inject, input, model } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Color } from '@sdcorejs/utils/models';\n\n@Component({\n selector: 'sd-section',\n templateUrl: './section.component.html',\n styleUrl: './section.component.scss',\n imports: [MatIconModule],\n})\nexport class SdSection {\n #el = inject(ElementRef);\n\n title = input<string | undefined | null>(undefined);\n subTitle = input<string | undefined | null>(undefined);\n icon = input<string | undefined | null>(undefined);\n iconColor = input<Color>('primary', { alias: 'iconColor' });\n\n collapsed = model<boolean>(false, { alias: 'collapsed' });\n collapsible = input(false, { transform: booleanAttribute });\n\n /** @deprecated Use `collapsible` instead. */\n collapsable = input(false, { transform: booleanAttribute });\n\n readonly isCollapsible = computed(() => this.collapsible() || this.collapsable());\n\n hideHeader = input(false, { transform: booleanAttribute });\n noPaddingBody = input(false, { transform: booleanAttribute });\n\n constructor() {\n effect(() => {\n if (this.title()) {\n this.#el.nativeElement.removeAttribute('title');\n }\n });\n }\n\n toggleCollapse = () => {\n if (this.isCollapsible()) {\n this.collapsed.set(!this.collapsed());\n } else {\n if (this.collapsed()) {\n this.collapsed.set(false);\n }\n }\n };\n}\n","@let _hideHeader = hideHeader();\n@let _isCollapsible = isCollapsible();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _icon = icon();\n@let _iconColor = iconColor();\n@let _noPaddingBody = noPaddingBody();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (_icon) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ _icon }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_isCollapsible) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- Nếu header bị ẩn thì không cần border top -->\n <div [class.p-16]=\"!_noPaddingBody\" [class.c-no-padding-body]=\"_noPaddingBody\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'sd-section-item',\n templateUrl: './section-item.component.html',\n styleUrl: 'section-item.component.scss',\n standalone: true,\n})\nexport class SdSectionItem {\n /** Left column text. Optional when the left column is projected through `[itemLeft]`. */\n label = input<string>('');\n labelWidth = input<string, string | null | undefined>('150px', {\n transform: (val: any): string => {\n return val || '150px';\n },\n });\n}\n","<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\"><ng-content select=\"[itemLeft]\">{{ label() }}</ng-content></div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2571,74 +2571,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2571
2571
  }]
2572
2572
  }] });
2573
2573
 
2574
- class SdSelectionVisiblePipe {
2575
- transform = (rowData, selection) => {
2576
- const groupedActions = [];
2577
- rowData.meta.selector.actions = rowData.meta.selector.actions || [];
2578
- if (!selection?.actions?.length) {
2579
- rowData.meta.selector.selectable = true;
2580
- return rowData.meta.selector.selectable;
2581
- }
2582
- for (const action of selection?.actions) {
2583
- if ('children' in action) {
2584
- let flag = false;
2585
- let hasGroup = false;
2586
- for (const child of action.children) {
2587
- const { hidden, isGrouped } = child;
2588
- const key = Utilities.hash(child);
2589
- if (isGrouped) {
2590
- hasGroup = true;
2591
- }
2592
- if (typeof hidden === 'function') {
2593
- if (!hidden(rowData.data)) {
2594
- flag = true;
2595
- rowData.meta.selector.actions.push(key);
2596
- if (isGrouped) {
2597
- groupedActions.push(key);
2598
- }
2599
- }
2600
- }
2601
- else if (!hidden) {
2602
- flag = true;
2603
- rowData.meta.selector.actions.push(key);
2604
- if (isGrouped) {
2605
- groupedActions.push(key);
2606
- }
2607
- }
2608
- }
2609
- if (flag) {
2610
- rowData.meta.selector.actions.push(Utilities.hash(action));
2611
- if (hasGroup) {
2612
- groupedActions.push(Utilities.hash(action));
2613
- }
2614
- }
2574
+ const isShown = (hidden, row) => typeof hidden === 'function' ? !hidden(row.data) : !hidden;
2575
+ /** Tính các action của selector mà dòng được dùng (bỏ action có `hidden` trả về true). Không ghi gì vào dòng. */
2576
+ const resolveSelectionActionKeys = (row, selection) => {
2577
+ const keys = [];
2578
+ const grouped = [];
2579
+ for (const action of selection?.actions ?? []) {
2580
+ if ('children' in action) {
2581
+ let shown = false;
2582
+ let hasGroup = false;
2583
+ for (const child of action.children) {
2584
+ if (child.isGrouped)
2585
+ hasGroup = true;
2586
+ if (!isShown(child.hidden, row))
2587
+ continue;
2588
+ const key = Utilities.hash(child);
2589
+ shown = true;
2590
+ keys.push(key);
2591
+ if (child.isGrouped)
2592
+ grouped.push(key);
2615
2593
  }
2616
- else {
2617
- const { hidden, isGrouped } = action;
2594
+ if (shown) {
2618
2595
  const key = Utilities.hash(action);
2619
- if (typeof hidden === 'function') {
2620
- if (!hidden(rowData.data)) {
2621
- rowData.meta.selector.actions.push(key);
2622
- if (isGrouped) {
2623
- groupedActions.push(key);
2624
- }
2625
- }
2626
- }
2627
- else if (!hidden) {
2628
- rowData.meta.selector.actions.push(key);
2629
- if (isGrouped) {
2630
- groupedActions.push(key);
2631
- }
2632
- }
2596
+ keys.push(key);
2597
+ if (hasGroup)
2598
+ grouped.push(key);
2633
2599
  }
2634
2600
  }
2635
- rowData.meta.selector.selectable = !!rowData.meta.selector.actions?.length;
2636
- if (!rowData.meta.selector.selectable || !groupedActions.length || rowData?.meta.group?.items?.length) {
2637
- return rowData.meta.selector.selectable;
2601
+ else if (isShown(action.hidden, row)) {
2602
+ const key = Utilities.hash(action);
2603
+ keys.push(key);
2604
+ if (action.isGrouped)
2605
+ grouped.push(key);
2606
+ }
2607
+ }
2608
+ return { keys, grouped };
2609
+ };
2610
+ /**
2611
+ * Ghi `meta.selector.actions` cho mọi dòng TRƯỚC khi bảng phát danh sách chọn mới (NSP-5934).
2612
+ *
2613
+ * why: pipe thuần `selectionDisabled` của một dòng so action của dòng đó với action của các dòng đã chọn. Trước đây
2614
+ * action của một dòng chỉ được ghi khi ô checkbox của chính dòng đó render (pipe `selectionVisible`). Khi
2615
+ * `preserveSelection` khôi phục dòng đã chọn thành object mới sau reload, object đó còn `actions = []` lúc các dòng
2616
+ * đứng trên nó render, nên các dòng này bị khoá và pipe thuần không tính lại. Chuẩn bị trước cho mọi dòng thì kết quả
2617
+ * không còn phụ thuộc thứ tự render.
2618
+ */
2619
+ const prepareSelectionActions = (rows, selection) => {
2620
+ if (!selection?.actions?.length)
2621
+ return;
2622
+ for (const row of new Set(rows)) {
2623
+ if (!row.meta.selector)
2624
+ continue;
2625
+ row.meta.selector.actions = resolveSelectionActionKeys(row, selection).keys;
2626
+ }
2627
+ };
2628
+
2629
+ class SdSelectionVisiblePipe {
2630
+ transform = (rowData, selection) => {
2631
+ const selector = rowData.meta.selector;
2632
+ if (!selection?.actions?.length) {
2633
+ selector.actions = selector.actions || [];
2634
+ selector.selectable = true;
2635
+ return selector.selectable;
2636
+ }
2637
+ // why: gán lại thay vì push để key không bị nhân đôi khi bảng đã chuẩn bị trước (prepareSelectionActions).
2638
+ const { keys, grouped } = resolveSelectionActionKeys(rowData, selection);
2639
+ selector.actions = keys;
2640
+ selector.selectable = !!keys.length;
2641
+ if (!selector.selectable || !grouped.length || rowData?.meta.group?.items?.length) {
2642
+ return selector.selectable;
2638
2643
  }
2639
2644
  // Đối với trường hợp grouped, tuy selectable là true nhưng vẫn ẩn đi checkbox
2640
2645
  // nếu các action đều thuộc groupedActions và rowData ko phải là dòng group
2641
- return rowData.meta.selector.actions.some(action => !groupedActions.includes(action));
2646
+ return keys.some(action => !grouped.includes(action));
2642
2647
  };
2643
2648
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSelectionVisiblePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2644
2649
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.21", ngImport: i0, type: SdSelectionVisiblePipe, isStandalone: true, name: "selectionVisible" });
@@ -4777,14 +4782,15 @@ class SdTable {
4777
4782
  };
4778
4783
  #updateSelectedItems = () => {
4779
4784
  const rows = this.#getSelectionRows();
4780
- if (this.#preserveEnabled()) {
4781
- // Sync map theo state visible: add nếu selected, remove nếu deselected.
4782
- // Off-page items giữ nguyên trong map (không bị visit ở đây).
4783
- this.selectedTableItems.set(syncPreservedSelection(rows, this.#preservedSelectedMap));
4784
- }
4785
- else {
4786
- this.selectedTableItems.set(rows.filter(item => item.meta.selector.isSelected));
4787
- }
4785
+ // Sync map theo state visible: add nếu selected, remove nếu deselected.
4786
+ // Off-page items giữ nguyên trong map (không bị visit ở đây).
4787
+ const selected = this.#preserveEnabled()
4788
+ ? syncPreservedSelection(rows, this.#preservedSelectedMap)
4789
+ : rows.filter(item => item.meta.selector.isSelected);
4790
+ // why: dòng đã chọn khôi phục sau reload là object mới chưa có action; chuẩn bị action cho mọi dòng trước khi
4791
+ // phát danh sách chọn để pipe selectionDisabled không khoá nhầm các dòng render trước nó (NSP-5934).
4792
+ prepareSelectionActions([...rows, ...selected], this.tableOption()?.selector);
4793
+ this.selectedTableItems.set(selected);
4788
4794
  this.#ref.detectChanges();
4789
4795
  };
4790
4796
  clearFilter = () => {