@sdcorejs/angular 19.0.9 → 19.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +270 -140
  2. package/assets/scss/core/utilities/_grid.scss +25 -19
  3. package/components/anchor/src/models/sd-anchor.model.d.ts +1 -1
  4. package/components/document-builder/src/document-builder.component.d.ts +2 -2
  5. package/components/document-builder/src/plugins/paste-handler/filters/parse.d.ts +1 -1
  6. package/components/editor/src/plugins/image-upload/utils/batch.utils.d.ts +3 -3
  7. package/components/form-generic/src/components/form-builder/components/attribute-expression/attribute-expression.component.d.ts +10 -6
  8. package/components/form-generic/src/components/form-builder/components/attribute-expression/form-expression-query-adapter.d.ts +6 -0
  9. package/components/form-generic/src/components/form-builder/components/attribute-parameter/attribute-parameter.component.d.ts +2 -2
  10. package/components/form-generic/src/components/form-builder/components/attribute-selection/attribute-selection.component.d.ts +2 -2
  11. package/components/form-generic/src/components/form-builder/components/attribute-selection/components/build-queries/build-queries.component.d.ts +2 -2
  12. package/components/form-generic/src/components/form-builder/components/attribute-selection/components/build-variables/build-variables.component.d.ts +2 -2
  13. package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +2 -4
  14. package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +2 -4
  15. package/components/form-generic/src/components/form-builder/components/checkbox/attribute/checkbox-attribute.component.d.ts +2 -2
  16. package/components/form-generic/src/components/form-builder/components/chip-calendar/attribute/chip-calendar-attribute.component.d.ts +2 -2
  17. package/components/form-generic/src/components/form-builder/components/chip-calendar/control/chip-calendar-control.component.d.ts +2 -2
  18. package/components/form-generic/src/components/form-builder/components/chip-string/attribute/chip-string-attribute.component.d.ts +2 -2
  19. package/components/form-generic/src/components/form-builder/components/chip-string/control/chip-string-control.component.d.ts +2 -2
  20. package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +6 -7
  21. package/components/form-generic/src/components/form-builder/components/datetime/attribute/datetime-attribute.component.d.ts +2 -2
  22. package/components/form-generic/src/components/form-builder/components/datetime/control/datetime-control.component.d.ts +2 -2
  23. package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +2 -2
  24. package/components/form-generic/src/components/form-builder/components/html/attribute/components/build-queries/build-queries.component.d.ts +2 -2
  25. package/components/form-generic/src/components/form-builder/components/html/control/html-control.component.d.ts +2 -2
  26. package/components/form-generic/src/components/form-builder/components/number/attribute/number-attribute.component.d.ts +2 -2
  27. package/components/form-generic/src/components/form-builder/components/number/control/number-control.component.d.ts +2 -2
  28. package/components/form-generic/src/components/form-builder/components/radio/attribute/radio-attribute.component.d.ts +2 -2
  29. package/components/form-generic/src/components/form-builder/components/radio/control/radio-control.component.d.ts +2 -2
  30. package/components/form-generic/src/components/form-builder/components/select/attribute/select-attribute.component.d.ts +2 -2
  31. package/components/form-generic/src/components/form-builder/components/select/control/select-control.component.d.ts +2 -2
  32. package/components/form-generic/src/components/form-builder/components/table/attribute/table-attribute.component.d.ts +2 -2
  33. package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +2 -2
  34. package/components/form-generic/src/components/form-builder/components/textarea/attribute/textarea-attribute.component.d.ts +2 -2
  35. package/components/form-generic/src/components/form-builder/components/textarea/control/textarea-control.component.d.ts +2 -2
  36. package/components/form-generic/src/components/form-builder/components/textfield/attribute/textfield-attribute.component.d.ts +2 -2
  37. package/components/form-generic/src/components/form-builder/components/textfield/control/textfield-control.component.d.ts +2 -2
  38. package/components/form-generic/src/components/form-builder/components/upload/attribute/upload-attribute.component.d.ts +2 -2
  39. package/components/form-generic/src/components/form-builder/components/upload/control/upload-control.component.d.ts +2 -2
  40. package/components/form-generic/src/components/form-builder/form-builder-layout.d.ts +22 -0
  41. package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +24 -5
  42. package/components/form-generic/src/components/form-render/components/item/components/chip-calendar/chip-calendar.component.d.ts +2 -2
  43. package/components/form-generic/src/components/form-render/components/item/components/chip-string/chip-string.component.d.ts +2 -2
  44. package/components/form-generic/src/components/form-render/components/item/components/datetime/datetime.component.d.ts +2 -2
  45. package/components/form-generic/src/components/form-render/components/item/components/html/html.component.d.ts +2 -2
  46. package/components/form-generic/src/components/form-render/components/item/components/number/number.component.d.ts +2 -2
  47. package/components/form-generic/src/components/form-render/components/item/components/radio/radio.component.d.ts +2 -2
  48. package/components/form-generic/src/components/form-render/components/item/components/select/select.component.d.ts +2 -2
  49. package/components/form-generic/src/components/form-render/components/item/components/table/table.component.d.ts +2 -2
  50. package/components/form-generic/src/components/form-render/components/item/components/textarea/textarea.component.d.ts +2 -2
  51. package/components/form-generic/src/components/form-render/components/item/components/textfield/textfield.component.d.ts +2 -2
  52. package/components/form-generic/src/components/form-render/components/item/components/upload/upload.component.d.ts +2 -2
  53. package/components/form-generic/src/components/form-render/components/variable/variable.component.d.ts +2 -2
  54. package/components/form-generic/src/components/form-render/form-render.component.d.ts +4 -6
  55. package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +2 -2
  56. package/components/form-generic/src/configurations/form.configuration.d.ts +1 -1
  57. package/components/form-generic/src/models/form-generic-component.model.d.ts +2 -2
  58. package/components/form-generic/src/services/form-generic.service.d.ts +1 -3
  59. package/components/import-excel/src/import-excel.model.d.ts +2 -2
  60. package/components/mini-editor/src/mini-editor.component.d.ts +4 -4
  61. package/components/modal/src/modal.component.d.ts +1 -1
  62. package/components/query-builder/src/query-builder.model.d.ts +4 -4
  63. package/components/splitter/src/splitter-state.service.d.ts +1 -1
  64. package/components/tab-router/src/models/tab-router.model.d.ts +2 -1
  65. package/components/tab-router/src/services/tab-router.service.d.ts +0 -1
  66. package/components/table/src/components/command/desktop-command.component.d.ts +8 -7
  67. package/components/table/src/components/command/pipes/command.pipe.d.ts +1 -12
  68. package/components/table/src/components/command/pipes/filter.pipe.d.ts +1 -8
  69. package/components/table/src/components/filter/column-filter/column-filter.component.d.ts +1 -0
  70. package/components/table/src/models/table-column.model.d.ts +3 -2
  71. package/components/table/src/pipes/selection-disabled.pipe.d.ts +1 -1
  72. package/components/table/src/services/config.service.d.ts +4 -5
  73. package/components/view/src/view.component.d.ts +1 -1
  74. package/configurations/src/sd-core.configuration.d.ts +2 -2
  75. package/fesm2022/sdcorejs-angular-components-anchor.mjs +15 -18
  76. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  77. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
  79. package/fesm2022/sdcorejs-angular-components-badge.mjs +0 -1
  80. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  81. package/fesm2022/sdcorejs-angular-components-button.mjs +6 -7
  82. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  83. package/fesm2022/sdcorejs-angular-components-chart.mjs.map +1 -1
  84. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
  85. package/fesm2022/sdcorejs-angular-components-code-editor.mjs +1 -1
  86. package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
  87. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +17 -26
  88. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
  89. package/fesm2022/sdcorejs-angular-components-editor.mjs +7 -2
  90. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  91. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +711 -426
  92. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  93. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +35 -18
  94. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  95. package/fesm2022/sdcorejs-angular-components-inform.mjs +0 -1
  96. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  97. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  99. package/fesm2022/sdcorejs-angular-components-modal.mjs +25 -14
  100. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  101. package/fesm2022/sdcorejs-angular-components-operator.mjs +1 -1
  102. package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
  103. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
  104. package/fesm2022/sdcorejs-angular-components-preview.mjs +33 -29
  105. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +15 -28
  107. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +2 -3
  109. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  110. package/fesm2022/sdcorejs-angular-components-quick-action.mjs.map +1 -1
  111. package/fesm2022/sdcorejs-angular-components-section.mjs +0 -1
  112. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  113. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +3 -3
  114. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  115. package/fesm2022/sdcorejs-angular-components-splitter.mjs +4 -4
  116. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  117. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  118. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +31 -31
  119. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  120. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  121. package/fesm2022/sdcorejs-angular-components-table.mjs +60 -78
  122. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  123. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  124. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +6 -6
  125. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  126. package/fesm2022/sdcorejs-angular-components-view.mjs +3 -9
  127. package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
  128. package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
  129. package/fesm2022/sdcorejs-angular-directives.mjs +2 -7
  130. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  131. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +0 -3
  132. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  133. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  134. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +2 -2
  135. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  136. package/fesm2022/sdcorejs-angular-forms-chip.mjs +2 -2
  137. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  138. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +1 -3
  139. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  140. package/fesm2022/sdcorejs-angular-forms-date.mjs +2 -4
  141. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  142. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +2 -6
  143. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  144. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +3 -3
  145. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  146. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +1 -1
  147. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  148. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  149. package/fesm2022/sdcorejs-angular-forms-label.mjs +0 -1
  150. package/fesm2022/sdcorejs-angular-forms-label.mjs.map +1 -1
  151. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  152. package/fesm2022/sdcorejs-angular-forms-radio.mjs +12 -2
  153. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  154. package/fesm2022/sdcorejs-angular-forms-select.mjs +45 -14
  155. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  156. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  157. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +2 -2
  158. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  159. package/fesm2022/sdcorejs-angular-handlers.mjs +3 -6
  160. package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
  161. package/fesm2022/sdcorejs-angular-i18n.mjs +11 -7
  162. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  163. package/fesm2022/sdcorejs-angular-interceptors.mjs +0 -2
  164. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  165. package/fesm2022/sdcorejs-angular-modules-auth.mjs +14 -38
  166. package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
  167. package/fesm2022/sdcorejs-angular-modules-authom.mjs +14 -14
  168. package/fesm2022/sdcorejs-angular-modules-authom.mjs.map +1 -1
  169. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +22 -11
  170. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
  171. package/fesm2022/sdcorejs-angular-modules-layout.mjs +30 -27
  172. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  173. package/fesm2022/sdcorejs-angular-modules-permission.mjs +5 -12
  174. package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
  175. package/fesm2022/sdcorejs-angular-pipes.mjs +71 -17
  176. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  177. package/fesm2022/sdcorejs-angular-services-api.mjs +0 -2
  178. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  179. package/fesm2022/sdcorejs-angular-services-cache.mjs +5 -11
  180. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  181. package/fesm2022/sdcorejs-angular-services-confirm.mjs +16 -21
  182. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  183. package/fesm2022/sdcorejs-angular-services-docx.mjs +2 -8
  184. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
  185. package/fesm2022/sdcorejs-angular-services-excel.mjs +2 -2
  186. package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
  187. package/fesm2022/sdcorejs-angular-services-license.mjs +5 -12
  188. package/fesm2022/sdcorejs-angular-services-license.mjs.map +1 -1
  189. package/fesm2022/sdcorejs-angular-services-notify.mjs +70 -87
  190. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  191. package/fesm2022/sdcorejs-angular-services-storage.mjs +6 -15
  192. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  193. package/fesm2022/sdcorejs-angular-utilities-data-state.mjs.map +1 -1
  194. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +47 -5
  195. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
  196. package/fesm2022/sdcorejs-angular-utilities-models.mjs +18 -3
  197. package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
  198. package/fesm2022/sdcorejs-angular.mjs.map +1 -1
  199. package/forms/chip/src/chip.component.d.ts +2 -2
  200. package/forms/chip-calendar/src/chip-calendar.component.d.ts +2 -2
  201. package/forms/input-color/src/input-color.component.d.ts +2 -1
  202. package/forms/select/src/select-footer-action.directive.d.ts +5 -1
  203. package/forms/select/src/select.component.d.ts +4 -0
  204. package/modules/auth/guards/auth.guard.d.ts +2 -4
  205. package/modules/auth/guards/portal.guard.d.ts +2 -4
  206. package/modules/auth/services/auth.service.d.ts +3 -4
  207. package/modules/layout/modules/home/guards/home-redirect.guard.d.ts +3 -5
  208. package/modules/permission/src/configurations/permission.configuration.d.ts +3 -3
  209. package/modules/permission/src/guards/permission.guard.d.ts +2 -5
  210. package/package.json +2 -2
  211. package/pipes/index.d.ts +3 -0
  212. package/pipes/src/format-date.pipe.d.ts +8 -0
  213. package/pipes/src/format-datetime.pipe.d.ts +8 -0
  214. package/pipes/src/format-number.pipe.d.ts +1 -3
  215. package/pipes/src/view.pipe.d.ts +7 -0
  216. package/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.d.ts +3 -3
  217. package/services/license/src/license.service.d.ts +2 -3
  218. package/services/notify/src/components/toast/toast.component.d.ts +9 -13
  219. package/services/notify/src/notify.service.d.ts +4 -5
  220. package/services/storage/src/storage.service.d.ts +3 -4
  221. package/utilities/extensions/index.d.ts +1 -0
  222. package/utilities/extensions/src/object.extension.d.ts +8 -0
  223. package/components/document-builder/src/plugins/paste-handler/filters/replacetabswithinprewithspaces.d.ts +0 -24
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, inject, TemplateRef, Directive, booleanAttribute, computed, ChangeDetectionStrategy, Component, model, output, isSignal, effect, Pipe, ChangeDetectorRef, signal, untracked, viewChild, InjectionToken, Inject, Optional, Injectable, EventEmitter, Input, Output, ViewChild, ElementRef, DestroyRef, afterNextRender, Renderer2, NgZone, contentChild, contentChildren } from '@angular/core';
2
+ import { input, inject, TemplateRef, Directive, booleanAttribute, computed, ChangeDetectionStrategy, Component, model, output, isSignal, effect, Pipe, ChangeDetectorRef, signal, untracked, viewChild, InjectionToken, Injectable, EventEmitter, Input, Output, ViewChild, ElementRef, DestroyRef, afterNextRender, Renderer2, NgZone, contentChild, contentChildren } from '@angular/core';
3
3
  import { trigger, state, style, transition, animate } from '@angular/animations';
4
4
  import * as i4$1 from '@angular/material/paginator';
5
5
  import { MatPaginatorIntl, MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
@@ -8,7 +8,7 @@ import { MatSort, MatSortModule } from '@angular/material/sort';
8
8
  import * as i6 from '@angular/material/table';
9
9
  import { MatTable, MatTableModule } from '@angular/material/table';
10
10
  import * as i1$1 from '@sdcorejs/angular/services';
11
- import { SdExcelService, SdNotifyService } from '@sdcorejs/angular/services';
11
+ import { SdStorageService, SdExcelService, SdNotifyService } from '@sdcorejs/angular/services';
12
12
  import { Subject, fromEvent, Subscription, isObservable, firstValueFrom } from 'rxjs';
13
13
  import { debounceTime, startWith, map, switchMap } from 'rxjs/operators';
14
14
  import { DateUtilities, StringUtilities } from '@sdcorejs/angular/utilities';
@@ -32,8 +32,8 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
32
32
  import { SdButton } from '@sdcorejs/angular/components/button';
33
33
  import { SdQuickAction } from '@sdcorejs/angular/components/quick-action';
34
34
  import { SdTooltipDirective, SdScrollDirective, SdDesktopDirective, SdMobileDirective, SdHoverCopyDirective } from '@sdcorejs/angular/directives';
35
- import { SdSafeHtmlPipe, SdFormatNumberPipe } from '@sdcorejs/angular/pipes';
36
- import { BrowserUtilities, Utilities } from '@sdcorejs/utils/fns';
35
+ import { SdSafeHtmlPipe, SdFormatDatePipe, SdFormatDatetimePipe, SdFormatNumberPipe } from '@sdcorejs/angular/pipes';
36
+ import { Utilities, BrowserUtilities } from '@sdcorejs/utils/fns';
37
37
  import { DateUtilities as DateUtilities$1, ArrayUtilities, NumberUtilities } from '@sdcorejs/angular/utilities/extensions';
38
38
  import { SdBadge } from '@sdcorejs/angular/components/badge';
39
39
  import { SdOperator } from '@sdcorejs/angular/components/operator';
@@ -51,6 +51,7 @@ import * as i4 from '@angular/material/button';
51
51
  import { MatButtonModule } from '@angular/material/button';
52
52
  import * as i2$1 from '@angular/material/tooltip';
53
53
  import { MatTooltipModule } from '@angular/material/tooltip';
54
+ import { DefaultMaterialIconFontSet } from '@sdcorejs/angular/utilities/models';
54
55
  import * as i5$1 from '@angular/material/chips';
55
56
  import { MatChipsModule } from '@angular/material/chips';
56
57
 
@@ -398,7 +399,6 @@ const SdConvertToPagingReq = (filterRequest, args) => {
398
399
  return req;
399
400
  };
400
401
 
401
- /* eslint-disable @typescript-eslint/no-explicit-any */
402
402
  class ColumnTitleComponent {
403
403
  column = input.required();
404
404
  titleDef = input(undefined);
@@ -417,8 +417,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
417
417
  args: [{ selector: 'column-title', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgTemplateOutlet], template: "@let _column = column();\n@let _templateRef = templateRef();\n\n@if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef\"></ng-container>\n} @else {\n {{ _column.title }}\n}\n" }]
418
418
  }] });
419
419
 
420
- /* eslint-disable @typescript-eslint/no-explicit-any */
421
420
  class ColumnFilterComponent {
421
+ #lastOnChangeValueHash;
422
422
  // ==========================================
423
423
  // 1. SIGNAL INPUTS
424
424
  // ==========================================
@@ -503,14 +503,34 @@ class ColumnFilterComponent {
503
503
  if (col.type === 'number' && col.filter?.type === 'split-number') {
504
504
  filter[col.field] = filter[col.field] || { from: null, to: null };
505
505
  }
506
+ this.#lastOnChangeValueHash = this.#filterValueHash(filter[col.field]);
506
507
  });
507
508
  }
508
509
  // ==========================================
509
510
  // 4. HANDLERS
510
511
  // ==========================================
511
- onFilterChange = () => this.filterChange.emit();
512
+ onFilterChange = () => {
513
+ this.#emitFilterOnChange();
514
+ this.filterChange.emit();
515
+ };
512
516
  // Blur input: commit giá trị KHÔNG trigger reload.
513
- onFilterCommit = () => this.filterCommit.emit();
517
+ onFilterCommit = () => {
518
+ this.#emitFilterOnChange();
519
+ this.filterCommit.emit();
520
+ };
521
+ #emitFilterOnChange = () => {
522
+ const col = this.column();
523
+ const filter = this.columnFilter();
524
+ if (!col?.filter?.onChange || !filter)
525
+ return;
526
+ const value = filter[col.field];
527
+ const hash = this.#filterValueHash(value);
528
+ if (hash === this.#lastOnChangeValueHash)
529
+ return;
530
+ this.#lastOnChangeValueHash = hash;
531
+ col.filter.onChange(value, col, filter);
532
+ };
533
+ #filterValueHash = (value) => Utilities.hash({ value });
514
534
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ColumnFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
515
535
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ColumnFilterComponent, isStandalone: true, selector: "column-filter", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, columnFilter: { classPropertyName: "columnFilter", publicName: "columnFilter", isSignal: true, isRequired: false, transformFunction: null }, cacheValues: { classPropertyName: "cacheValues", publicName: "cacheValues", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, operator: { classPropertyName: "operator", publicName: "operator", isSignal: true, isRequired: false, transformFunction: null }, isMobile: { classPropertyName: "isMobile", publicName: "isMobile", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operator: "operatorChange", filterChange: "filterChange", filterCommit: "filterCommit" }, ngImport: i0, template: "@let _column = column();\n@let _columnFilter = columnFilter();\n@let _autoId = autoId();\n@let _templateRef = templateRef();\n@let _operators = operators();\n@let _items = items();\n@let _label = label();\n@let _context = { columnFilter: _columnFilter, autoId: _autoId };\n\n<div class=\"d-flex c-inline-column align-items-center\" style=\"width: 100%; max-width: 100%\">\n @if (\n _column.type === 'string' ||\n _column.type === 'number' ||\n _column.type === 'boolean' ||\n _column.type === 'values' ||\n _column.type === 'lazy-values' ||\n _column.type === 'date' ||\n _column.type === 'datetime' ||\n _column.type === 'time'\n ) {\n <!-- Operator filter -->\n @if (_operators.length) {\n <sd-operator class=\"mr-4\" [(model)]=\"operator\" [operators]=\"operatorValues()\" />\n }\n\n <!-- N\u1EBFu filter nh\u1EADn v\u00E0o template -->\n @if (_templateRef) {\n <ng-container *ngTemplateOutlet=\"_templateRef; context: _context\"></ng-container>\n }\n <!-- M\u1EB7c \u0111\u1ECBnh theo type v\u00E0 gi\u00E1 tr\u1ECB values defined c\u1EE7a column -->\n @else {\n @if (_column.type === 'string') {\n <sd-input\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n type=\"text\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input>\n } @else if (_column.type === 'number') {\n @if (!_column.filter?.type) {\n <sd-input-number\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (keyupEnter)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-input-number>\n } @else if (_column.filter?.type === 'split-number') {\n <ng-container *ngTemplateOutlet=\"splitNumberTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n } @else if (_column.type === 'boolean') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"[\n { value: '1', display: _column.option?.displayOnTrue || 'True' },\n { value: '0', display: _column.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n <ng-template sdItemDef let-item=\"item\">\n @if (item.value === '1') {\n <sd-badge color=\"success\" [title]=\"_column.option?.displayOnTrue || 'True'\"> </sd-badge>\n } @else {\n <sd-badge color=\"error\" [title]=\"_column.option?.displayOnFalse || 'False'\"> </sd-badge>\n }\n </ng-template>\n </sd-select>\n } @else if (_column.type === 'values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'lazy-values') {\n <sd-select\n minWidthPanel=\"200px\"\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n [style.width]=\"'100%'\"\n size=\"sm\"\n [label]=\"_label\"\n [items]=\"_items\"\n [valueField]=\"_column.option.valueField\"\n [displayField]=\"_column.option.displayField\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n [multiple]=\"_column.option.selection === 'MULTIPLE'\"\n hideInlineError>\n </sd-select>\n } @else if (_column.type === 'date' || _column.type === 'datetime' || _column.type === 'time') {\n @if (!_column.filter?.type || _column.filter?.type === 'daterange') {\n <sd-date-range\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date-range>\n } @else if (_column.filter?.type === 'date') {\n <sd-date\n [autoId]=\"_autoId\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[_column.field]\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"_column.filter?.disabled\"\n hideInlineError>\n </sd-date>\n } @else if (_column.filter?.type === 'split-date') {\n <ng-container *ngTemplateOutlet=\"splitDateTpl; context: { field: _column.field, disabled: _column.filter?.disabled }\">\n </ng-container>\n }\n }\n }\n } @else {\n <sd-input [autoId]=\"_autoId\" style=\"flex: 1 1 0%; min-width: 0\" type=\"text\" size=\"sm\" disabled></sd-input>\n }\n</div>\n\n<!-- ================================================ -->\n<!-- Split from/to templates (\u0111\u01B0a xu\u1ED1ng cu\u1ED1i file) -->\n<!-- ================================================ -->\n<ng-template #splitNumberTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-input-number\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n <div class=\"mx-4\">-</div>\n <sd-input-number\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n (sdBlur)=\"onFilterCommit()\"\n (cleared)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-input-number>\n </div>\n</ng-template>\n\n<ng-template #splitDateTpl let-field=\"field\" let-disabled=\"disabled\">\n <div class=\"d-flex align-items-center\" style=\"flex: 1 1 0%; min-width: 0\">\n <sd-date\n [autoId]=\"_autoId + '-from'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [label]=\"_label\"\n [(model)]=\"_columnFilter[field].from\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n <div class=\"mx-4\">-</div>\n <sd-date\n [autoId]=\"_autoId + '-to'\"\n style=\"flex: 1 1 0%; min-width: 0\"\n type=\"date\"\n size=\"sm\"\n [(model)]=\"_columnFilter[field].to\"\n (sdChange)=\"onFilterChange()\"\n [disabled]=\"disabled\"\n hideInlineError>\n </sd-date>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .c-inline-column .mat-mdc-text-field-wrapper{background-color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SdOperator, selector: "sd-operator", inputs: ["model", "operators", "disabled", "autoId"], outputs: ["modelChange"] }, { kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdInputNumber, selector: "sd-input-number", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "type", "precision", "format", "min", "max", "validator", "inlineError", "hyperlink", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "component", type: SdSelect, selector: "sd-select", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "valueField", "displayField", "disabledField", "cacheChecksum", "limit", "hyperlink", "minWidthPanel", "hideInlineError", "required", "disabled", "viewed", "multiple", "clearable", "validator", "inlineError", "appearance", "floatLabel", "items", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdDateRange, selector: "sd-date-range", inputs: ["autoId", "name", "size", "form", "label", "helperText", "hideInlineError", "required", "disabled", "viewed", "clearable", "appearance", "floatLabel", "min", "max", "model"], outputs: ["modelChange", "sdChange"] }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
516
536
  }
@@ -766,8 +786,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
766
786
  args: [{ name: 'sdTree' }]
767
787
  }] });
768
788
 
769
- /* eslint-disable @typescript-eslint/no-explicit-any */
770
- // eslint-disable-next-line @angular-eslint/component-class-suffix
771
789
  class ExternalFilterComponent {
772
790
  // ==========================================
773
791
  // 1. SIGNAL INPUTS
@@ -915,7 +933,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
915
933
  ], template: "@let _filter = filter();\n@let _autoId = autoId();\n@let _filterItems = filterItems();\n@let _externalFilter = externalFilter();\n@let _inlineExternal = inlineExternal();\n@let _filtered = filtered();\n@let _col = col();\n\n@if (!_filter?.disabled) {\n @if (!isMobileOrTablet && _filterItems.length) {\n <sd-section\n [hideHeader]=\"_filter?.hideExternalFilterToolbar\"\n icon=\"filter_alt\"\n iconColor=\"secondary\"\n [title]=\"'core.component.table.filter' | translate\"\n [collapsible]=\"_filter?.collapsible ?? _filter?.collapsable ?? true\">\n <div class=\"d-flex mr-4\" sdHeaderRight>\n <sd-button\n [autoId]=\"_autoId + 'clear'\"\n [disabled]=\"!_filtered\"\n type=\"link\"\n prefixIcon=\"cleaning_services\"\n [tooltip]=\"'core.component.table.clear-selection' | translate\"\n (click)=\"$event.stopPropagation(); clearFilter($event)\"></sd-button>\n <sd-button\n [autoId]=\"_autoId + 'setting'\"\n type=\"link\"\n prefixIcon=\"settings\"\n [tooltip]=\"'core.component.table.customize' | translate\"\n [matMenuTriggerFor]=\"menu\"\n (click)=\"$event.stopPropagation()\"></sd-button>\n <mat-menu #menu=\"matMenu\" class=\"sd-custom-panel-filter-configuration\" [attr.data-autoid]=\"_autoId + 'setting-menu'\">\n @for (externalFilter of _filterItems; track externalFilter.field) {\n <button\n [attr.data-autoid]=\"_autoId + 'setting-' + externalFilter.field\"\n mat-menu-item\n (click)=\"onCheckboxChange($event, externalFilter)\"\n [disabled]=\"externalFilter.required\">\n <sd-checkbox\n [autoId]=\"_autoId + 'setting-' + externalFilter.field + '-checkbox'\"\n [label]=\"externalFilter.title\"\n [model]=\"_inlineExternal[externalFilter.field]\"\n [disabled]=\"externalFilter.required\" />\n </button>\n }\n </mat-menu>\n </div>\n <div class=\"row mx-0\" style=\"row-gap: 16px\">\n @for (item of _filterItems; track item.field) {\n @if (_inlineExternal[item.field]) {\n <div class=\"col-md-3 col-sm-6 px-8\" [class.col-lg-2]=\"_col === 2\" [class.col-lg-3]=\"_col === 3\">\n @if (item.type === 'string') {\n <sd-input\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n type=\"text\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input>\n } @else if (item.type === 'number') {\n <sd-input-number\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (keyupEnter)=\"onKeyupEnter()\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-input-number>\n } @else if (item.type === 'boolean') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"[\n { value: true, display: item.option?.displayOnTrue || 'True' },\n { value: false, display: item.option?.displayOnFalse || 'False' },\n ]\"\n valueField=\"value\"\n displayField=\"display\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.type === 'date') {\n <sd-date\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-date>\n } @else if (item.type === 'datetime') {\n <sd-datetime\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n hideInlineError>\n </sd-datetime>\n } @else if (item.type === 'daterange') {\n <sd-date-range\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n [form]=\"form\"\n [required]=\"item.required\"\n [min]=\"item.minDate\"\n [max]=\"item.maxDate\"\n appearance=\"outline\"\n hideInlineError>\n </sd-date-range>\n } @else if (item.type === 'values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'AUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else if (item.option.selection === 'MULTIPLEAUTOCOMPLETE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items | filterValues | async\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'lazy-values') {\n @if (item.option.selection === 'MULTIPLE') {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n multiple\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n } @else {\n <sd-select\n [autoId]=\"_autoId + item.field\"\n [label]=\"item.title\"\n [items]=\"item.option.items\"\n [valueField]=\"item.option.valueField\"\n [displayField]=\"item.option.displayField\"\n [(model)]=\"_externalFilter[item.field]\"\n (sdChange)=\"onFilter(item)\"\n appearance=\"outline\"\n [form]=\"form\"\n [required]=\"item.required\"\n hideInlineError>\n </sd-select>\n }\n } @else if (item.type === 'custom' && item.filterDef) {\n <ng-container\n *ngTemplateOutlet=\"\n item.filterDef;\n context: { form: form, externalFilter: _externalFilter, autoId: _autoId + item.field }\n \">\n </ng-container>\n }\n </div>\n }\n }\n </div>\n @if (_filter?.manualFilter) {\n <div class=\"d-flex justify-content-end mt-16 px-8\">\n <sd-button\n [autoId]=\"_autoId + 'submit'\"\n [disabled]=\"form.invalid\"\n type=\"fill\"\n color=\"primary\"\n [title]=\"'core.component.table.search' | translate\"\n prefixIcon=\"filter_alt\"\n (click)=\"onSubmit()\">\n </sd-button>\n </div>\n }\n </sd-section>\n }\n}\n", styles: [":host{display:block;padding-left:0;padding-right:0}::ng-deep .sd-custom-panel-filter-configuration{width:240px;max-height:550px;overflow-y:auto}\n"] }]
916
934
  }], ctorParameters: () => [] });
917
935
 
918
- /* eslint-disable @typescript-eslint/no-explicit-any */
919
936
  /**
920
937
  * Mobile-filter — side-drawer chiếm ~90% width thiết bị. Dùng cho table khi
921
938
  * render trên màn hình điện thoại (inline filter bị ẩn).
@@ -1133,8 +1150,6 @@ const DEFAULT_TABLE_CONFIG = {
1133
1150
  const SD_TABLE_CONFIGURATION = new InjectionToken('sd-table.configuration');
1134
1151
 
1135
1152
  class ConfigService {
1136
- storageService;
1137
- tableConfiguration;
1138
1153
  #COLUMNS = {
1139
1154
  SUBINFORMATION: 'sdSubInformationAction',
1140
1155
  COMMAND: 'sdCommand',
@@ -1148,10 +1163,8 @@ class ConfigService {
1148
1163
  #storage;
1149
1164
  #widthChange = new Subject();
1150
1165
  widthChange$ = this.#widthChange.asObservable();
1151
- constructor(storageService, tableConfiguration) {
1152
- this.storageService = storageService;
1153
- this.tableConfiguration = tableConfiguration;
1154
- }
1166
+ storageService = inject(SdStorageService);
1167
+ tableConfiguration = inject(SD_TABLE_CONFIGURATION, { optional: true });
1155
1168
  #loadConfiguredTable = (option) => {
1156
1169
  // Nếu không có key thì không lấy được setting
1157
1170
  if (!option?.key) {
@@ -1340,20 +1353,13 @@ class ConfigService {
1340
1353
  columns,
1341
1354
  };
1342
1355
  };
1343
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ConfigService, deps: [{ token: i1$1.SdStorageService }, { token: SD_TABLE_CONFIGURATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1356
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1344
1357
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ConfigService });
1345
1358
  }
1346
1359
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ConfigService, decorators: [{
1347
1360
  type: Injectable
1348
- }], ctorParameters: () => [{ type: i1$1.SdStorageService }, { type: undefined, decorators: [{
1349
- type: Inject,
1350
- args: [SD_TABLE_CONFIGURATION]
1351
- }, {
1352
- type: Optional
1353
- }] }] });
1361
+ }] });
1354
1362
 
1355
- /* eslint-disable @typescript-eslint/no-explicit-any */
1356
- // eslint-disable-next-line @angular-eslint/component-class-suffix
1357
1363
  class ConfigComponent {
1358
1364
  // ==========================================
1359
1365
  // 1. SIGNAL INPUTS / OUTPUTS
@@ -1580,18 +1586,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
1580
1586
  }], ctorParameters: () => [] });
1581
1587
 
1582
1588
  /**
1583
- * Pipe gộp resolve metadata của 1 command theo row hiện tại return 1 object
1584
- * chứa `disabled`, `title`, `icon`, và `htmlTemplate` (khi command là child có
1585
- * htmlTemplate). Một lần gọi cho cả 4 truy vấn, template dùng `@let` để alias.
1586
- *
1587
- * Trước đây tách thành 3 pipe `commandDisable` / `commandTitle` / `commandIcon`.
1588
- *
1589
- * @example
1590
- * @let meta = item | command:cmd;
1591
- * <button [disabled]="meta.disabled" [matTooltip]="meta.title">
1592
- * <mat-icon>{{ meta.icon }}</mat-icon>
1593
- * <div [innerHTML]="meta.htmlTemplate"></div>
1594
- * </button>
1589
+ * Resolves command metadata for the current row once, then lets the template reuse it with `@let`.
1595
1590
  */
1596
1591
  class CommandPipe {
1597
1592
  transform(item, command) {
@@ -1618,8 +1613,7 @@ class CommandPipe {
1618
1613
  return '';
1619
1614
  return typeof command.icon === 'string' ? command.icon : command.icon(item.data);
1620
1615
  };
1621
- // Chỉ child command (SdTableCommandNormal) mới htmlTemplate.
1622
- // Parent (SdTableCommandChildren) không khai báo — trả về undefined.
1616
+ // Only child commands can provide htmlTemplate.
1623
1617
  #htmlTemplate = (item, command) => {
1624
1618
  const tpl = command?.htmlTemplate;
1625
1619
  return typeof tpl === 'function' ? tpl(item.data) : undefined;
@@ -1629,18 +1623,11 @@ class CommandPipe {
1629
1623
  }
1630
1624
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: CommandPipe, decorators: [{
1631
1625
  type: Pipe,
1632
- args: [{ name: 'command' }]
1626
+ args: [{ name: 'command', standalone: true }]
1633
1627
  }] });
1634
1628
 
1635
1629
  /**
1636
- * Lọc danh sách commands theo `hidden` (sync / async) + pre-resolve `icon`, `title`, `key`
1637
- * cho từng row. Output dùng trực tiếp trong template không cần thêm pipe phụ.
1638
- *
1639
- * Đã rename từ `commandFilter` → `filter` sau khi gom toàn bộ pipe command vào
1640
- * `components/command/pipes/`.
1641
- *
1642
- * @example
1643
- * @let filteredCommands = item | filter:commands | async;
1630
+ * Filters visible commands and pre-resolves icon, title, and stable key for the current row.
1644
1631
  */
1645
1632
  class CommandFilterPipe {
1646
1633
  async transform(item, commands) {
@@ -1707,7 +1694,7 @@ class CommandFilterPipe {
1707
1694
  return '';
1708
1695
  return typeof command.title === 'string' ? command.title : command.title(item.data);
1709
1696
  };
1710
- // Key dùng để gán cho autoId cần stable theo (icon, title).
1697
+ // Stable autoId key generated from resolved icon and title.
1711
1698
  #key = (item, command) => {
1712
1699
  const icon = this.#icon(item, command);
1713
1700
  const title = this.#title(item, command);
@@ -1718,46 +1705,36 @@ class CommandFilterPipe {
1718
1705
  }
1719
1706
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: CommandFilterPipe, decorators: [{
1720
1707
  type: Pipe,
1721
- args: [{ name: 'filter' }]
1708
+ args: [{ name: 'filter', standalone: true }]
1722
1709
  }] });
1723
1710
 
1724
- // eslint-disable-next-line @angular-eslint/component-class-suffix
1725
1711
  class DesktopCommand {
1726
- // ==========================================
1727
- // 1. SIGNAL INPUTS
1728
- // ==========================================
1712
+ defaultIconFontSet = DefaultMaterialIconFontSet;
1729
1713
  autoIdInput = input(undefined, { alias: 'autoId' });
1730
1714
  item = input.required();
1731
1715
  itemIndex = input.required();
1732
1716
  commands = input([]);
1733
- // ==========================================
1734
- // 2. COMPUTED
1735
- // ==========================================
1736
- // Key định danh row dùng để build autoId: ưu tiên id → code → value → fallback itemIndex.
1717
+ // Row key for autoId: prefer id, then code, then value, then itemIndex.
1737
1718
  itemKey = computed(() => {
1738
1719
  const data = this.item()?.data;
1739
1720
  return data?.['id']?.toString() || data?.['code']?.toString() || data?.['value']?.toString() || this.itemIndex().toString();
1740
1721
  });
1741
- // autoId của host: `<base>-command-<itemKey>` đã unique theo row.
1742
- // Template ghép tiếp `-<commandKey>` (và `-<childKey>` nếu child) cho mỗi button.
1722
+ // Host autoId: `<base>-command-<itemKey>`. Template appends command and child keys.
1743
1723
  autoId = computed(() => {
1744
1724
  const base = this.autoIdInput();
1745
1725
  return base ? `${base}-command-${this.itemKey()}` : '';
1746
1726
  });
1747
- // Commands signal (mặc định mảng rỗng).
1748
1727
  _commands = computed(() => this.commands() || []);
1749
1728
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: DesktopCommand, deps: [], target: i0.ɵɵFactoryTarget.Component });
1750
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: DesktopCommand, isStandalone: true, selector: "desktop-command", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, itemIndex: { classPropertyName: "itemIndex", publicName: "itemIndex", isSignal: true, isRequired: true, transformFunction: null }, commands: { classPropertyName: "commands", publicName: "commands", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-autoid": "autoId()" } }, ngImport: i0, template: "@let _autoId = autoId();\n@let _item = item();\n@let filteredCommands = _item | filter: _commands() | async;\n\n@if (filteredCommands?.length) {\n @for (command of filteredCommands; track command.key) {\n @let _meta = _item | command: command;\n @if (command.type === 'normal') {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n (click)=\"command.click(_item.data)\"\n [matTooltip]=\"_meta.title\"\n aria-hidden=\"true\"\n [disabled]=\"_meta.disabled\"\n mat-icon-button>\n <mat-icon class=\"c-icon\" [color]=\"command.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _meta.icon }}\n </mat-icon>\n </button>\n } @else {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n [matMenuTriggerFor]=\"menu\"\n aria-hidden=\"true\"\n mat-icon-button>\n @if (_meta.icon) {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet!\">{{ _meta.icon }}</mat-icon>\n } @else {\n <mat-icon class=\"c-icon\">more_vert</mat-icon>\n }\n </button>\n <mat-menu #menu=\"matMenu\" [attr.data-autoid]=\"_autoId + '-' + command.key + '-menu'\">\n <span>\n @for (childCommand of command.children; track childCommand.key) {\n @let _childMeta = _item | command: childCommand;\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key + '-' + childCommand.key\"\n mat-menu-item\n (click)=\"childCommand.click(_item.data)\"\n [disabled]=\"_childMeta.disabled\">\n @if (_childMeta.htmlTemplate) {\n <div [innerHTML]=\"_childMeta.htmlTemplate\"></div>\n } @else {\n <div>\n <mat-icon [color]=\"childCommand.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _childMeta.icon }}\n </mat-icon>\n <span> {{ _childMeta.title }}</span>\n </div>\n }\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:flex;align-items:center}button[mat-icon-button]{width:24px;height:24px;line-height:24px;padding:0}mat-icon.c-icon{color:var(--sd-black400)!important;width:16px;height:16px;font-size:16px;line-height:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: CommandPipe, name: "command" }, { kind: "pipe", type: CommandFilterPipe, name: "filter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1729
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: DesktopCommand, isStandalone: true, selector: "desktop-command", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, itemIndex: { classPropertyName: "itemIndex", publicName: "itemIndex", isSignal: true, isRequired: true, transformFunction: null }, commands: { classPropertyName: "commands", publicName: "commands", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-autoid": "autoId()" } }, ngImport: i0, template: "@let _autoId = autoId();\n@let _item = item();\n@let filteredCommands = _item | filter: _commands() | async;\n\n@if (filteredCommands?.length) {\n @for (command of filteredCommands; track command.key) {\n @let _meta = _item | command: command;\n @if (command.type === 'normal') {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n (click)=\"command.click(_item.data)\"\n [matTooltip]=\"_meta.title\"\n aria-hidden=\"true\"\n [disabled]=\"_meta.disabled\"\n mat-icon-button>\n <mat-icon class=\"c-icon\" [color]=\"command.color || 'secondary'\" [fontSet]=\"command.fontSet || defaultIconFontSet\">\n {{ _meta.icon }}\n </mat-icon>\n </button>\n } @else {\n <button [attr.data-autoid]=\"_autoId + '-' + command.key\" [matMenuTriggerFor]=\"menu\" aria-hidden=\"true\" mat-icon-button>\n @if (_meta.icon) {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet || defaultIconFontSet\">{{ _meta.icon }}</mat-icon>\n } @else {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet || defaultIconFontSet\">more_vert</mat-icon>\n }\n </button>\n <mat-menu #menu=\"matMenu\" [attr.data-autoid]=\"_autoId + '-' + command.key + '-menu'\">\n <span>\n @for (childCommand of command.children; track childCommand.key) {\n @let _childMeta = _item | command: childCommand;\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key + '-' + childCommand.key\"\n mat-menu-item\n (click)=\"childCommand.click(_item.data)\"\n [disabled]=\"_childMeta.disabled\">\n @if (_childMeta.htmlTemplate) {\n <div [innerHTML]=\"_childMeta.htmlTemplate\"></div>\n } @else {\n <span class=\"sd-command-menu-item__content\">\n <mat-icon\n class=\"sd-command-menu-item__icon\"\n [color]=\"childCommand.color || 'secondary'\"\n [fontSet]=\"childCommand.fontSet || defaultIconFontSet\">\n {{ _childMeta.icon }}\n </mat-icon>\n <span class=\"sd-command-menu-item__title\">{{ _childMeta.title }}</span>\n </span>\n }\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:flex;align-items:center}button[mat-icon-button]{width:24px;height:24px;line-height:24px;padding:0}mat-icon.c-icon{color:var(--sd-black400)!important;width:16px;height:16px;font-size:16px;line-height:16px}.sd-command-menu-item__content{display:inline-flex;align-items:center;gap:8px;min-width:0;width:100%}.sd-command-menu-item__icon{color:var(--sd-black400)!important;width:24px;height:24px;font-size:18px;line-height:24px!important;margin-right:0!important;flex:0 0 24px}.sd-command-menu-item__title{min-width:0;line-height:20px;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: CommandPipe, name: "command" }, { kind: "pipe", type: CommandFilterPipe, name: "filter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1751
1730
  }
1752
1731
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: DesktopCommand, decorators: [{
1753
1732
  type: Component,
1754
1733
  args: [{ selector: 'desktop-command', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, host: {
1755
1734
  '[attr.data-autoid]': 'autoId()',
1756
- }, imports: [CommonModule, MatTooltipModule, MatMenuModule, MatButtonModule, MatIconModule, CommandPipe, CommandFilterPipe], template: "@let _autoId = autoId();\n@let _item = item();\n@let filteredCommands = _item | filter: _commands() | async;\n\n@if (filteredCommands?.length) {\n @for (command of filteredCommands; track command.key) {\n @let _meta = _item | command: command;\n @if (command.type === 'normal') {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n (click)=\"command.click(_item.data)\"\n [matTooltip]=\"_meta.title\"\n aria-hidden=\"true\"\n [disabled]=\"_meta.disabled\"\n mat-icon-button>\n <mat-icon class=\"c-icon\" [color]=\"command.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _meta.icon }}\n </mat-icon>\n </button>\n } @else {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n [matMenuTriggerFor]=\"menu\"\n aria-hidden=\"true\"\n mat-icon-button>\n @if (_meta.icon) {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet!\">{{ _meta.icon }}</mat-icon>\n } @else {\n <mat-icon class=\"c-icon\">more_vert</mat-icon>\n }\n </button>\n <mat-menu #menu=\"matMenu\" [attr.data-autoid]=\"_autoId + '-' + command.key + '-menu'\">\n <span>\n @for (childCommand of command.children; track childCommand.key) {\n @let _childMeta = _item | command: childCommand;\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key + '-' + childCommand.key\"\n mat-menu-item\n (click)=\"childCommand.click(_item.data)\"\n [disabled]=\"_childMeta.disabled\">\n @if (_childMeta.htmlTemplate) {\n <div [innerHTML]=\"_childMeta.htmlTemplate\"></div>\n } @else {\n <div>\n <mat-icon [color]=\"childCommand.color || 'secondary'\" [fontSet]=\"command.fontSet!\">\n {{ _childMeta.icon }}\n </mat-icon>\n <span> {{ _childMeta.title }}</span>\n </div>\n }\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:flex;align-items:center}button[mat-icon-button]{width:24px;height:24px;line-height:24px;padding:0}mat-icon.c-icon{color:var(--sd-black400)!important;width:16px;height:16px;font-size:16px;line-height:16px}\n"] }]
1735
+ }, imports: [CommonModule, MatTooltipModule, MatMenuModule, MatButtonModule, MatIconModule, CommandPipe, CommandFilterPipe], template: "@let _autoId = autoId();\n@let _item = item();\n@let filteredCommands = _item | filter: _commands() | async;\n\n@if (filteredCommands?.length) {\n @for (command of filteredCommands; track command.key) {\n @let _meta = _item | command: command;\n @if (command.type === 'normal') {\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key\"\n (click)=\"command.click(_item.data)\"\n [matTooltip]=\"_meta.title\"\n aria-hidden=\"true\"\n [disabled]=\"_meta.disabled\"\n mat-icon-button>\n <mat-icon class=\"c-icon\" [color]=\"command.color || 'secondary'\" [fontSet]=\"command.fontSet || defaultIconFontSet\">\n {{ _meta.icon }}\n </mat-icon>\n </button>\n } @else {\n <button [attr.data-autoid]=\"_autoId + '-' + command.key\" [matMenuTriggerFor]=\"menu\" aria-hidden=\"true\" mat-icon-button>\n @if (_meta.icon) {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet || defaultIconFontSet\">{{ _meta.icon }}</mat-icon>\n } @else {\n <mat-icon class=\"c-icon\" [fontSet]=\"command.fontSet || defaultIconFontSet\">more_vert</mat-icon>\n }\n </button>\n <mat-menu #menu=\"matMenu\" [attr.data-autoid]=\"_autoId + '-' + command.key + '-menu'\">\n <span>\n @for (childCommand of command.children; track childCommand.key) {\n @let _childMeta = _item | command: childCommand;\n <button\n [attr.data-autoid]=\"_autoId + '-' + command.key + '-' + childCommand.key\"\n mat-menu-item\n (click)=\"childCommand.click(_item.data)\"\n [disabled]=\"_childMeta.disabled\">\n @if (_childMeta.htmlTemplate) {\n <div [innerHTML]=\"_childMeta.htmlTemplate\"></div>\n } @else {\n <span class=\"sd-command-menu-item__content\">\n <mat-icon\n class=\"sd-command-menu-item__icon\"\n [color]=\"childCommand.color || 'secondary'\"\n [fontSet]=\"childCommand.fontSet || defaultIconFontSet\">\n {{ _childMeta.icon }}\n </mat-icon>\n <span class=\"sd-command-menu-item__title\">{{ _childMeta.title }}</span>\n </span>\n }\n </button>\n }\n </span>\n </mat-menu>\n }\n }\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:flex;align-items:center}button[mat-icon-button]{width:24px;height:24px;line-height:24px;padding:0}mat-icon.c-icon{color:var(--sd-black400)!important;width:16px;height:16px;font-size:16px;line-height:16px}.sd-command-menu-item__content{display:inline-flex;align-items:center;gap:8px;min-width:0;width:100%}.sd-command-menu-item__icon{color:var(--sd-black400)!important;width:24px;height:24px;font-size:18px;line-height:24px!important;margin-right:0!important;flex:0 0 24px}.sd-command-menu-item__title{min-width:0;line-height:20px;white-space:nowrap}\n"] }]
1757
1736
  }] });
1758
1737
 
1759
- /* eslint-disable @angular-eslint/no-input-rename */
1760
- // eslint-disable-next-line @angular-eslint/component-class-suffix
1761
1738
  class SdPopupExport {
1762
1739
  ref;
1763
1740
  loadingService;
@@ -1936,7 +1913,7 @@ class SdPopupExport {
1936
1913
  generateAndUploadTemplate = async (fileName) => {
1937
1914
  const sheets = [];
1938
1915
  if (Array.isArray(this.exportOption?.sheets)) {
1939
- for (const sheet of this.exportOption?.sheets) {
1916
+ for (const sheet of this.exportOption.sheets) {
1940
1917
  if (sheet.name && sheet.items && sheet.headers) {
1941
1918
  if (Array.isArray(sheet.items)) {
1942
1919
  sheets.push({
@@ -2394,19 +2371,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2394
2371
  class SdSelectionDisabledPipe {
2395
2372
  transform = (selectedItems, rowData, selection) => {
2396
2373
  const { disabled, actions } = selection;
2374
+ if (rowData.meta.selector.isSelected) {
2375
+ rowData.meta.selector.selectable = true;
2376
+ return false;
2377
+ }
2397
2378
  if (!actions?.length) {
2398
2379
  if (!disabled) {
2399
2380
  rowData.meta.selector.selectable = true;
2400
2381
  return false;
2401
2382
  }
2402
- rowData.meta.selector.selectable = !disabled(rowData, selectedItems);
2383
+ rowData.meta.selector.selectable = !disabled(rowData.data, selectedItems.map(e => e.data));
2403
2384
  return !rowData.meta.selector.selectable;
2404
2385
  }
2405
2386
  // Kiểm tra có bị disabled theo function không
2406
2387
  // Dữ liệu chưa được check thì kiểm tra hàm disable nếu có
2407
- if (disabled && !rowData.meta.selector.isSelected) {
2388
+ if (disabled) {
2408
2389
  // Nếu disabled và dữ liệu chưa được check
2409
- if (disabled(rowData, selectedItems)) {
2390
+ if (disabled(rowData.data, selectedItems.map(e => e.data))) {
2410
2391
  return true;
2411
2392
  }
2412
2393
  }
@@ -2471,7 +2452,7 @@ class SdSelectionVisibleSelectAllPipe {
2471
2452
  await new Promise(resolve => setTimeout(resolve, 500));
2472
2453
  const first = items.find(t => t.meta.selector?.actions?.length);
2473
2454
  if (first) {
2474
- for (const action of first.meta.selector?.actions) {
2455
+ for (const action of first.meta.selector?.actions ?? []) {
2475
2456
  if (items.filter(t => t.meta.selector?.actions?.length).every(e => e.meta.selector?.actions?.includes(action))) {
2476
2457
  return true;
2477
2458
  }
@@ -2497,7 +2478,7 @@ class SdSelectionVisiblePipe {
2497
2478
  rowData.meta.selector.selectable = true;
2498
2479
  return rowData.meta.selector.selectable;
2499
2480
  }
2500
- for (const action of selection?.actions) {
2481
+ for (const action of selection.actions) {
2501
2482
  if ('children' in action) {
2502
2483
  let flag = false;
2503
2484
  let hasGroup = false;
@@ -2826,7 +2807,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2826
2807
  }] });
2827
2808
 
2828
2809
  class TableFormatService {
2829
- // Inject các pipe/service dùng để format dữ liệu
2810
+ // Keep table display formatting aligned with the public template pipes.
2811
+ #formatDatePipe = inject(SdFormatDatePipe);
2812
+ #formatDatetimePipe = inject(SdFormatDatetimePipe);
2830
2813
  #formatNumberPipe = inject(SdFormatNumberPipe);
2831
2814
  // ==========================================
2832
2815
  // PUBLIC METHODS
@@ -2987,15 +2970,15 @@ class TableFormatService {
2987
2970
  // PRIVATE HELPERS
2988
2971
  // ==========================================
2989
2972
  #formatDateDisplay(value, type) {
2990
- const date = DateUtilities$1.toFormat(value, 'dd/MM/yyyy');
2991
- const time = DateUtilities$1.toFormat(value, 'HH:mm:ss');
2973
+ const date = this.#formatDatePipe.transform(value);
2974
+ const time = this.#formatDatetimePipe.transform(value, 'HH:mm:ss');
2992
2975
  if (type === 'datetime') {
2993
2976
  return time && date ? `<div class="T14R">${date}<span class="T14R text-black400 ml-4">${time}</span></div>` : '';
2994
2977
  }
2995
2978
  if (type === 'date')
2996
- return date || '';
2979
+ return date ?? '';
2997
2980
  if (type === 'time')
2998
- return time || '';
2981
+ return time ?? '';
2999
2982
  return '';
3000
2983
  }
3001
2984
  #processValuesDisplay(value, column, field, cacheObjValues) {
@@ -3049,7 +3032,6 @@ const buildColumnWidthMap = (column) => {
3049
3032
  return result;
3050
3033
  };
3051
3034
 
3052
- /* eslint-disable @typescript-eslint/no-explicit-any */
3053
3035
  const isTableItem = (item) => !!item && typeof item === 'object' && 'data' in item && 'meta' in item;
3054
3036
  const resolveItemData = (item) => (isTableItem(item) ? item.data : item);
3055
3037
  const hasActiveColumnFilter = (rawColumnFilter = {}, columns = []) => columns.some(col => {