@weeehaoooz/talos-ui 0.1.1 → 0.1.2

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 (190) hide show
  1. package/README.md +2 -0
  2. package/fesm2022/{weeehaoooz-talos-ui-button-button-group.mjs → weeehaoooz-talos-ui-button.mjs} +91 -15
  3. package/fesm2022/weeehaoooz-talos-ui-button.mjs.map +1 -0
  4. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs +3110 -0
  5. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs.map +1 -0
  6. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs +2414 -0
  7. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs.map +1 -0
  8. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs +1039 -0
  9. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs.map +1 -0
  10. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs +2885 -0
  11. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs.map +1 -0
  12. package/fesm2022/weeehaoooz-talos-ui-form.mjs +10799 -0
  13. package/fesm2022/weeehaoooz-talos-ui-form.mjs.map +1 -0
  14. package/fesm2022/weeehaoooz-talos-ui-layout.mjs +1316 -7
  15. package/fesm2022/weeehaoooz-talos-ui-layout.mjs.map +1 -1
  16. package/fesm2022/weeehaoooz-talos-ui-nav.mjs +3 -3
  17. package/fesm2022/weeehaoooz-talos-ui-nav.mjs.map +1 -1
  18. package/fesm2022/weeehaoooz-talos-ui.mjs +21592 -16293
  19. package/fesm2022/weeehaoooz-talos-ui.mjs.map +1 -1
  20. package/package.json +20 -139
  21. package/styles/_breadcrumb.scss +16 -0
  22. package/styles/_button-group.scss +2 -1
  23. package/styles/_buttons.scss +51 -0
  24. package/styles/_dropdown.scss +438 -0
  25. package/styles/_form-controls.scss +13 -0
  26. package/styles/_progress-bar.scss +43 -0
  27. package/styles/_skeleton.scss +176 -0
  28. package/styles/_spinner.scss +58 -0
  29. package/styles/_variables.scss +33 -0
  30. package/styles/index.scss +6 -1
  31. package/types/weeehaoooz-talos-ui-button.d.ts +92 -0
  32. package/types/weeehaoooz-talos-ui-button.d.ts.map +1 -0
  33. package/types/weeehaoooz-talos-ui-data-display.d.ts +1018 -0
  34. package/types/weeehaoooz-talos-ui-data-display.d.ts.map +1 -0
  35. package/types/weeehaoooz-talos-ui-data-viz.d.ts +839 -0
  36. package/types/weeehaoooz-talos-ui-data-viz.d.ts.map +1 -0
  37. package/types/weeehaoooz-talos-ui-dropdown.d.ts +187 -0
  38. package/types/weeehaoooz-talos-ui-dropdown.d.ts.map +1 -0
  39. package/types/weeehaoooz-talos-ui-feedback.d.ts +1495 -0
  40. package/types/weeehaoooz-talos-ui-feedback.d.ts.map +1 -0
  41. package/types/weeehaoooz-talos-ui-form.d.ts +2639 -0
  42. package/types/weeehaoooz-talos-ui-form.d.ts.map +1 -0
  43. package/types/weeehaoooz-talos-ui-layout.d.ts +851 -3
  44. package/types/weeehaoooz-talos-ui-layout.d.ts.map +1 -1
  45. package/types/weeehaoooz-talos-ui-nav.d.ts +1 -1
  46. package/types/weeehaoooz-talos-ui.d.ts +7148 -4629
  47. package/types/weeehaoooz-talos-ui.d.ts.map +1 -1
  48. package/fesm2022/weeehaoooz-talos-ui-button-button-group.mjs.map +0 -1
  49. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs +0 -94
  50. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs.map +0 -1
  51. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs +0 -233
  52. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs.map +0 -1
  53. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs +0 -1627
  54. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs.map +0 -1
  55. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs +0 -361
  56. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs.map +0 -1
  57. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs +0 -312
  58. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs.map +0 -1
  59. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs +0 -235
  60. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs.map +0 -1
  61. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs +0 -462
  62. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs.map +0 -1
  63. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs +0 -805
  64. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs.map +0 -1
  65. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs +0 -267
  66. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs.map +0 -1
  67. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs +0 -351
  68. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs.map +0 -1
  69. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs +0 -566
  70. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs.map +0 -1
  71. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs +0 -534
  72. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs.map +0 -1
  73. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs +0 -446
  74. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs.map +0 -1
  75. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs +0 -376
  76. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs.map +0 -1
  77. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs +0 -147
  78. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs.map +0 -1
  79. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs +0 -242
  80. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs.map +0 -1
  81. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs +0 -514
  82. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs.map +0 -1
  83. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs +0 -548
  84. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs.map +0 -1
  85. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs +0 -692
  86. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs.map +0 -1
  87. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs +0 -761
  88. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs.map +0 -1
  89. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs +0 -896
  90. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs.map +0 -1
  91. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs +0 -872
  92. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs.map +0 -1
  93. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs +0 -119
  94. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs.map +0 -1
  95. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs +0 -135
  96. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs.map +0 -1
  97. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs +0 -666
  98. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs.map +0 -1
  99. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs +0 -147
  100. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs.map +0 -1
  101. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs +0 -33
  102. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs.map +0 -1
  103. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs +0 -455
  104. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs.map +0 -1
  105. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs +0 -379
  106. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs.map +0 -1
  107. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs +0 -297
  108. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs.map +0 -1
  109. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs +0 -661
  110. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs.map +0 -1
  111. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs +0 -346
  112. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs.map +0 -1
  113. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs +0 -896
  114. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs.map +0 -1
  115. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs +0 -252
  116. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs.map +0 -1
  117. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs +0 -916
  118. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs.map +0 -1
  119. package/types/weeehaoooz-talos-ui-button-button-group.d.ts +0 -62
  120. package/types/weeehaoooz-talos-ui-button-button-group.d.ts.map +0 -1
  121. package/types/weeehaoooz-talos-ui-button-button.d.ts +0 -38
  122. package/types/weeehaoooz-talos-ui-button-button.d.ts.map +0 -1
  123. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts +0 -119
  124. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts.map +0 -1
  125. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts +0 -272
  126. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts.map +0 -1
  127. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts +0 -135
  128. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts.map +0 -1
  129. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts +0 -144
  130. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts.map +0 -1
  131. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts +0 -83
  132. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts.map +0 -1
  133. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts +0 -255
  134. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts.map +0 -1
  135. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts +0 -204
  136. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts.map +0 -1
  137. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts +0 -101
  138. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts.map +0 -1
  139. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts +0 -138
  140. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts.map +0 -1
  141. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts +0 -161
  142. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts.map +0 -1
  143. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts +0 -212
  144. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts.map +0 -1
  145. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts +0 -259
  146. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts.map +0 -1
  147. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts +0 -147
  148. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts.map +0 -1
  149. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts +0 -32
  150. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts.map +0 -1
  151. package/types/weeehaoooz-talos-ui-form-affix.d.ts +0 -88
  152. package/types/weeehaoooz-talos-ui-form-affix.d.ts.map +0 -1
  153. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts +0 -113
  154. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts.map +0 -1
  155. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts +0 -165
  156. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts.map +0 -1
  157. package/types/weeehaoooz-talos-ui-form-chips.d.ts +0 -152
  158. package/types/weeehaoooz-talos-ui-form-chips.d.ts.map +0 -1
  159. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts +0 -144
  160. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts.map +0 -1
  161. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts +0 -138
  162. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts.map +0 -1
  163. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts +0 -148
  164. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts.map +0 -1
  165. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts +0 -44
  166. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts.map +0 -1
  167. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts +0 -48
  168. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts.map +0 -1
  169. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts +0 -227
  170. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts.map +0 -1
  171. package/types/weeehaoooz-talos-ui-form-form-field.d.ts +0 -42
  172. package/types/weeehaoooz-talos-ui-form-form-field.d.ts.map +0 -1
  173. package/types/weeehaoooz-talos-ui-form-input.d.ts +0 -15
  174. package/types/weeehaoooz-talos-ui-form-input.d.ts.map +0 -1
  175. package/types/weeehaoooz-talos-ui-form-otp.d.ts +0 -111
  176. package/types/weeehaoooz-talos-ui-form-otp.d.ts.map +0 -1
  177. package/types/weeehaoooz-talos-ui-form-password-input.d.ts +0 -145
  178. package/types/weeehaoooz-talos-ui-form-password-input.d.ts.map +0 -1
  179. package/types/weeehaoooz-talos-ui-form-radio.d.ts +0 -84
  180. package/types/weeehaoooz-talos-ui-form-radio.d.ts.map +0 -1
  181. package/types/weeehaoooz-talos-ui-form-range-input.d.ts +0 -181
  182. package/types/weeehaoooz-talos-ui-form-range-input.d.ts.map +0 -1
  183. package/types/weeehaoooz-talos-ui-form-rating.d.ts +0 -110
  184. package/types/weeehaoooz-talos-ui-form-rating.d.ts.map +0 -1
  185. package/types/weeehaoooz-talos-ui-form-select-input.d.ts +0 -195
  186. package/types/weeehaoooz-talos-ui-form-select-input.d.ts.map +0 -1
  187. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts +0 -79
  188. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts.map +0 -1
  189. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts +0 -192
  190. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts.map +0 -1
@@ -1,1627 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { input, computed, Component, output, signal, Pipe, effect, NgModule } from '@angular/core';
3
- import { TalosStatusTagComponent } from '@weeehaoooz/talos-ui/data-display/status-tag';
4
- import { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';
5
- import { TalosButtonDirective } from '@weeehaoooz/talos-ui/button/button';
6
- import { TalosTooltipDirective } from '@weeehaoooz/talos-ui/feedback/tooltip';
7
- import * as i1 from '@angular/forms';
8
- import { FormsModule } from '@angular/forms';
9
- import { LucideSearch, LucideCheck, LucideChevronDown, LucideX, LucideArrowUp, LucideArrowDown, LucideArrowUpDown, LucideChevronLeft, LucideChevronRight, LucideChevronsLeft, LucideChevronsRight, LucideInbox, LucideLoader2, LucideFilter } from '@lucide/angular';
10
- import { DatePickerComponent } from '@weeehaoooz/talos-ui/form/date-picker';
11
- import * as i1$1 from '@angular/cdk/overlay';
12
- import { OverlayModule, CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
13
-
14
- class TalosGridStatusCellComponent {
15
- row = input.required(/* @ts-ignore */
16
- ...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
17
- column = input.required(/* @ts-ignore */
18
- ...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
19
- rawValue = input(/* @ts-ignore */
20
- ...(ngDevMode ? [undefined, { debugName: "rawValue" }] : /* istanbul ignore next */ []));
21
- value = computed(() => {
22
- const directVal = this.rawValue();
23
- if (directVal !== undefined) {
24
- return directVal;
25
- }
26
- const r = this.row();
27
- const col = this.column();
28
- if (!r || !col?.field)
29
- return '';
30
- return r[col.field];
31
- }, /* @ts-ignore */
32
- ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
33
- status = computed(() => {
34
- const val = this.value();
35
- const r = this.row();
36
- const config = this.column().statusConfig;
37
- if (config?.statusMap) {
38
- return config.statusMap(val, r);
39
- }
40
- return (val ?? 'PENDING');
41
- }, /* @ts-ignore */
42
- ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
43
- label = computed(() => {
44
- const val = this.value();
45
- const r = this.row();
46
- const col = this.column();
47
- if (col.formatter) {
48
- return col.formatter(val, r);
49
- }
50
- return String(val ?? '');
51
- }, /* @ts-ignore */
52
- ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
53
- variant = computed(() => {
54
- return this.column().statusConfig?.variant ?? 'subtle';
55
- }, /* @ts-ignore */
56
- ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
57
- size = computed(() => {
58
- return this.column().statusConfig?.size ?? 'sm';
59
- }, /* @ts-ignore */
60
- ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
61
- shape = computed(() => {
62
- return this.column().statusConfig?.shape ?? 'rounded';
63
- }, /* @ts-ignore */
64
- ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
65
- showIcon = computed(() => {
66
- return this.column().statusConfig?.showIcon ?? true;
67
- }, /* @ts-ignore */
68
- ...(ngDevMode ? [{ debugName: "showIcon" }] : /* istanbul ignore next */ []));
69
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridStatusCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
70
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: TalosGridStatusCellComponent, isStandalone: true, selector: "talos-grid-status-cell", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rawValue: { classPropertyName: "rawValue", publicName: "rawValue", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "talos-grid-status-cell" }, ngImport: i0, template: `
71
- <talos-status-tag
72
- [status]="status()"
73
- [variant]="variant()"
74
- [size]="size()"
75
- [shape]="shape()"
76
- [showIcon]="showIcon()"
77
- >
78
- {{ label() }}
79
- </talos-status-tag>
80
- `, isInline: true, dependencies: [{ kind: "component", type: TalosStatusTagComponent, selector: "talos-status-tag, [talosStatusTag]", inputs: ["status", "label", "variant", "size", "shape", "showIcon", "icon", "iconOnly", "pulse", "ariaLabel"] }] });
81
- }
82
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridStatusCellComponent, decorators: [{
83
- type: Component,
84
- args: [{
85
- selector: 'talos-grid-status-cell',
86
- imports: [TalosStatusTagComponent],
87
- template: `
88
- <talos-status-tag
89
- [status]="status()"
90
- [variant]="variant()"
91
- [size]="size()"
92
- [shape]="shape()"
93
- [showIcon]="showIcon()"
94
- >
95
- {{ label() }}
96
- </talos-status-tag>
97
- `,
98
- host: {
99
- class: 'talos-grid-status-cell',
100
- },
101
- }]
102
- }], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], rawValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "rawValue", required: false }] }] } });
103
-
104
- class TalosGridActionsCellComponent {
105
- row = input.required(/* @ts-ignore */
106
- ...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
107
- rowIndex = input.required(/* @ts-ignore */
108
- ...(ngDevMode ? [{ debugName: "rowIndex" }] : /* istanbul ignore next */ []));
109
- actions = input([], /* @ts-ignore */
110
- ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
111
- actionClick = output();
112
- visibleActions() {
113
- const r = this.row();
114
- return (this.actions() || []).filter((a) => {
115
- if (typeof a.hidden === 'function') {
116
- return !a.hidden(r);
117
- }
118
- return !a.hidden;
119
- });
120
- }
121
- isActionDisabled(action) {
122
- if (typeof action.disabled === 'function') {
123
- return action.disabled(this.row());
124
- }
125
- return !!action.disabled;
126
- }
127
- getActionTooltip(action) {
128
- if (typeof action.tooltip === 'function') {
129
- return action.tooltip(this.row());
130
- }
131
- return action.tooltip || '';
132
- }
133
- onActionClick(action, event) {
134
- event.stopPropagation();
135
- if (this.isActionDisabled(action))
136
- return;
137
- if (action.onClick) {
138
- action.onClick(this.row(), this.rowIndex(), event);
139
- }
140
- this.actionClick.emit({
141
- actionId: action.id,
142
- row: this.row(),
143
- index: this.rowIndex(),
144
- });
145
- }
146
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridActionsCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
147
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosGridActionsCellComponent, isStandalone: true, selector: "talos-grid-actions-cell", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick" }, host: { classAttribute: "talos-grid-actions-cell" }, ngImport: i0, template: `
148
- <div class="talos-grid-actions-wrapper">
149
- @for (action of visibleActions(); track action.id) {
150
- <button
151
- talosButton
152
- type="button"
153
- [variant]="action.variant ?? 'ghost'"
154
- [size]="action.size ?? 'xs'"
155
- [iconOnly]="action.iconOnly ?? !action.label"
156
- [disabled]="isActionDisabled(action)"
157
- [talosTooltip]="getActionTooltip(action)"
158
- [tooltipDisabled]="!getActionTooltip(action)"
159
- (click)="onActionClick(action, $event)"
160
- >
161
- @if (action.icon) {
162
- <ng-container *ngComponentOutlet="action.icon" />
163
- }
164
- @if (action.label && !action.iconOnly) {
165
- <span class="action-label">{{ action.label }}</span>
166
- }
167
- </button>
168
- }
169
- </div>
170
- `, isInline: true, styles: [".talos-grid-actions-wrapper{display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap}.action-label{margin-left:2px;font-size:11.5px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: TalosButtonDirective, selector: "button[talosButton], a[talosButton], button[talos-btn], a[talos-btn]", inputs: ["variant", "size", "iconOnly", "fullWidth", "pill", "loading", "disabled", "animation", "spinning", "popping", "feedback"] }, { kind: "directive", type: TalosTooltipDirective, selector: "[talosTooltip], [tooltip]", inputs: ["talosTooltip", "tooltip", "tooltipPosition", "tooltipDisabled"] }] });
171
- }
172
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridActionsCellComponent, decorators: [{
173
- type: Component,
174
- args: [{ selector: 'talos-grid-actions-cell', imports: [NgComponentOutlet, TalosButtonDirective, TalosTooltipDirective], template: `
175
- <div class="talos-grid-actions-wrapper">
176
- @for (action of visibleActions(); track action.id) {
177
- <button
178
- talosButton
179
- type="button"
180
- [variant]="action.variant ?? 'ghost'"
181
- [size]="action.size ?? 'xs'"
182
- [iconOnly]="action.iconOnly ?? !action.label"
183
- [disabled]="isActionDisabled(action)"
184
- [talosTooltip]="getActionTooltip(action)"
185
- [tooltipDisabled]="!getActionTooltip(action)"
186
- (click)="onActionClick(action, $event)"
187
- >
188
- @if (action.icon) {
189
- <ng-container *ngComponentOutlet="action.icon" />
190
- }
191
- @if (action.label && !action.iconOnly) {
192
- <span class="action-label">{{ action.label }}</span>
193
- }
194
- </button>
195
- }
196
- </div>
197
- `, host: {
198
- class: 'talos-grid-actions-cell',
199
- }, styles: [".talos-grid-actions-wrapper{display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap}.action-label{margin-left:2px;font-size:11.5px;font-weight:500}\n"] }]
200
- }], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], rowIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIndex", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
201
-
202
- class TalosGridFilterDialogComponent {
203
- column = input.required(/* @ts-ignore */
204
- ...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
205
- distinctValues = input([], /* @ts-ignore */
206
- ...(ngDevMode ? [{ debugName: "distinctValues" }] : /* istanbul ignore next */ []));
207
- currentFilter = input(undefined, /* @ts-ignore */
208
- ...(ngDevMode ? [{ debugName: "currentFilter" }] : /* istanbul ignore next */ []));
209
- align = input('left', /* @ts-ignore */
210
- ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
211
- filterApplied = output();
212
- filterCleared = output();
213
- closed = output();
214
- // Template icons
215
- searchIcon = LucideSearch;
216
- checkIcon = LucideCheck;
217
- chevronDownIcon = LucideChevronDown;
218
- xIcon = LucideX;
219
- // Filter mode derived from column:
220
- // Mode A: text, select, status
221
- // Mode B: number, date
222
- filterMode = computed(() => {
223
- const col = this.column();
224
- if (col.filterMode)
225
- return col.filterMode;
226
- if (col.type === 'number' ||
227
- col.sortType === 'number' ||
228
- col.type === 'date' ||
229
- col.sortType === 'date') {
230
- return 'condition';
231
- }
232
- return 'set';
233
- }, /* @ts-ignore */
234
- ...(ngDevMode ? [{ debugName: "filterMode" }] : /* istanbul ignore next */ []));
235
- // Mode A local state
236
- searchTerm = signal('', /* @ts-ignore */
237
- ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
238
- selectedSet = signal(new Set(), /* @ts-ignore */
239
- ...(ngDevMode ? [{ debugName: "selectedSet" }] : /* istanbul ignore next */ []));
240
- // Mode B local state
241
- selectedOperator = signal('eq', /* @ts-ignore */
242
- ...(ngDevMode ? [{ debugName: "selectedOperator" }] : /* istanbul ignore next */ []));
243
- filterVal = signal('', /* @ts-ignore */
244
- ...(ngDevMode ? [{ debugName: "filterVal" }] : /* istanbul ignore next */ []));
245
- filterVal2 = signal('', /* @ts-ignore */
246
- ...(ngDevMode ? [{ debugName: "filterVal2" }] : /* istanbul ignore next */ []));
247
- operatorOptions = computed(() => {
248
- if (this.isDateField()) {
249
- return [
250
- { value: 'eq', label: 'Is on' },
251
- { value: 'neq', label: 'Is not on' },
252
- { value: 'gt', label: 'After' },
253
- { value: 'gte', label: 'On or after' },
254
- { value: 'lt', label: 'Before' },
255
- { value: 'lte', label: 'On or before' },
256
- { value: 'between', label: 'Between' },
257
- { value: 'blank', label: 'Blank' },
258
- { value: 'notBlank', label: 'Not blank' },
259
- ];
260
- }
261
- if (this.isNumberField()) {
262
- return [
263
- { value: 'eq', label: 'Equals' },
264
- { value: 'neq', label: 'Does not equal' },
265
- { value: 'gt', label: 'Greater than' },
266
- { value: 'gte', label: 'Greater than or equal to' },
267
- { value: 'lt', label: 'Less than' },
268
- { value: 'lte', label: 'Less than or equal to' },
269
- { value: 'between', label: 'Between' },
270
- { value: 'blank', label: 'Blank' },
271
- { value: 'notBlank', label: 'Not blank' },
272
- ];
273
- }
274
- return [
275
- { value: 'contains', label: 'Contains' },
276
- { value: 'eq', label: 'Equals' },
277
- { value: 'neq', label: 'Does not equal' },
278
- { value: 'startsWith', label: 'Starts with' },
279
- { value: 'endsWith', label: 'Ends with' },
280
- { value: 'blank', label: 'Blank' },
281
- { value: 'notBlank', label: 'Not blank' },
282
- ];
283
- }, /* @ts-ignore */
284
- ...(ngDevMode ? [{ debugName: "operatorOptions" }] : /* istanbul ignore next */ []));
285
- ngOnInit() {
286
- this.initFromCurrentFilter();
287
- }
288
- initFromCurrentFilter() {
289
- const cf = this.currentFilter();
290
- const all = this.distinctValues();
291
- if (this.filterMode() === 'set') {
292
- if (cf && cf.mode === 'set' && cf.selectedValues) {
293
- this.selectedSet.set(new Set(cf.selectedValues));
294
- }
295
- else {
296
- // Default: all selected
297
- this.selectedSet.set(new Set(all));
298
- }
299
- }
300
- else {
301
- if (cf && cf.mode === 'condition') {
302
- this.selectedOperator.set(cf.operator || 'eq');
303
- this.filterVal.set(cf.value !== undefined && cf.value !== null ? String(cf.value) : '');
304
- this.filterVal2.set(cf.secondValue !== undefined && cf.secondValue !== null ? String(cf.secondValue) : '');
305
- }
306
- else {
307
- const defaultOp = this.isDateField() || this.isNumberField() ? 'eq' : 'contains';
308
- this.selectedOperator.set(defaultOp);
309
- this.filterVal.set('');
310
- this.filterVal2.set('');
311
- }
312
- }
313
- }
314
- isDateField() {
315
- const col = this.column();
316
- return col.type === 'date' || col.sortType === 'date';
317
- }
318
- isNumberField() {
319
- const col = this.column();
320
- return col.type === 'number' || col.sortType === 'number';
321
- }
322
- onDateFilterValChange(val) {
323
- if (!val) {
324
- this.filterVal.set('');
325
- }
326
- else if (val instanceof Date) {
327
- const y = val.getFullYear();
328
- const m = String(val.getMonth() + 1).padStart(2, '0');
329
- const d = String(val.getDate()).padStart(2, '0');
330
- this.filterVal.set(`${y}-${m}-${d}`);
331
- }
332
- else {
333
- this.filterVal.set(String(val));
334
- }
335
- }
336
- onDateFilterVal2Change(val) {
337
- if (!val) {
338
- this.filterVal2.set('');
339
- }
340
- else if (val instanceof Date) {
341
- const y = val.getFullYear();
342
- const m = String(val.getMonth() + 1).padStart(2, '0');
343
- const d = String(val.getDate()).padStart(2, '0');
344
- this.filterVal2.set(`${y}-${m}-${d}`);
345
- }
346
- else {
347
- this.filterVal2.set(String(val));
348
- }
349
- }
350
- // Mode A Helpers
351
- visibleDistinctValues = computed(() => {
352
- const term = this.searchTerm().toLowerCase().trim();
353
- const all = this.distinctValues();
354
- if (!term)
355
- return all;
356
- return all.filter((v) => (v || '').toLowerCase().includes(term));
357
- }, /* @ts-ignore */
358
- ...(ngDevMode ? [{ debugName: "visibleDistinctValues" }] : /* istanbul ignore next */ []));
359
- isAllSelected() {
360
- const visible = this.visibleDistinctValues();
361
- if (visible.length === 0)
362
- return false;
363
- const sel = this.selectedSet();
364
- return visible.every((v) => sel.has(v));
365
- }
366
- isIndeterminate() {
367
- const visible = this.visibleDistinctValues();
368
- if (visible.length === 0)
369
- return false;
370
- const sel = this.selectedSet();
371
- const count = visible.filter((v) => sel.has(v)).length;
372
- return count > 0 && count < visible.length;
373
- }
374
- toggleSelectAll(event) {
375
- const checked = event.target.checked;
376
- const sel = new Set(this.selectedSet());
377
- const visible = this.visibleDistinctValues();
378
- if (checked) {
379
- visible.forEach((v) => sel.add(v));
380
- }
381
- else {
382
- visible.forEach((v) => sel.delete(v));
383
- }
384
- this.selectedSet.set(sel);
385
- }
386
- isValSelected(val) {
387
- return this.selectedSet().has(val);
388
- }
389
- toggleVal(val, event) {
390
- const checked = event.target.checked;
391
- const sel = new Set(this.selectedSet());
392
- if (checked) {
393
- sel.add(val);
394
- }
395
- else {
396
- sel.delete(val);
397
- }
398
- this.selectedSet.set(sel);
399
- }
400
- onSearchEnter() {
401
- const term = this.searchTerm().trim();
402
- if (term) {
403
- const visible = this.visibleDistinctValues();
404
- this.selectedSet.set(new Set(visible));
405
- }
406
- this.applySetFilter();
407
- }
408
- // Apply Actions
409
- applyFilter() {
410
- if (this.filterMode() === 'set') {
411
- this.applySetFilter();
412
- }
413
- else {
414
- this.applyConditionFilter();
415
- }
416
- }
417
- applySetFilter() {
418
- const field = this.column().field;
419
- const all = this.distinctValues();
420
- let sel = Array.from(this.selectedSet());
421
- // If search term is present and user hadn't changed individual checkboxes (still all selected),
422
- // narrow selection to the visible search matches
423
- const term = this.searchTerm().trim();
424
- if (term && sel.length === all.length) {
425
- sel = this.visibleDistinctValues();
426
- this.selectedSet.set(new Set(sel));
427
- }
428
- // If all distinct values are selected and no search term, it's effectively no filter
429
- if (sel.length === all.length && all.every((v) => this.selectedSet().has(v))) {
430
- this.clearFilter();
431
- return;
432
- }
433
- this.filterApplied.emit({
434
- field,
435
- mode: 'set',
436
- selectedValues: sel,
437
- });
438
- this.closed.emit();
439
- }
440
- applyConditionFilter() {
441
- const field = this.column().field;
442
- const op = this.selectedOperator();
443
- const val = this.filterVal().trim();
444
- const val2 = this.filterVal2().trim();
445
- if (op !== 'blank' && op !== 'notBlank' && val === '') {
446
- this.clearFilter();
447
- return;
448
- }
449
- this.filterApplied.emit({
450
- field,
451
- mode: 'condition',
452
- operator: op,
453
- value: val,
454
- secondValue: op === 'between' ? val2 : undefined,
455
- });
456
- this.closed.emit();
457
- }
458
- clearFilter() {
459
- this.filterCleared.emit();
460
- this.closed.emit();
461
- }
462
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridFilterDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
463
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosGridFilterDialogComponent, isStandalone: true, selector: "talos-grid-filter-dialog", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, distinctValues: { classPropertyName: "distinctValues", publicName: "distinctValues", isSignal: true, isRequired: false, transformFunction: null }, currentFilter: { classPropertyName: "currentFilter", publicName: "currentFilter", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterApplied: "filterApplied", filterCleared: "filterCleared", closed: "closed" }, host: { listeners: { "keydown.escape": "closed.emit()" }, properties: { "class.align-right": "align() === 'right'" } }, ngImport: i0, template: `
464
- <div class="filter-dialog-container" (click)="$event.stopPropagation()">
465
- @if (filterMode() === 'set') {
466
- <!-- MODE A: Searchable Checkbox List (for text / select / status) -->
467
- <div class="mode-a-wrapper">
468
- <!-- Search input -->
469
- <div class="search-input-wrapper">
470
- <span class="search-icon">
471
- <ng-container *ngComponentOutlet="searchIcon" />
472
- </span>
473
- <input
474
- type="text"
475
- class="filter-search-input"
476
- placeholder="Search..."
477
- [ngModel]="searchTerm()"
478
- (ngModelChange)="searchTerm.set($event)"
479
- (keydown.enter)="onSearchEnter()"
480
- autofocus
481
- />
482
- @if (searchTerm()) {
483
- <button type="button" class="clear-search-btn" (click)="searchTerm.set('')">
484
- <ng-container *ngComponentOutlet="xIcon" />
485
- </button>
486
- }
487
- </div>
488
-
489
- <!-- Checkbox List -->
490
- <div class="checkbox-list-wrapper">
491
- <!-- (Select All) item -->
492
- <label class="checkbox-item select-all-item">
493
- <input
494
- type="checkbox"
495
- class="filter-checkbox"
496
- [checked]="isAllSelected()"
497
- [indeterminate]="isIndeterminate()"
498
- (change)="toggleSelectAll($event)"
499
- />
500
- <span
501
- class="checkbox-custom"
502
- [class.is-checked]="isAllSelected()"
503
- [class.is-indeterminate]="isIndeterminate()"
504
- >
505
- @if (isAllSelected()) {
506
- <ng-container *ngComponentOutlet="checkIcon" />
507
- } @else if (isIndeterminate()) {
508
- <span class="indeterminate-bar"></span>
509
- }
510
- </span>
511
- <span class="checkbox-label">
512
- {{ searchTerm() ? '(Select All Matches)' : '(Select All)' }}
513
- </span>
514
- </label>
515
-
516
- <!-- Distinct item checkboxes -->
517
- @for (val of visibleDistinctValues(); track val) {
518
- <label class="checkbox-item">
519
- <input
520
- type="checkbox"
521
- class="filter-checkbox"
522
- [checked]="isValSelected(val)"
523
- (change)="toggleVal(val, $event)"
524
- />
525
- <span class="checkbox-custom" [class.is-checked]="isValSelected(val)">
526
- @if (isValSelected(val)) {
527
- <ng-container *ngComponentOutlet="checkIcon" />
528
- }
529
- </span>
530
- <span class="checkbox-label">{{ val || '(Blank)' }}</span>
531
- </label>
532
- }
533
-
534
- @if (visibleDistinctValues().length === 0) {
535
- <div class="no-matches-msg">No matching values</div>
536
- }
537
- </div>
538
- </div>
539
- } @else {
540
- <!-- MODE B: Operator Dropdown & Filter Input (for numbers / dates) -->
541
- <div class="mode-b-wrapper">
542
- <!-- Operator Dropdown -->
543
- <div class="operator-dropdown-wrapper">
544
- <select
545
- class="operator-select"
546
- [ngModel]="selectedOperator()"
547
- (ngModelChange)="selectedOperator.set($event)"
548
- >
549
- @for (op of operatorOptions(); track op.value) {
550
- <option [value]="op.value">{{ op.label }}</option>
551
- }
552
- </select>
553
- <span class="dropdown-arrow">
554
- <ng-container *ngComponentOutlet="chevronDownIcon" />
555
- </span>
556
- </div>
557
-
558
- <!-- Filter Value Input -->
559
- @if (selectedOperator() !== 'blank' && selectedOperator() !== 'notBlank') {
560
- @if (isDateField()) {
561
- <div class="date-picker-wrapper" (keydown.enter)="applyConditionFilter()">
562
- <talos-date-picker
563
- [ngModel]="filterVal()"
564
- (ngModelChange)="onDateFilterValChange($event)"
565
- size="sm"
566
- placeholder="Select date"
567
- />
568
- </div>
569
- } @else {
570
- <div class="search-input-wrapper">
571
- <span class="search-icon">
572
- <ng-container *ngComponentOutlet="searchIcon" />
573
- </span>
574
- <input
575
- type="text"
576
- class="filter-search-input"
577
- placeholder="Filter..."
578
- [ngModel]="filterVal()"
579
- (ngModelChange)="filterVal.set($event)"
580
- (keydown.enter)="applyConditionFilter()"
581
- autofocus
582
- />
583
- </div>
584
- }
585
-
586
- <!-- Second input for Between -->
587
- @if (selectedOperator() === 'between') {
588
- @if (isDateField()) {
589
- <div class="date-picker-wrapper" style="margin-top: 6px;" (keydown.enter)="applyConditionFilter()">
590
- <talos-date-picker
591
- [ngModel]="filterVal2()"
592
- (ngModelChange)="onDateFilterVal2Change($event)"
593
- size="sm"
594
- placeholder="And max date"
595
- />
596
- </div>
597
- } @else {
598
- <div class="search-input-wrapper" style="margin-top: 6px;">
599
- <span class="search-icon">
600
- <ng-container *ngComponentOutlet="searchIcon" />
601
- </span>
602
- <input
603
- type="text"
604
- class="filter-search-input"
605
- placeholder="And max value..."
606
- [ngModel]="filterVal2()"
607
- (ngModelChange)="filterVal2.set($event)"
608
- (keydown.enter)="applyConditionFilter()"
609
- />
610
- </div>
611
- }
612
- }
613
- }
614
- </div>
615
- }
616
-
617
- <!-- Dialog Footer -->
618
- <div class="dialog-footer">
619
- <button talosButton variant="ghost" size="sm" type="button" (click)="clearFilter()">
620
- Clear
621
- </button>
622
- <button talosButton variant="primary" size="sm" type="button" (click)="applyFilter()">
623
- Apply
624
- </button>
625
- </div>
626
- </div>
627
- `, isInline: true, styles: [":host{display:block;font-family:var(--talos-font-sans, system-ui, sans-serif);font-size:13px}.filter-dialog-container{background:var(--talos-dropdown-bg, var(--talos-bg-surface, #ffffff));color:var(--talos-text-primary, #0f172a);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-md, 8px);box-shadow:0 12px 28px -4px #00000040,0 4px 10px #0000001a;width:240px;padding:10px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.date-picker-wrapper{width:100%}.date-picker-wrapper talos-date-picker{display:block;width:100%}.search-input-wrapper{position:relative;display:flex;align-items:center;width:100%}.search-icon{position:absolute;left:9px;width:14px;height:14px;opacity:.6;display:flex;align-items:center;justify-content:center;pointer-events:none;color:var(--talos-text-muted, #94a3b8)}.search-icon ::ng-deep svg,.search-icon svg{width:13px;height:13px;display:block}.filter-search-input{width:100%;height:32px;padding:0 24px 0 28px;background:var(--talos-bg-subtle, #f8fafc);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 6px);color:var(--talos-text-primary, #0f172a);font-size:13px;outline:none;box-sizing:border-box;transition:border-color .15s,box-shadow .15s}.filter-search-input::placeholder{color:var(--talos-text-muted, #94a3b8)}.filter-search-input:focus{border-color:var(--talos-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40}.clear-search-btn{position:absolute;right:6px;background:transparent;border:none;color:var(--talos-text-muted, #94a3b8);cursor:pointer;padding:0;width:16px;height:16px;display:flex;align-items:center;justify-content:center}.clear-search-btn ::ng-deep svg,.clear-search-btn svg{width:12px;height:12px;display:block}.clear-search-btn:hover{color:var(--talos-text-primary, #0f172a)}.checkbox-list-wrapper{margin-top:8px;max-height:175px;overflow-y:auto;overflow-x:hidden;padding-right:4px;scrollbar-width:thin;scrollbar-color:var(--talos-border-default, #cbd5e1) transparent}.checkbox-list-wrapper::-webkit-scrollbar{width:5px}.checkbox-list-wrapper::-webkit-scrollbar-thumb{background:var(--talos-border-default, #cbd5e1);border-radius:4px}.checkbox-item{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;cursor:pointer;color:var(--talos-text-primary, #0f172a);transition:background-color .12s}.checkbox-item:hover{background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .05))}.checkbox-item.select-all-item{font-weight:500;border-bottom:1px solid var(--talos-border-subtle, rgba(0, 0, 0, .08));margin-bottom:3px;padding-bottom:6px}.filter-checkbox{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.checkbox-custom{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--talos-border-hover, #94a3b8);background:transparent;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .12s}.checkbox-custom ::ng-deep svg,.checkbox-custom svg{width:12px;height:12px;display:block}.checkbox-custom.is-checked,.checkbox-custom.is-indeterminate{background:var(--talos-primary, #2563eb);border-color:var(--talos-primary, #2563eb);color:#fff}.checkbox-custom .indeterminate-bar{width:8px;height:2px;background:#fff;border-radius:1px}.checkbox-label{font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.no-matches-msg{padding:12px;text-align:center;color:var(--talos-text-muted, #94a3b8);font-size:12px}.operator-dropdown-wrapper{position:relative;margin-bottom:8px}.operator-select{width:100%;height:32px;padding:0 24px 0 10px;background:var(--talos-bg-subtle, #f8fafc);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 6px);color:var(--talos-text-primary, #0f172a);font-size:13px;outline:none;cursor:pointer;appearance:none;box-sizing:border-box}.operator-select:focus{border-color:var(--talos-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40}.dropdown-arrow{position:absolute;right:8px;top:50%;transform:translateY(-50%);pointer-events:none;opacity:.6;width:14px;height:14px;display:flex;align-items:center;justify-content:center;color:var(--talos-text-muted, #94a3b8)}.dropdown-arrow ::ng-deep svg,.dropdown-arrow svg{width:13px;height:13px;display:block}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:6px;margin-top:10px;padding-top:8px;border-top:1px solid var(--talos-border-subtle, rgba(0, 0, 0, .08))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: TalosButtonDirective, selector: "button[talosButton], a[talosButton], button[talos-btn], a[talos-btn]", inputs: ["variant", "size", "iconOnly", "fullWidth", "pill", "loading", "disabled", "animation", "spinning", "popping", "feedback"] }, { kind: "component", type: DatePickerComponent, selector: "talos-date-picker", inputs: ["placeholder", "label", "floatingLabel", "floating", "required", "disabled", "clearable", "size", "displayFormat", "valueFormat", "showTime", "use24Hour", "showSeconds", "minuteStep", "minDate", "maxDate", "firstDayOfWeek", "filterDate"], outputs: ["dateChange", "opened", "closed"] }] });
628
- }
629
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridFilterDialogComponent, decorators: [{
630
- type: Component,
631
- args: [{ selector: 'talos-grid-filter-dialog', imports: [FormsModule, NgComponentOutlet, TalosButtonDirective, DatePickerComponent], host: {
632
- '[class.align-right]': "align() === 'right'",
633
- '(keydown.escape)': 'closed.emit()',
634
- }, template: `
635
- <div class="filter-dialog-container" (click)="$event.stopPropagation()">
636
- @if (filterMode() === 'set') {
637
- <!-- MODE A: Searchable Checkbox List (for text / select / status) -->
638
- <div class="mode-a-wrapper">
639
- <!-- Search input -->
640
- <div class="search-input-wrapper">
641
- <span class="search-icon">
642
- <ng-container *ngComponentOutlet="searchIcon" />
643
- </span>
644
- <input
645
- type="text"
646
- class="filter-search-input"
647
- placeholder="Search..."
648
- [ngModel]="searchTerm()"
649
- (ngModelChange)="searchTerm.set($event)"
650
- (keydown.enter)="onSearchEnter()"
651
- autofocus
652
- />
653
- @if (searchTerm()) {
654
- <button type="button" class="clear-search-btn" (click)="searchTerm.set('')">
655
- <ng-container *ngComponentOutlet="xIcon" />
656
- </button>
657
- }
658
- </div>
659
-
660
- <!-- Checkbox List -->
661
- <div class="checkbox-list-wrapper">
662
- <!-- (Select All) item -->
663
- <label class="checkbox-item select-all-item">
664
- <input
665
- type="checkbox"
666
- class="filter-checkbox"
667
- [checked]="isAllSelected()"
668
- [indeterminate]="isIndeterminate()"
669
- (change)="toggleSelectAll($event)"
670
- />
671
- <span
672
- class="checkbox-custom"
673
- [class.is-checked]="isAllSelected()"
674
- [class.is-indeterminate]="isIndeterminate()"
675
- >
676
- @if (isAllSelected()) {
677
- <ng-container *ngComponentOutlet="checkIcon" />
678
- } @else if (isIndeterminate()) {
679
- <span class="indeterminate-bar"></span>
680
- }
681
- </span>
682
- <span class="checkbox-label">
683
- {{ searchTerm() ? '(Select All Matches)' : '(Select All)' }}
684
- </span>
685
- </label>
686
-
687
- <!-- Distinct item checkboxes -->
688
- @for (val of visibleDistinctValues(); track val) {
689
- <label class="checkbox-item">
690
- <input
691
- type="checkbox"
692
- class="filter-checkbox"
693
- [checked]="isValSelected(val)"
694
- (change)="toggleVal(val, $event)"
695
- />
696
- <span class="checkbox-custom" [class.is-checked]="isValSelected(val)">
697
- @if (isValSelected(val)) {
698
- <ng-container *ngComponentOutlet="checkIcon" />
699
- }
700
- </span>
701
- <span class="checkbox-label">{{ val || '(Blank)' }}</span>
702
- </label>
703
- }
704
-
705
- @if (visibleDistinctValues().length === 0) {
706
- <div class="no-matches-msg">No matching values</div>
707
- }
708
- </div>
709
- </div>
710
- } @else {
711
- <!-- MODE B: Operator Dropdown & Filter Input (for numbers / dates) -->
712
- <div class="mode-b-wrapper">
713
- <!-- Operator Dropdown -->
714
- <div class="operator-dropdown-wrapper">
715
- <select
716
- class="operator-select"
717
- [ngModel]="selectedOperator()"
718
- (ngModelChange)="selectedOperator.set($event)"
719
- >
720
- @for (op of operatorOptions(); track op.value) {
721
- <option [value]="op.value">{{ op.label }}</option>
722
- }
723
- </select>
724
- <span class="dropdown-arrow">
725
- <ng-container *ngComponentOutlet="chevronDownIcon" />
726
- </span>
727
- </div>
728
-
729
- <!-- Filter Value Input -->
730
- @if (selectedOperator() !== 'blank' && selectedOperator() !== 'notBlank') {
731
- @if (isDateField()) {
732
- <div class="date-picker-wrapper" (keydown.enter)="applyConditionFilter()">
733
- <talos-date-picker
734
- [ngModel]="filterVal()"
735
- (ngModelChange)="onDateFilterValChange($event)"
736
- size="sm"
737
- placeholder="Select date"
738
- />
739
- </div>
740
- } @else {
741
- <div class="search-input-wrapper">
742
- <span class="search-icon">
743
- <ng-container *ngComponentOutlet="searchIcon" />
744
- </span>
745
- <input
746
- type="text"
747
- class="filter-search-input"
748
- placeholder="Filter..."
749
- [ngModel]="filterVal()"
750
- (ngModelChange)="filterVal.set($event)"
751
- (keydown.enter)="applyConditionFilter()"
752
- autofocus
753
- />
754
- </div>
755
- }
756
-
757
- <!-- Second input for Between -->
758
- @if (selectedOperator() === 'between') {
759
- @if (isDateField()) {
760
- <div class="date-picker-wrapper" style="margin-top: 6px;" (keydown.enter)="applyConditionFilter()">
761
- <talos-date-picker
762
- [ngModel]="filterVal2()"
763
- (ngModelChange)="onDateFilterVal2Change($event)"
764
- size="sm"
765
- placeholder="And max date"
766
- />
767
- </div>
768
- } @else {
769
- <div class="search-input-wrapper" style="margin-top: 6px;">
770
- <span class="search-icon">
771
- <ng-container *ngComponentOutlet="searchIcon" />
772
- </span>
773
- <input
774
- type="text"
775
- class="filter-search-input"
776
- placeholder="And max value..."
777
- [ngModel]="filterVal2()"
778
- (ngModelChange)="filterVal2.set($event)"
779
- (keydown.enter)="applyConditionFilter()"
780
- />
781
- </div>
782
- }
783
- }
784
- }
785
- </div>
786
- }
787
-
788
- <!-- Dialog Footer -->
789
- <div class="dialog-footer">
790
- <button talosButton variant="ghost" size="sm" type="button" (click)="clearFilter()">
791
- Clear
792
- </button>
793
- <button talosButton variant="primary" size="sm" type="button" (click)="applyFilter()">
794
- Apply
795
- </button>
796
- </div>
797
- </div>
798
- `, styles: [":host{display:block;font-family:var(--talos-font-sans, system-ui, sans-serif);font-size:13px}.filter-dialog-container{background:var(--talos-dropdown-bg, var(--talos-bg-surface, #ffffff));color:var(--talos-text-primary, #0f172a);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-md, 8px);box-shadow:0 12px 28px -4px #00000040,0 4px 10px #0000001a;width:240px;padding:10px;box-sizing:border-box;-webkit-user-select:none;user-select:none}.date-picker-wrapper{width:100%}.date-picker-wrapper talos-date-picker{display:block;width:100%}.search-input-wrapper{position:relative;display:flex;align-items:center;width:100%}.search-icon{position:absolute;left:9px;width:14px;height:14px;opacity:.6;display:flex;align-items:center;justify-content:center;pointer-events:none;color:var(--talos-text-muted, #94a3b8)}.search-icon ::ng-deep svg,.search-icon svg{width:13px;height:13px;display:block}.filter-search-input{width:100%;height:32px;padding:0 24px 0 28px;background:var(--talos-bg-subtle, #f8fafc);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 6px);color:var(--talos-text-primary, #0f172a);font-size:13px;outline:none;box-sizing:border-box;transition:border-color .15s,box-shadow .15s}.filter-search-input::placeholder{color:var(--talos-text-muted, #94a3b8)}.filter-search-input:focus{border-color:var(--talos-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40}.clear-search-btn{position:absolute;right:6px;background:transparent;border:none;color:var(--talos-text-muted, #94a3b8);cursor:pointer;padding:0;width:16px;height:16px;display:flex;align-items:center;justify-content:center}.clear-search-btn ::ng-deep svg,.clear-search-btn svg{width:12px;height:12px;display:block}.clear-search-btn:hover{color:var(--talos-text-primary, #0f172a)}.checkbox-list-wrapper{margin-top:8px;max-height:175px;overflow-y:auto;overflow-x:hidden;padding-right:4px;scrollbar-width:thin;scrollbar-color:var(--talos-border-default, #cbd5e1) transparent}.checkbox-list-wrapper::-webkit-scrollbar{width:5px}.checkbox-list-wrapper::-webkit-scrollbar-thumb{background:var(--talos-border-default, #cbd5e1);border-radius:4px}.checkbox-item{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;cursor:pointer;color:var(--talos-text-primary, #0f172a);transition:background-color .12s}.checkbox-item:hover{background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .05))}.checkbox-item.select-all-item{font-weight:500;border-bottom:1px solid var(--talos-border-subtle, rgba(0, 0, 0, .08));margin-bottom:3px;padding-bottom:6px}.filter-checkbox{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.checkbox-custom{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--talos-border-hover, #94a3b8);background:transparent;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .12s}.checkbox-custom ::ng-deep svg,.checkbox-custom svg{width:12px;height:12px;display:block}.checkbox-custom.is-checked,.checkbox-custom.is-indeterminate{background:var(--talos-primary, #2563eb);border-color:var(--talos-primary, #2563eb);color:#fff}.checkbox-custom .indeterminate-bar{width:8px;height:2px;background:#fff;border-radius:1px}.checkbox-label{font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.no-matches-msg{padding:12px;text-align:center;color:var(--talos-text-muted, #94a3b8);font-size:12px}.operator-dropdown-wrapper{position:relative;margin-bottom:8px}.operator-select{width:100%;height:32px;padding:0 24px 0 10px;background:var(--talos-bg-subtle, #f8fafc);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 6px);color:var(--talos-text-primary, #0f172a);font-size:13px;outline:none;cursor:pointer;appearance:none;box-sizing:border-box}.operator-select:focus{border-color:var(--talos-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40}.dropdown-arrow{position:absolute;right:8px;top:50%;transform:translateY(-50%);pointer-events:none;opacity:.6;width:14px;height:14px;display:flex;align-items:center;justify-content:center;color:var(--talos-text-muted, #94a3b8)}.dropdown-arrow ::ng-deep svg,.dropdown-arrow svg{width:13px;height:13px;display:block}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:6px;margin-top:10px;padding-top:8px;border-top:1px solid var(--talos-border-subtle, rgba(0, 0, 0, .08))}\n"] }]
799
- }], propDecorators: { column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], distinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "distinctValues", required: false }] }], currentFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFilter", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], filterApplied: [{ type: i0.Output, args: ["filterApplied"] }], filterCleared: [{ type: i0.Output, args: ["filterCleared"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
800
-
801
- class TalosGridCellFormatPipe {
802
- fieldPartsCache = new Map();
803
- transform(row, col) {
804
- if (!row || !col)
805
- return '';
806
- const val = this.extractFieldValue(row, col.field);
807
- if (col.formatter) {
808
- return col.formatter(val, row);
809
- }
810
- if (val === null || val === undefined) {
811
- return '';
812
- }
813
- if (col.type === 'date' && val instanceof Date) {
814
- return val.toLocaleDateString();
815
- }
816
- return String(val);
817
- }
818
- extractFieldValue(item, field) {
819
- if (!item || !field)
820
- return undefined;
821
- if (!field.includes('.')) {
822
- return item[field];
823
- }
824
- let parts = this.fieldPartsCache.get(field);
825
- if (!parts) {
826
- parts = field.split('.');
827
- this.fieldPartsCache.set(field, parts);
828
- }
829
- let cur = item;
830
- for (let i = 0; i < parts.length; i++) {
831
- if (cur == null)
832
- return undefined;
833
- cur = cur[parts[i]];
834
- }
835
- return cur;
836
- }
837
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridCellFormatPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
838
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.1", ngImport: i0, type: TalosGridCellFormatPipe, isStandalone: true, name: "talosGridCellFormat" });
839
- }
840
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosGridCellFormatPipe, decorators: [{
841
- type: Pipe,
842
- args: [{
843
- name: 'talosGridCellFormat',
844
- pure: true,
845
- }]
846
- }] });
847
-
848
- class TalosDataGridComponent {
849
- // Inputs
850
- data = input.required(/* @ts-ignore */
851
- ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
852
- columns = input.required(/* @ts-ignore */
853
- ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
854
- density = input('comfortable', /* @ts-ignore */
855
- ...(ngDevMode ? [{ debugName: "density" }] : /* istanbul ignore next */ []));
856
- filterable = input(false, /* @ts-ignore */
857
- ...(ngDevMode ? [{ debugName: "filterable" }] : /* istanbul ignore next */ []));
858
- pagination = input(false, /* @ts-ignore */
859
- ...(ngDevMode ? [{ debugName: "pagination" }] : /* istanbul ignore next */ []));
860
- pageSize = input(10, /* @ts-ignore */
861
- ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
862
- pageSizeOptions = input([5, 10, 20, 50], /* @ts-ignore */
863
- ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
864
- pageIndex = input(0, /* @ts-ignore */
865
- ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
866
- totalItems = input(null, /* @ts-ignore */
867
- ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
868
- trackBy = input(null, /* @ts-ignore */
869
- ...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
870
- striped = input(false, /* @ts-ignore */
871
- ...(ngDevMode ? [{ debugName: "striped" }] : /* istanbul ignore next */ []));
872
- bordered = input(true, /* @ts-ignore */
873
- ...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
874
- hoverable = input(true, /* @ts-ignore */
875
- ...(ngDevMode ? [{ debugName: "hoverable" }] : /* istanbul ignore next */ []));
876
- emptyMessage = input('No records to display', /* @ts-ignore */
877
- ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
878
- loading = input(false, /* @ts-ignore */
879
- ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
880
- clientSort = input(true, /* @ts-ignore */
881
- ...(ngDevMode ? [{ debugName: "clientSort" }] : /* istanbul ignore next */ []));
882
- clientPagination = input(true, /* @ts-ignore */
883
- ...(ngDevMode ? [{ debugName: "clientPagination" }] : /* istanbul ignore next */ []));
884
- clientFilter = input(true, /* @ts-ignore */
885
- ...(ngDevMode ? [{ debugName: "clientFilter" }] : /* istanbul ignore next */ []));
886
- resizable = input(false, /* @ts-ignore */
887
- ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
888
- rowKey = input(null, /* @ts-ignore */
889
- ...(ngDevMode ? [{ debugName: "rowKey" }] : /* istanbul ignore next */ []));
890
- // Outputs
891
- sortChange = output();
892
- filterChange = output();
893
- pageChange = output();
894
- rowClick = output();
895
- actionClick = output();
896
- columnResize = output();
897
- // Icons for template
898
- arrowUpIcon = LucideArrowUp;
899
- arrowDownIcon = LucideArrowDown;
900
- arrowUpDownIcon = LucideArrowUpDown;
901
- chevronLeftIcon = LucideChevronLeft;
902
- chevronRightIcon = LucideChevronRight;
903
- chevronsLeftIcon = LucideChevronsLeft;
904
- chevronsRightIcon = LucideChevronsRight;
905
- xIcon = LucideX;
906
- inboxIcon = LucideInbox;
907
- loaderIcon = LucideLoader2;
908
- filterIcon = LucideFilter;
909
- // Internal reactive states
910
- internalSortState = signal({ field: '', direction: null }, /* @ts-ignore */
911
- ...(ngDevMode ? [{ debugName: "internalSortState" }] : /* istanbul ignore next */ []));
912
- internalFilterStates = signal(new Map(), /* @ts-ignore */
913
- ...(ngDevMode ? [{ debugName: "internalFilterStates" }] : /* istanbul ignore next */ []));
914
- internalPageIndex = signal(0, /* @ts-ignore */
915
- ...(ngDevMode ? [{ debugName: "internalPageIndex" }] : /* istanbul ignore next */ []));
916
- internalPageSize = signal(10, /* @ts-ignore */
917
- ...(ngDevMode ? [{ debugName: "internalPageSize" }] : /* istanbul ignore next */ []));
918
- activeFilterCol = signal(null, /* @ts-ignore */
919
- ...(ngDevMode ? [{ debugName: "activeFilterCol" }] : /* istanbul ignore next */ []));
920
- columnWidths = signal({}, /* @ts-ignore */
921
- ...(ngDevMode ? [{ debugName: "columnWidths" }] : /* istanbul ignore next */ []));
922
- resizingColumn = signal(null, /* @ts-ignore */
923
- ...(ngDevMode ? [{ debugName: "resizingColumn" }] : /* istanbul ignore next */ []));
924
- isResizing = computed(() => this.resizingColumn() !== null, /* @ts-ignore */
925
- ...(ngDevMode ? [{ debugName: "isResizing" }] : /* istanbul ignore next */ []));
926
- hasResizableColumns = computed(() => {
927
- return this.resizable() || this.columns().some((c) => c.resizable === true);
928
- }, /* @ts-ignore */
929
- ...(ngDevMode ? [{ debugName: "hasResizableColumns" }] : /* istanbul ignore next */ []));
930
- // CDK Connected Overlay Positions
931
- overlayPositions = [
932
- {
933
- originX: 'start',
934
- originY: 'bottom',
935
- overlayX: 'start',
936
- overlayY: 'top',
937
- offsetY: 6,
938
- },
939
- {
940
- originX: 'end',
941
- originY: 'bottom',
942
- overlayX: 'end',
943
- overlayY: 'top',
944
- offsetY: 6,
945
- },
946
- {
947
- originX: 'start',
948
- originY: 'top',
949
- overlayX: 'start',
950
- overlayY: 'bottom',
951
- offsetY: -6,
952
- },
953
- {
954
- originX: 'end',
955
- originY: 'top',
956
- overlayX: 'end',
957
- overlayY: 'bottom',
958
- offsetY: -6,
959
- },
960
- ];
961
- constructor() {
962
- effect(() => {
963
- this.internalPageIndex.set(this.pageIndex());
964
- });
965
- effect(() => {
966
- this.internalPageSize.set(this.pageSize());
967
- });
968
- }
969
- // Active filters list
970
- activeFiltersList = computed(() => {
971
- return Array.from(this.internalFilterStates().values());
972
- }, /* @ts-ignore */
973
- ...(ngDevMode ? [{ debugName: "activeFiltersList" }] : /* istanbul ignore next */ []));
974
- hasActiveFilters = computed(() => {
975
- return this.internalFilterStates().size > 0;
976
- }, /* @ts-ignore */
977
- ...(ngDevMode ? [{ debugName: "hasActiveFilters" }] : /* istanbul ignore next */ []));
978
- // Cached distinct values for the currently active filter column
979
- activeColumnDistinctValues = computed(() => {
980
- const field = this.activeFilterCol();
981
- if (!field)
982
- return [];
983
- const col = this.columns().find((c) => c.field === field);
984
- if (!col)
985
- return [];
986
- return this.getDistinctValues(col);
987
- }, /* @ts-ignore */
988
- ...(ngDevMode ? [{ debugName: "activeColumnDistinctValues" }] : /* istanbul ignore next */ []));
989
- // Multi-Stage Processing Pipeline:
990
- // Stage 1: Filtered Data
991
- filteredData = computed(() => {
992
- const raw = this.data() || [];
993
- if (!this.clientFilter() || this.internalFilterStates().size === 0) {
994
- return raw;
995
- }
996
- const filters = this.internalFilterStates();
997
- const colsMap = new Map(this.columns().map((c) => [c.field, c]));
998
- return raw.filter((item) => {
999
- for (const [field, filter] of filters.entries()) {
1000
- const rawVal = this.extractFieldValue(item, field);
1001
- const col = colsMap.get(field);
1002
- if (!this.matchesFilter(rawVal, filter, col)) {
1003
- return false;
1004
- }
1005
- }
1006
- return true;
1007
- });
1008
- }, /* @ts-ignore */
1009
- ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
1010
- // Stage 2: Sorted Data
1011
- sortedData = computed(() => {
1012
- const base = this.filteredData();
1013
- const sort = this.internalSortState();
1014
- if (!this.clientSort() || !sort.direction || !sort.field) {
1015
- return base;
1016
- }
1017
- const col = this.columns().find((c) => c.field === sort.field);
1018
- const sortType = sort.sortType || col?.sortType || this.inferSortType(col);
1019
- const dir = sort.direction === 'asc' ? 1 : -1;
1020
- // Schwartzian transform: Pre-extract and parse sort keys in an O(N) pass
1021
- // to eliminate reflection, string conversions, and Date parsing from the O(N log N) comparator
1022
- const mapped = base.map((item, index) => {
1023
- const raw = this.extractFieldValue(item, sort.field);
1024
- let sortKey = null;
1025
- if (raw !== null && raw !== undefined && raw !== '') {
1026
- switch (sortType) {
1027
- case 'number': {
1028
- const num = Number(raw);
1029
- sortKey = isNaN(num) ? null : num;
1030
- break;
1031
- }
1032
- case 'date': {
1033
- const time = raw instanceof Date ? raw.getTime() : new Date(raw).getTime();
1034
- sortKey = isNaN(time) ? null : time;
1035
- break;
1036
- }
1037
- case 'string':
1038
- default:
1039
- sortKey = String(raw);
1040
- break;
1041
- }
1042
- }
1043
- return { item, index, sortKey };
1044
- });
1045
- mapped.sort((a, b) => {
1046
- if (a.sortKey === b.sortKey)
1047
- return a.index - b.index;
1048
- if (a.sortKey === null)
1049
- return 1;
1050
- if (b.sortKey === null)
1051
- return -1;
1052
- if (sortType === 'number' || sortType === 'date') {
1053
- const diff = (a.sortKey - b.sortKey) * dir;
1054
- return diff !== 0 ? diff : a.index - b.index;
1055
- }
1056
- // string
1057
- const cmp = a.sortKey.localeCompare(b.sortKey, undefined, {
1058
- numeric: true,
1059
- sensitivity: 'base',
1060
- }) * dir;
1061
- return cmp !== 0 ? cmp : a.index - b.index;
1062
- });
1063
- return mapped.map((m) => m.item);
1064
- }, /* @ts-ignore */
1065
- ...(ngDevMode ? [{ debugName: "sortedData" }] : /* istanbul ignore next */ []));
1066
- // Stage 3: Paged Data
1067
- pagedData = computed(() => {
1068
- const sorted = this.sortedData();
1069
- if (!this.pagination() || !this.clientPagination()) {
1070
- return sorted;
1071
- }
1072
- const pageSize = this.internalPageSize();
1073
- const pageIndex = this.internalPageIndex();
1074
- const start = pageIndex * pageSize;
1075
- return sorted.slice(start, start + pageSize);
1076
- }, /* @ts-ignore */
1077
- ...(ngDevMode ? [{ debugName: "pagedData" }] : /* istanbul ignore next */ []));
1078
- // Stage 4: Pagination Metrics
1079
- totalCount = computed(() => {
1080
- const externalTotal = this.totalItems();
1081
- if (externalTotal !== null && externalTotal !== undefined) {
1082
- return externalTotal;
1083
- }
1084
- return this.filteredData().length;
1085
- }, /* @ts-ignore */
1086
- ...(ngDevMode ? [{ debugName: "totalCount" }] : /* istanbul ignore next */ []));
1087
- totalPages = computed(() => {
1088
- const count = this.totalCount();
1089
- const size = this.internalPageSize();
1090
- if (count <= 0 || size <= 0)
1091
- return 1;
1092
- return Math.ceil(count / size);
1093
- }, /* @ts-ignore */
1094
- ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
1095
- startRecord = computed(() => {
1096
- const total = this.totalCount();
1097
- if (total === 0)
1098
- return 0;
1099
- return this.internalPageIndex() * this.internalPageSize() + 1;
1100
- }, /* @ts-ignore */
1101
- ...(ngDevMode ? [{ debugName: "startRecord" }] : /* istanbul ignore next */ []));
1102
- endRecord = computed(() => {
1103
- const total = this.totalCount();
1104
- if (total === 0)
1105
- return 0;
1106
- return Math.min(total, (this.internalPageIndex() + 1) * this.internalPageSize());
1107
- }, /* @ts-ignore */
1108
- ...(ngDevMode ? [{ debugName: "endRecord" }] : /* istanbul ignore next */ []));
1109
- get hasRowClickListeners() {
1110
- return true;
1111
- }
1112
- // Row Identification for TrackBy
1113
- trackByRow(index, row) {
1114
- const customTrack = this.trackBy();
1115
- if (customTrack) {
1116
- return customTrack(index, row);
1117
- }
1118
- const customKey = this.rowKey();
1119
- if (customKey && row && typeof row === 'object') {
1120
- return row[customKey];
1121
- }
1122
- if (row && typeof row === 'object') {
1123
- const anyRow = row;
1124
- return anyRow.id ?? anyRow._id ?? anyRow.uuid ?? anyRow.key ?? index;
1125
- }
1126
- return index;
1127
- }
1128
- // Header & Sorting helpers
1129
- isSortable(col) {
1130
- if (col.type === 'actions')
1131
- return false;
1132
- if (col.sortable !== undefined)
1133
- return col.sortable;
1134
- return !!col.sortType;
1135
- }
1136
- isSorted(col) {
1137
- return (this.internalSortState().field === col.field && this.internalSortState().direction !== null);
1138
- }
1139
- getSortDirection(col) {
1140
- if (this.internalSortState().field !== col.field) {
1141
- return null;
1142
- }
1143
- return this.internalSortState().direction;
1144
- }
1145
- getAriaSort(col) {
1146
- if (!this.isSortable(col))
1147
- return null;
1148
- const dir = this.getSortDirection(col);
1149
- if (dir === 'asc')
1150
- return 'ascending';
1151
- if (dir === 'desc')
1152
- return 'descending';
1153
- return 'none';
1154
- }
1155
- onHeaderClick(col) {
1156
- if (!this.isSortable(col))
1157
- return;
1158
- const current = this.internalSortState();
1159
- let nextDirection;
1160
- if (current.field !== col.field) {
1161
- nextDirection = 'asc';
1162
- }
1163
- else if (current.direction === 'asc') {
1164
- nextDirection = 'desc';
1165
- }
1166
- else if (current.direction === 'desc') {
1167
- nextDirection = null;
1168
- }
1169
- else {
1170
- nextDirection = 'asc';
1171
- }
1172
- const sortType = col.sortType || this.inferSortType(col);
1173
- const newState = {
1174
- field: nextDirection ? col.field : '',
1175
- direction: nextDirection,
1176
- sortType,
1177
- };
1178
- this.internalSortState.set(newState);
1179
- this.sortChange.emit(newState);
1180
- }
1181
- // Column Resizing Helpers & Handlers
1182
- isResizable(col) {
1183
- if (col.resizable !== undefined) {
1184
- return col.resizable;
1185
- }
1186
- if (col.type === 'actions') {
1187
- return false;
1188
- }
1189
- return this.resizable();
1190
- }
1191
- isColumnResizing(field) {
1192
- return this.resizingColumn() === field;
1193
- }
1194
- getColumnWidth(col) {
1195
- const dynamic = this.columnWidths()[col.field];
1196
- if (dynamic !== undefined) {
1197
- return `${dynamic}px`;
1198
- }
1199
- return col.width || col.minWidth;
1200
- }
1201
- setColumnWidth(field, width) {
1202
- this.columnWidths.update((prev) => ({
1203
- ...prev,
1204
- [field]: width,
1205
- }));
1206
- }
1207
- resetColumnWidths() {
1208
- this.columnWidths.set({});
1209
- }
1210
- onResizeStart(col, event, thEl) {
1211
- if (!this.isResizable(col))
1212
- return;
1213
- event.preventDefault();
1214
- event.stopPropagation();
1215
- const startX = 'touches' in event ? event.touches[0].clientX : event.clientX;
1216
- const startWidth = thEl.getBoundingClientRect().width;
1217
- const minW = col.minWidth ? parseInt(col.minWidth, 10) : 50;
1218
- const maxW = col.maxWidth ? parseInt(col.maxWidth, 10) : undefined;
1219
- this.resizingColumn.set(col.field);
1220
- if (typeof document !== 'undefined') {
1221
- document.body.style.cursor = 'col-resize';
1222
- document.body.style.userSelect = 'none';
1223
- }
1224
- let lastWidth = startWidth;
1225
- const onMove = (moveEvent) => {
1226
- const currentX = 'touches' in moveEvent ? moveEvent.touches[0].clientX : moveEvent.clientX;
1227
- const deltaX = currentX - startX;
1228
- let newWidth = Math.round(startWidth + deltaX);
1229
- if (minW !== undefined && newWidth < minW)
1230
- newWidth = minW;
1231
- if (maxW !== undefined && newWidth > maxW)
1232
- newWidth = maxW;
1233
- lastWidth = newWidth;
1234
- this.columnWidths.update((prev) => ({
1235
- ...prev,
1236
- [col.field]: newWidth,
1237
- }));
1238
- };
1239
- const onEnd = () => {
1240
- if (typeof document !== 'undefined') {
1241
- document.removeEventListener('mousemove', onMove);
1242
- document.removeEventListener('mouseup', onEnd);
1243
- document.removeEventListener('touchmove', onMove);
1244
- document.removeEventListener('touchend', onEnd);
1245
- document.body.style.cursor = '';
1246
- document.body.style.userSelect = '';
1247
- }
1248
- this.resizingColumn.set(null);
1249
- this.columnResize.emit({ column: col, width: lastWidth });
1250
- };
1251
- if (typeof document !== 'undefined') {
1252
- document.addEventListener('mousemove', onMove);
1253
- document.addEventListener('mouseup', onEnd);
1254
- document.addEventListener('touchmove', onMove, { passive: true });
1255
- document.addEventListener('touchend', onEnd);
1256
- }
1257
- }
1258
- onResizeDoubleClick(col, event) {
1259
- event.stopPropagation();
1260
- event.preventDefault();
1261
- this.columnWidths.update((prev) => {
1262
- const next = { ...prev };
1263
- delete next[col.field];
1264
- return next;
1265
- });
1266
- if (col.width) {
1267
- const parsed = parseInt(col.width, 10);
1268
- if (!isNaN(parsed)) {
1269
- this.columnResize.emit({ column: col, width: parsed });
1270
- }
1271
- }
1272
- }
1273
- onResizeKeydown(col, event, thEl) {
1274
- if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
1275
- event.preventDefault();
1276
- event.stopPropagation();
1277
- const currentWidth = this.columnWidths()[col.field] ?? thEl.getBoundingClientRect().width;
1278
- const step = event.key === 'ArrowRight' ? 10 : -10;
1279
- const minW = col.minWidth ? parseInt(col.minWidth, 10) : 50;
1280
- const maxW = col.maxWidth ? parseInt(col.maxWidth, 10) : undefined;
1281
- let newWidth = Math.round(currentWidth + step);
1282
- if (minW !== undefined && newWidth < minW)
1283
- newWidth = minW;
1284
- if (maxW !== undefined && newWidth > maxW)
1285
- newWidth = maxW;
1286
- this.columnWidths.update((prev) => ({
1287
- ...prev,
1288
- [col.field]: newWidth,
1289
- }));
1290
- this.columnResize.emit({ column: col, width: newWidth });
1291
- }
1292
- }
1293
- // Filter Helpers & Dialog Management
1294
- isFilterable(col) {
1295
- if (col.type === 'actions')
1296
- return false;
1297
- if (col.filterable !== undefined)
1298
- return col.filterable;
1299
- return this.filterable();
1300
- }
1301
- isFilterDialogOpen(field) {
1302
- return this.activeFilterCol() === field;
1303
- }
1304
- toggleFilterDialog(field, event) {
1305
- event.stopPropagation();
1306
- if (this.activeFilterCol() === field) {
1307
- this.activeFilterCol.set(null);
1308
- }
1309
- else {
1310
- this.activeFilterCol.set(field);
1311
- }
1312
- }
1313
- closeFilterDialog() {
1314
- this.activeFilterCol.set(null);
1315
- }
1316
- onOverlayOutsideClick(event, field) {
1317
- const target = event.target;
1318
- if (target &&
1319
- (target.closest(`.filter-anchor-${field}`) ||
1320
- target.closest('.datepicker-dropdown-panel') ||
1321
- target.closest('.talos-datepicker-host'))) {
1322
- return;
1323
- }
1324
- this.closeFilterDialog();
1325
- }
1326
- getDistinctValues(col) {
1327
- const raw = this.data() || [];
1328
- const valuesSet = new Set();
1329
- for (const item of raw) {
1330
- const val = this.extractFieldValue(item, col.field);
1331
- if (val === null || val === undefined) {
1332
- valuesSet.add('');
1333
- }
1334
- else {
1335
- valuesSet.add(String(val));
1336
- }
1337
- }
1338
- return Array.from(valuesSet).sort((a, b) => {
1339
- if (a === '')
1340
- return 1;
1341
- if (b === '')
1342
- return -1;
1343
- return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });
1344
- });
1345
- }
1346
- getFilter(field) {
1347
- return this.internalFilterStates().get(field);
1348
- }
1349
- hasFilter(field) {
1350
- return this.internalFilterStates().has(field);
1351
- }
1352
- onFilterApplied(filter) {
1353
- const map = new Map(this.internalFilterStates());
1354
- map.set(filter.field, filter);
1355
- this.internalFilterStates.set(map);
1356
- this.internalPageIndex.set(0);
1357
- this.filterChange.emit(this.activeFiltersList());
1358
- }
1359
- onFilterCleared(field) {
1360
- const map = new Map(this.internalFilterStates());
1361
- map.delete(field);
1362
- this.internalFilterStates.set(map);
1363
- this.internalPageIndex.set(0);
1364
- this.filterChange.emit(this.activeFiltersList());
1365
- }
1366
- clearAllFilters() {
1367
- this.internalFilterStates.set(new Map());
1368
- this.internalPageIndex.set(0);
1369
- this.filterChange.emit([]);
1370
- }
1371
- // Filter Matching Evaluator
1372
- matchesFilter(rawValue, filter, col) {
1373
- // Mode A: Set Filter (text / select / status)
1374
- if (filter.mode === 'set') {
1375
- if (!filter.selectedValues)
1376
- return true;
1377
- const strVal = rawValue === null || rawValue === undefined ? '' : String(rawValue);
1378
- return filter.selectedValues.includes(strVal);
1379
- }
1380
- // Mode B: Condition Filter (numbers / dates / text)
1381
- const op = filter.operator || 'eq';
1382
- if (op === 'blank') {
1383
- return rawValue === null || rawValue === undefined || rawValue === '';
1384
- }
1385
- if (op === 'notBlank') {
1386
- return rawValue !== null && rawValue !== undefined && rawValue !== '';
1387
- }
1388
- if (rawValue === null || rawValue === undefined || rawValue === '') {
1389
- return false;
1390
- }
1391
- const filterVal = filter.value;
1392
- const secondVal = filter.secondValue;
1393
- // Check if comparing dates
1394
- const isDate = col?.type === 'date' ||
1395
- col?.sortType === 'date' ||
1396
- filterVal instanceof Date ||
1397
- (typeof filterVal === 'string' && /^\d{4}-\d{2}-\d{2}/.test(filterVal)) ||
1398
- rawValue instanceof Date;
1399
- if (isDate) {
1400
- const rowDate = this.normalizeDateToYMD(rawValue);
1401
- const targetDate = this.normalizeDateToYMD(filterVal);
1402
- const targetDate2 = secondVal ? this.normalizeDateToYMD(secondVal) : '';
1403
- switch (op) {
1404
- case 'eq':
1405
- return rowDate === targetDate;
1406
- case 'neq':
1407
- return rowDate !== targetDate;
1408
- case 'gt':
1409
- return rowDate > targetDate;
1410
- case 'gte':
1411
- return rowDate >= targetDate;
1412
- case 'lt':
1413
- return rowDate < targetDate;
1414
- case 'lte':
1415
- return rowDate <= targetDate;
1416
- case 'between': {
1417
- if (!targetDate2)
1418
- return rowDate >= targetDate;
1419
- const minD = targetDate <= targetDate2 ? targetDate : targetDate2;
1420
- const maxD = targetDate <= targetDate2 ? targetDate2 : targetDate;
1421
- return rowDate >= minD && rowDate <= maxD;
1422
- }
1423
- default:
1424
- return true;
1425
- }
1426
- }
1427
- // Check if comparing numbers
1428
- const isNumber = col?.type === 'number' || col?.sortType === 'number';
1429
- const hasFilterNum = filterVal !== '' &&
1430
- filterVal !== null &&
1431
- filterVal !== undefined &&
1432
- !isNaN(Number(filterVal));
1433
- const numRaw = Number(rawValue);
1434
- if ((isNumber || hasFilterNum) && !isNaN(numRaw)) {
1435
- const numFilter = Number(filterVal);
1436
- const numFilter2 = secondVal !== '' && secondVal !== null && secondVal !== undefined ? Number(secondVal) : NaN;
1437
- switch (op) {
1438
- case 'eq':
1439
- return numRaw === numFilter;
1440
- case 'neq':
1441
- return numRaw !== numFilter;
1442
- case 'gt':
1443
- return numRaw > numFilter;
1444
- case 'gte':
1445
- return numRaw >= numFilter;
1446
- case 'lt':
1447
- return numRaw < numFilter;
1448
- case 'lte':
1449
- return numRaw <= numFilter;
1450
- case 'between': {
1451
- if (isNaN(numFilter2))
1452
- return numRaw >= numFilter;
1453
- const minN = Math.min(numFilter, numFilter2);
1454
- const maxN = Math.max(numFilter, numFilter2);
1455
- return numRaw >= minN && numRaw <= maxN;
1456
- }
1457
- default:
1458
- return true;
1459
- }
1460
- }
1461
- // String / Text comparison
1462
- const strRaw = String(rawValue).toLowerCase().trim();
1463
- const strFilter = String(filterVal ?? '')
1464
- .toLowerCase()
1465
- .trim();
1466
- switch (op) {
1467
- case 'eq':
1468
- return strRaw === strFilter;
1469
- case 'neq':
1470
- return strRaw !== strFilter;
1471
- case 'startsWith':
1472
- return strRaw.startsWith(strFilter);
1473
- case 'endsWith':
1474
- return strRaw.endsWith(strFilter);
1475
- case 'contains':
1476
- default:
1477
- return strRaw.includes(strFilter);
1478
- }
1479
- }
1480
- normalizeDateToYMD(val) {
1481
- if (!val)
1482
- return '';
1483
- if (typeof val === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(val)) {
1484
- return val;
1485
- }
1486
- const d = new Date(val);
1487
- if (isNaN(d.getTime()))
1488
- return '';
1489
- const y = d.getFullYear();
1490
- const m = String(d.getMonth() + 1).padStart(2, '0');
1491
- const day = String(d.getDate()).padStart(2, '0');
1492
- return `${y}-${m}-${day}`;
1493
- }
1494
- // Pagination Handlers
1495
- setPage(pageIndex) {
1496
- const validPage = Math.max(0, Math.min(pageIndex, this.totalPages() - 1));
1497
- if (validPage !== this.internalPageIndex()) {
1498
- this.internalPageIndex.set(validPage);
1499
- this.pageChange.emit({
1500
- pageIndex: validPage,
1501
- pageSize: this.internalPageSize(),
1502
- totalItems: this.totalCount(),
1503
- });
1504
- }
1505
- }
1506
- onPageSizeChange(event) {
1507
- const target = event.target;
1508
- const newSize = Number(target.value);
1509
- this.internalPageSize.set(newSize);
1510
- this.internalPageIndex.set(0);
1511
- this.pageChange.emit({
1512
- pageIndex: 0,
1513
- pageSize: newSize,
1514
- totalItems: this.totalCount(),
1515
- });
1516
- }
1517
- // Cell Content & Row Click Helpers
1518
- getCellValue(row, col) {
1519
- return this.extractFieldValue(row, col.field);
1520
- }
1521
- formatCellValue(row, col) {
1522
- const val = this.getCellValue(row, col);
1523
- if (col.formatter) {
1524
- return col.formatter(val, row);
1525
- }
1526
- if (val === null || val === undefined) {
1527
- return '';
1528
- }
1529
- if (col.type === 'date' && val instanceof Date) {
1530
- return val.toLocaleDateString();
1531
- }
1532
- return String(val);
1533
- }
1534
- onRowClick(row, index) {
1535
- this.rowClick.emit({ row, index });
1536
- }
1537
- fieldPartsCache = new Map();
1538
- extractFieldValue(item, field) {
1539
- if (!item || !field)
1540
- return undefined;
1541
- if (!field.includes('.')) {
1542
- return item[field];
1543
- }
1544
- let parts = this.fieldPartsCache.get(field);
1545
- if (!parts) {
1546
- parts = field.split('.');
1547
- this.fieldPartsCache.set(field, parts);
1548
- }
1549
- let cur = item;
1550
- for (let i = 0; i < parts.length; i++) {
1551
- if (cur == null)
1552
- return undefined;
1553
- cur = cur[parts[i]];
1554
- }
1555
- return cur;
1556
- }
1557
- inferSortType(col) {
1558
- if (!col)
1559
- return 'string';
1560
- if (col.type === 'number')
1561
- return 'number';
1562
- if (col.type === 'date')
1563
- return 'date';
1564
- return 'string';
1565
- }
1566
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1567
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosDataGridComponent, isStandalone: true, selector: "talos-data-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, clientSort: { classPropertyName: "clientSort", publicName: "clientSort", isSignal: true, isRequired: false, transformFunction: null }, clientPagination: { classPropertyName: "clientPagination", publicName: "clientPagination", isSignal: true, isRequired: false, transformFunction: null }, clientFilter: { classPropertyName: "clientFilter", publicName: "clientFilter", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChange: "sortChange", filterChange: "filterChange", pageChange: "pageChange", rowClick: "rowClick", actionClick: "actionClick", columnResize: "columnResize" }, host: { classAttribute: "talos-data-grid-host" }, ngImport: i0, template: "<div\n class=\"talos-data-grid-container\"\n [class.density-compact]=\"density() === 'compact'\"\n [class.density-comfortable]=\"density() === 'comfortable'\"\n [class.density-spacious]=\"density() === 'spacious'\"\n [class.is-bordered]=\"bordered()\"\n [class.is-striped]=\"striped()\"\n [class.is-resizing]=\"isResizing()\"\n>\n <!-- Loading overlay -->\n @if (loading()) {\n <div class=\"talos-data-grid-loading-overlay\">\n <ng-container *ngComponentOutlet=\"loaderIcon\" />\n </div>\n }\n\n <!-- Main Scrollable Table Wrapper -->\n <div class=\"talos-data-grid-table-wrapper\">\n <table class=\"talos-data-grid-table\" [class.has-resizable-columns]=\"hasResizableColumns()\" role=\"grid\">\n <thead>\n <!-- Header Column Row -->\n <tr>\n @for (col of columns(); track col.field) {\n <th\n #thEl\n [style.width]=\"getColumnWidth(col)\"\n [style.min-width]=\"col.minWidth\"\n [style.max-width]=\"col.maxWidth\"\n [class.align-left]=\"!col.align || col.align === 'left'\"\n [class.align-center]=\"col.align === 'center'\"\n [class.align-right]=\"col.align === 'right'\"\n [class.is-sortable]=\"isSortable(col)\"\n [class.is-sorted]=\"isSorted(col)\"\n [class.is-resizable]=\"isResizable(col)\"\n [class.is-resizing]=\"isColumnResizing(col.field)\"\n (click)=\"onHeaderClick(col)\"\n role=\"columnheader\"\n [attr.aria-sort]=\"getAriaSort(col)\"\n >\n <div class=\"header-content-wrapper\">\n <span class=\"header-title\" [title]=\"col.header\">{{ col.header }}</span>\n @if (isSortable(col) || isFilterable(col)) {\n <div class=\"header-tools\">\n @if (isSortable(col)) {\n <button\n talosButton\n variant=\"ghost\"\n size=\"xs\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"header-sort-btn\"\n [class.is-sorted]=\"isSorted(col)\"\n (click)=\"$event.stopPropagation(); onHeaderClick(col)\"\n [attr.aria-label]=\"'Sort by ' + col.header\"\n [title]=\"'Sort by ' + col.header\"\n >\n @if (getSortDirection(col) === 'asc') {\n <ng-container *ngComponentOutlet=\"arrowUpIcon\" />\n } @else if (getSortDirection(col) === 'desc') {\n <ng-container *ngComponentOutlet=\"arrowDownIcon\" />\n } @else {\n <ng-container *ngComponentOutlet=\"arrowUpDownIcon\" />\n }\n </button>\n }\n @if (isFilterable(col)) {\n <div\n class=\"talos-grid-filter-anchor\"\n [class]=\"'filter-anchor-' + col.field\"\n cdkOverlayOrigin\n #filterOrigin=\"cdkOverlayOrigin\"\n (click)=\"$event.stopPropagation()\"\n >\n <button\n talosButton\n variant=\"ghost\"\n size=\"xs\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"header-filter-btn\"\n [class.is-active]=\"hasFilter(col.field)\"\n [class.is-open]=\"isFilterDialogOpen(col.field)\"\n (click)=\"toggleFilterDialog(col.field, $event)\"\n [attr.aria-label]=\"'Filter ' + col.header\"\n title=\"Filter\"\n >\n <ng-container *ngComponentOutlet=\"filterIcon\" />\n </button>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"filterOrigin\"\n [cdkConnectedOverlayOpen]=\"isFilterDialogOpen(col.field)\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick($event, col.field)\"\n >\n <talos-grid-filter-dialog\n [column]=\"col\"\n [distinctValues]=\"activeColumnDistinctValues()\"\n [currentFilter]=\"getFilter(col.field)\"\n [align]=\"col.align === 'right' ? 'right' : 'left'\"\n (filterApplied)=\"onFilterApplied($event)\"\n (filterCleared)=\"onFilterCleared(col.field)\"\n (closed)=\"closeFilterDialog()\"\n />\n </ng-template>\n </div>\n }\n </div>\n }\n </div>\n @if (isResizable(col)) {\n <div\n class=\"talos-grid-resize-handle\"\n [class.is-resizing]=\"isColumnResizing(col.field)\"\n (mousedown)=\"onResizeStart(col, $event, thEl)\"\n (touchstart)=\"onResizeStart(col, $event, thEl)\"\n (dblclick)=\"onResizeDoubleClick(col, $event)\"\n (click)=\"$event.stopPropagation()\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Resize ' + col.header + ' column'\"\n (keydown)=\"onResizeKeydown(col, $event, thEl)\"\n ></div>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Table Body with TrackBy for Optimal Refresh Performance -->\n <tbody>\n @for (row of pagedData(); track trackByRow($index, row)) {\n <tr\n [class.is-hoverable]=\"hoverable()\"\n [class.is-clickable]=\"hasRowClickListeners\"\n (click)=\"onRowClick(row, $index)\"\n role=\"row\"\n >\n @for (col of columns(); track col.field) {\n <td\n [class.align-left]=\"!col.align || col.align === 'left'\"\n [class.align-center]=\"col.align === 'center'\"\n [class.align-right]=\"col.align === 'right'\"\n role=\"gridcell\"\n >\n @if (col.cellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n col.cellTemplate;\n context: {\n $implicit: getCellValue(row, col),\n row: row,\n index: $index,\n column: col,\n }\n \"\n />\n } @else if (col.type === 'status') {\n <talos-grid-status-cell\n [row]=\"row\"\n [column]=\"col\"\n [rawValue]=\"getCellValue(row, col)\"\n />\n } @else if (col.type === 'actions' && col.actionsConfig) {\n <talos-grid-actions-cell\n [row]=\"row\"\n [rowIndex]=\"$index\"\n [actions]=\"col.actionsConfig\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n } @else {\n {{ row | talosGridCellFormat: col }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n\n <!-- Empty State -->\n @if (pagedData().length === 0) {\n <div class=\"talos-data-grid-empty\">\n <div class=\"empty-icon\">\n <ng-container *ngComponentOutlet=\"inboxIcon\" />\n </div>\n <div class=\"empty-text\">\n @if (hasActiveFilters()) {\n <span>No results matching the active filters.</span>\n } @else {\n <span>{{ emptyMessage() }}</span>\n }\n </div>\n @if (hasActiveFilters()) {\n <button talosButton variant=\"outline\" size=\"sm\" (click)=\"clearAllFilters()\">\n Clear Filters\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Pagination Bar -->\n @if (pagination()) {\n <div class=\"talos-data-grid-pagination\">\n <div class=\"pagination-left\">\n <span class=\"pagination-info\">\n Showing {{ startRecord() }} to {{ endRecord() }} of {{ totalCount() }} entries\n </span>\n\n @if (pageSizeOptions().length > 1) {\n <div class=\"pagination-size-selector\">\n <span>Rows per page:</span>\n <select\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Select page size\"\n >\n @for (size of pageSizeOptions(); track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </div>\n }\n </div>\n\n <div class=\"pagination-right\">\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() <= 0\"\n (click)=\"setPage(0)\"\n title=\"First page\"\n aria-label=\"First page\"\n >\n <ng-container *ngComponentOutlet=\"chevronsLeftIcon\" />\n </button>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() <= 0\"\n (click)=\"setPage(internalPageIndex() - 1)\"\n title=\"Previous page\"\n aria-label=\"Previous page\"\n >\n <ng-container *ngComponentOutlet=\"chevronLeftIcon\" />\n </button>\n\n <span class=\"page-indicator\">\n Page {{ internalPageIndex() + 1 }} of {{ totalPages() }}\n </span>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() >= totalPages() - 1\"\n (click)=\"setPage(internalPageIndex() + 1)\"\n title=\"Next page\"\n aria-label=\"Next page\"\n >\n <ng-container *ngComponentOutlet=\"chevronRightIcon\" />\n </button>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() >= totalPages() - 1\"\n (click)=\"setPage(totalPages() - 1)\"\n title=\"Last page\"\n aria-label=\"Last page\"\n >\n <ng-container *ngComponentOutlet=\"chevronsRightIcon\" />\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;font-family:var(--talos-font-sans, system-ui, -apple-system, sans-serif);color:var(--talos-text-primary, #0f172a)}.talos-data-grid-container{display:flex;flex-direction:column;background-color:var(--talos-bg-surface, #ffffff);border-radius:var(--talos-radius-lg, 8px);position:relative;width:100%;overflow:hidden}.talos-data-grid-container.is-bordered{border:1px solid var(--talos-border-default, #cbd5e1)}.talos-data-grid-container.is-resizing{cursor:col-resize!important;-webkit-user-select:none!important;user-select:none!important}.talos-data-grid-container.is-resizing *{-webkit-user-select:none!important;user-select:none!important;cursor:col-resize!important}.talos-data-grid-table-wrapper{width:100%;overflow-x:auto;overflow-y:visible;position:relative;scrollbar-width:thin;scrollbar-color:var(--talos-border-default, #cbd5e1) transparent}.talos-data-grid-table-wrapper::-webkit-scrollbar{height:6px;width:6px}.talos-data-grid-table-wrapper::-webkit-scrollbar-thumb{background:var(--talos-border-default, #cbd5e1);border-radius:4px}.talos-data-grid-table{width:100%;min-width:100%;border-collapse:collapse;text-align:left;font-size:var(--talos-font-size-sm, 13px);line-height:var(--talos-line-height-normal, 1.5)}.talos-data-grid-table.has-resizable-columns{table-layout:fixed;width:max-content;min-width:100%}.talos-data-grid-container.density-compact{--grid-header-padding-y: 6px;--grid-header-padding-x: 10px;--grid-cell-padding-y: 5px;--grid-cell-padding-x: 10px;--grid-font-size: 12px;--grid-header-font-size: 11px;--grid-filter-height: 24px}.talos-data-grid-container.density-comfortable{--grid-header-padding-y: 10px;--grid-header-padding-x: 14px;--grid-cell-padding-y: 9px;--grid-cell-padding-x: 14px;--grid-font-size: 13.5px;--grid-header-font-size: 12px;--grid-filter-height: 28px}.talos-data-grid-container.density-spacious{--grid-header-padding-y: 14px;--grid-header-padding-x: 18px;--grid-cell-padding-y: 14px;--grid-cell-padding-x: 18px;--grid-font-size: 14.5px;--grid-header-font-size: 13px;--grid-filter-height: 32px}.talos-data-grid-table thead th{position:relative;background-color:var(--talos-bg-subtle, #f8fafc);color:var(--talos-text-secondary, #475569);font-size:var(--grid-header-font-size, 12px);font-weight:var(--talos-font-weight-semibold, 600);text-transform:uppercase;letter-spacing:.04em;padding:var(--grid-header-padding-y) 8px var(--grid-header-padding-y) var(--grid-header-padding-x);border-bottom:1px solid var(--talos-border-default, #cbd5e1);white-space:nowrap;-webkit-user-select:none;user-select:none;vertical-align:middle;overflow:hidden}.talos-data-grid-table thead th.is-sortable{cursor:pointer;transition:background-color var(--talos-transition, .15s ease)}.talos-data-grid-table thead th.is-sortable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f1f5f9);color:var(--talos-text-primary, #0f172a)}.talos-data-grid-table thead th.is-sorted{color:var(--talos-primary, #2563eb);background-color:var(--talos-primary-subtle-bg, #eff6ff)}.talos-data-grid-table thead th.is-resizable{padding-right:10px}.talos-data-grid-table thead th.is-resizing{background-color:var(--talos-neutral-subtle-bg-hover, #f1f5f9)}.header-content-wrapper{display:flex;align-items:center;gap:4px;width:100%;min-width:0;overflow:hidden}.header-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-tools{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}.sort-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.45;transition:opacity var(--talos-transition, .15s ease),transform .15s ease}.sort-icon-wrapper ::ng-deep svg,.sort-icon-wrapper ::ng-deep .lucide,.sort-icon-wrapper svg,.sort-icon-wrapper .lucide{width:13px!important;height:13px!important;display:block}.is-sortable:hover .sort-icon-wrapper{opacity:.85}.is-sorted .sort-icon-wrapper{opacity:1;color:var(--talos-primary, #2563eb)}.header-sort-btn{width:22px!important;height:22px!important;min-width:22px!important;padding:0!important;border-radius:var(--talos-radius-sm, 4px)!important;border:1px solid transparent!important;background:transparent!important;color:var(--talos-text-muted, #94a3b8)!important;cursor:pointer;opacity:.45;transition:all var(--talos-transition, .15s ease);box-shadow:none!important}.header-sort-btn ::ng-deep svg,.header-sort-btn ::ng-deep .lucide,.header-sort-btn svg,.header-sort-btn .lucide{width:13px!important;height:13px!important;display:block;flex-shrink:0}th:hover .header-sort-btn{opacity:.85}.header-sort-btn:hover{opacity:1;color:var(--talos-text-primary, #0f172a)!important;background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .06))!important}.header-sort-btn.is-sorted{opacity:1;color:var(--talos-primary, #2563eb)!important;background:var(--talos-primary-subtle-bg, #eff6ff)!important}.align-left{text-align:left}.align-left .header-content-wrapper{justify-content:flex-start}.align-center{text-align:center}.align-center .header-content-wrapper{justify-content:center}.align-right{text-align:right}.align-right .header-content-wrapper{justify-content:flex-end}.talos-grid-resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;-webkit-user-select:none;user-select:none;touch-action:none;z-index:2;display:flex;align-items:center;justify-content:center}.talos-grid-resize-handle:after{content:\"\";display:block;width:2px;height:50%;border-radius:1px;background-color:transparent;transition:background-color var(--talos-transition, .15s ease),height var(--talos-transition, .15s ease)}.talos-grid-resize-handle:hover:after,.talos-grid-resize-handle:focus-visible:after,.talos-grid-resize-handle.is-resizing:after{background-color:var(--talos-primary, #2563eb);height:100%}.talos-grid-resize-handle:focus-visible{outline:none}.talos-grid-filter-anchor{position:relative;display:inline-flex;align-items:center}.header-filter-btn{display:inline-flex;align-items:center;justify-content:center;width:22px!important;height:22px!important;min-width:22px!important;padding:0!important;border-radius:var(--talos-radius-sm, 4px)!important;border:1px solid transparent!important;background:transparent!important;color:var(--talos-text-muted, #94a3b8)!important;cursor:pointer;opacity:.5;transition:all var(--talos-transition, .15s ease);box-shadow:none!important}.header-filter-btn ::ng-deep svg,.header-filter-btn ::ng-deep .lucide,.header-filter-btn svg,.header-filter-btn .lucide{width:13px!important;height:13px!important;display:block;flex-shrink:0}th:hover .header-filter-btn{opacity:.85}.header-filter-btn:hover,.header-filter-btn.is-open{opacity:1;color:var(--talos-text-primary, #0f172a)!important;background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .06))!important}.header-filter-btn.is-active{opacity:1;color:#fff!important;background:var(--talos-primary, #2563eb)!important;border-color:var(--talos-primary, #2563eb)!important}.talos-data-grid-table tbody tr{border-bottom:1px solid var(--talos-border-subtle, #f1f5f9);transition:background-color var(--talos-transition, .12s ease)}.talos-data-grid-table tbody tr.is-hoverable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f8fafc)}.talos-data-grid-table tbody tr.is-clickable{cursor:pointer}.talos-data-grid-container.is-striped .talos-data-grid-table tbody tr:nth-child(2n){background-color:var(--talos-bg-subtle, #fcfdfe)}.talos-data-grid-container.is-striped .talos-data-grid-table tbody tr:nth-child(2n).is-hoverable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f8fafc)}.talos-data-grid-table tbody td{padding:var(--grid-cell-padding-y) var(--grid-cell-padding-x);font-size:var(--grid-font-size, 13.5px);color:var(--talos-text-primary, #0f172a);vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.talos-data-grid-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--talos-text-muted, #64748b);text-align:center;gap:12px}.talos-data-grid-empty .empty-icon{opacity:.5;width:36px;height:36px;display:flex;align-items:center;justify-content:center}.talos-data-grid-empty .empty-icon ::ng-deep svg,.talos-data-grid-empty .empty-icon ::ng-deep .lucide,.talos-data-grid-empty .empty-icon svg,.talos-data-grid-empty .empty-icon .lucide{width:36px;height:36px}.talos-data-grid-empty .empty-text{font-size:var(--talos-font-size-base, 14px);font-weight:var(--talos-font-weight-medium, 500)}.talos-data-grid-pagination{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-top:1px solid var(--talos-border-default, #cbd5e1);background-color:var(--talos-bg-surface, #ffffff);gap:12px;flex-wrap:wrap}.pagination-left{display:flex;align-items:center;gap:12px}.pagination-info{font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-muted, #64748b)}.pagination-size-selector{display:flex;align-items:center;gap:6px;font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-secondary, #334155)}.pagination-size-selector select{height:28px;padding:0 8px;font-size:var(--talos-font-size-sm, 13px);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 4px);background-color:var(--talos-bg-surface, #ffffff);color:var(--talos-text-primary, #0f172a);cursor:pointer;outline:none}.pagination-size-selector select:focus{border-color:var(--talos-border-focus, #2563eb)}.pagination-right{display:flex;align-items:center;gap:4px}.pagination-right ::ng-deep button.talos-btn svg,.pagination-right ::ng-deep button.talos-btn .lucide{width:14px;height:14px}.page-indicator{font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-secondary, #334155);font-weight:var(--talos-font-weight-medium, 500);padding:0 8px}.talos-data-grid-loading-overlay{position:absolute;inset:0;background:#ffffffb3;display:flex;align-items:center;justify-content:center;z-index:10;-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}.talos-data-grid-loading-overlay ::ng-deep svg,.talos-data-grid-loading-overlay ::ng-deep .lucide,.talos-data-grid-loading-overlay svg,.talos-data-grid-loading-overlay .lucide{width:24px;height:24px;animation:talos-grid-spin .8s linear infinite}@keyframes talos-grid-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: TalosButtonDirective, selector: "button[talosButton], a[talosButton], button[talos-btn], a[talos-btn]", inputs: ["variant", "size", "iconOnly", "fullWidth", "pill", "loading", "disabled", "animation", "spinning", "popping", "feedback"] }, { kind: "component", type: TalosGridStatusCellComponent, selector: "talos-grid-status-cell", inputs: ["row", "column", "rawValue"] }, { kind: "component", type: TalosGridActionsCellComponent, selector: "talos-grid-actions-cell", inputs: ["row", "rowIndex", "actions"], outputs: ["actionClick"] }, { kind: "component", type: TalosGridFilterDialogComponent, selector: "talos-grid-filter-dialog", inputs: ["column", "distinctValues", "currentFilter", "align"], outputs: ["filterApplied", "filterCleared", "closed"] }, { kind: "pipe", type: TalosGridCellFormatPipe, name: "talosGridCellFormat" }] });
1568
- }
1569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridComponent, decorators: [{
1570
- type: Component,
1571
- args: [{ selector: 'talos-data-grid', imports: [
1572
- NgComponentOutlet,
1573
- NgTemplateOutlet,
1574
- OverlayModule,
1575
- CdkConnectedOverlay,
1576
- CdkOverlayOrigin,
1577
- TalosButtonDirective,
1578
- TalosGridStatusCellComponent,
1579
- TalosGridActionsCellComponent,
1580
- TalosGridFilterDialogComponent,
1581
- TalosGridCellFormatPipe,
1582
- ], host: {
1583
- class: 'talos-data-grid-host',
1584
- }, template: "<div\n class=\"talos-data-grid-container\"\n [class.density-compact]=\"density() === 'compact'\"\n [class.density-comfortable]=\"density() === 'comfortable'\"\n [class.density-spacious]=\"density() === 'spacious'\"\n [class.is-bordered]=\"bordered()\"\n [class.is-striped]=\"striped()\"\n [class.is-resizing]=\"isResizing()\"\n>\n <!-- Loading overlay -->\n @if (loading()) {\n <div class=\"talos-data-grid-loading-overlay\">\n <ng-container *ngComponentOutlet=\"loaderIcon\" />\n </div>\n }\n\n <!-- Main Scrollable Table Wrapper -->\n <div class=\"talos-data-grid-table-wrapper\">\n <table class=\"talos-data-grid-table\" [class.has-resizable-columns]=\"hasResizableColumns()\" role=\"grid\">\n <thead>\n <!-- Header Column Row -->\n <tr>\n @for (col of columns(); track col.field) {\n <th\n #thEl\n [style.width]=\"getColumnWidth(col)\"\n [style.min-width]=\"col.minWidth\"\n [style.max-width]=\"col.maxWidth\"\n [class.align-left]=\"!col.align || col.align === 'left'\"\n [class.align-center]=\"col.align === 'center'\"\n [class.align-right]=\"col.align === 'right'\"\n [class.is-sortable]=\"isSortable(col)\"\n [class.is-sorted]=\"isSorted(col)\"\n [class.is-resizable]=\"isResizable(col)\"\n [class.is-resizing]=\"isColumnResizing(col.field)\"\n (click)=\"onHeaderClick(col)\"\n role=\"columnheader\"\n [attr.aria-sort]=\"getAriaSort(col)\"\n >\n <div class=\"header-content-wrapper\">\n <span class=\"header-title\" [title]=\"col.header\">{{ col.header }}</span>\n @if (isSortable(col) || isFilterable(col)) {\n <div class=\"header-tools\">\n @if (isSortable(col)) {\n <button\n talosButton\n variant=\"ghost\"\n size=\"xs\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"header-sort-btn\"\n [class.is-sorted]=\"isSorted(col)\"\n (click)=\"$event.stopPropagation(); onHeaderClick(col)\"\n [attr.aria-label]=\"'Sort by ' + col.header\"\n [title]=\"'Sort by ' + col.header\"\n >\n @if (getSortDirection(col) === 'asc') {\n <ng-container *ngComponentOutlet=\"arrowUpIcon\" />\n } @else if (getSortDirection(col) === 'desc') {\n <ng-container *ngComponentOutlet=\"arrowDownIcon\" />\n } @else {\n <ng-container *ngComponentOutlet=\"arrowUpDownIcon\" />\n }\n </button>\n }\n @if (isFilterable(col)) {\n <div\n class=\"talos-grid-filter-anchor\"\n [class]=\"'filter-anchor-' + col.field\"\n cdkOverlayOrigin\n #filterOrigin=\"cdkOverlayOrigin\"\n (click)=\"$event.stopPropagation()\"\n >\n <button\n talosButton\n variant=\"ghost\"\n size=\"xs\"\n [iconOnly]=\"true\"\n type=\"button\"\n class=\"header-filter-btn\"\n [class.is-active]=\"hasFilter(col.field)\"\n [class.is-open]=\"isFilterDialogOpen(col.field)\"\n (click)=\"toggleFilterDialog(col.field, $event)\"\n [attr.aria-label]=\"'Filter ' + col.header\"\n title=\"Filter\"\n >\n <ng-container *ngComponentOutlet=\"filterIcon\" />\n </button>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"filterOrigin\"\n [cdkConnectedOverlayOpen]=\"isFilterDialogOpen(col.field)\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick($event, col.field)\"\n >\n <talos-grid-filter-dialog\n [column]=\"col\"\n [distinctValues]=\"activeColumnDistinctValues()\"\n [currentFilter]=\"getFilter(col.field)\"\n [align]=\"col.align === 'right' ? 'right' : 'left'\"\n (filterApplied)=\"onFilterApplied($event)\"\n (filterCleared)=\"onFilterCleared(col.field)\"\n (closed)=\"closeFilterDialog()\"\n />\n </ng-template>\n </div>\n }\n </div>\n }\n </div>\n @if (isResizable(col)) {\n <div\n class=\"talos-grid-resize-handle\"\n [class.is-resizing]=\"isColumnResizing(col.field)\"\n (mousedown)=\"onResizeStart(col, $event, thEl)\"\n (touchstart)=\"onResizeStart(col, $event, thEl)\"\n (dblclick)=\"onResizeDoubleClick(col, $event)\"\n (click)=\"$event.stopPropagation()\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"'Resize ' + col.header + ' column'\"\n (keydown)=\"onResizeKeydown(col, $event, thEl)\"\n ></div>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Table Body with TrackBy for Optimal Refresh Performance -->\n <tbody>\n @for (row of pagedData(); track trackByRow($index, row)) {\n <tr\n [class.is-hoverable]=\"hoverable()\"\n [class.is-clickable]=\"hasRowClickListeners\"\n (click)=\"onRowClick(row, $index)\"\n role=\"row\"\n >\n @for (col of columns(); track col.field) {\n <td\n [class.align-left]=\"!col.align || col.align === 'left'\"\n [class.align-center]=\"col.align === 'center'\"\n [class.align-right]=\"col.align === 'right'\"\n role=\"gridcell\"\n >\n @if (col.cellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n col.cellTemplate;\n context: {\n $implicit: getCellValue(row, col),\n row: row,\n index: $index,\n column: col,\n }\n \"\n />\n } @else if (col.type === 'status') {\n <talos-grid-status-cell\n [row]=\"row\"\n [column]=\"col\"\n [rawValue]=\"getCellValue(row, col)\"\n />\n } @else if (col.type === 'actions' && col.actionsConfig) {\n <talos-grid-actions-cell\n [row]=\"row\"\n [rowIndex]=\"$index\"\n [actions]=\"col.actionsConfig\"\n (actionClick)=\"actionClick.emit($event)\"\n />\n } @else {\n {{ row | talosGridCellFormat: col }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n\n <!-- Empty State -->\n @if (pagedData().length === 0) {\n <div class=\"talos-data-grid-empty\">\n <div class=\"empty-icon\">\n <ng-container *ngComponentOutlet=\"inboxIcon\" />\n </div>\n <div class=\"empty-text\">\n @if (hasActiveFilters()) {\n <span>No results matching the active filters.</span>\n } @else {\n <span>{{ emptyMessage() }}</span>\n }\n </div>\n @if (hasActiveFilters()) {\n <button talosButton variant=\"outline\" size=\"sm\" (click)=\"clearAllFilters()\">\n Clear Filters\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Pagination Bar -->\n @if (pagination()) {\n <div class=\"talos-data-grid-pagination\">\n <div class=\"pagination-left\">\n <span class=\"pagination-info\">\n Showing {{ startRecord() }} to {{ endRecord() }} of {{ totalCount() }} entries\n </span>\n\n @if (pageSizeOptions().length > 1) {\n <div class=\"pagination-size-selector\">\n <span>Rows per page:</span>\n <select\n [value]=\"internalPageSize()\"\n (change)=\"onPageSizeChange($event)\"\n aria-label=\"Select page size\"\n >\n @for (size of pageSizeOptions(); track size) {\n <option [value]=\"size\">{{ size }}</option>\n }\n </select>\n </div>\n }\n </div>\n\n <div class=\"pagination-right\">\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() <= 0\"\n (click)=\"setPage(0)\"\n title=\"First page\"\n aria-label=\"First page\"\n >\n <ng-container *ngComponentOutlet=\"chevronsLeftIcon\" />\n </button>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() <= 0\"\n (click)=\"setPage(internalPageIndex() - 1)\"\n title=\"Previous page\"\n aria-label=\"Previous page\"\n >\n <ng-container *ngComponentOutlet=\"chevronLeftIcon\" />\n </button>\n\n <span class=\"page-indicator\">\n Page {{ internalPageIndex() + 1 }} of {{ totalPages() }}\n </span>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() >= totalPages() - 1\"\n (click)=\"setPage(internalPageIndex() + 1)\"\n title=\"Next page\"\n aria-label=\"Next page\"\n >\n <ng-container *ngComponentOutlet=\"chevronRightIcon\" />\n </button>\n\n <button\n talosButton\n variant=\"ghost\"\n size=\"sm\"\n [iconOnly]=\"true\"\n [disabled]=\"internalPageIndex() >= totalPages() - 1\"\n (click)=\"setPage(totalPages() - 1)\"\n title=\"Last page\"\n aria-label=\"Last page\"\n >\n <ng-container *ngComponentOutlet=\"chevronsRightIcon\" />\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;font-family:var(--talos-font-sans, system-ui, -apple-system, sans-serif);color:var(--talos-text-primary, #0f172a)}.talos-data-grid-container{display:flex;flex-direction:column;background-color:var(--talos-bg-surface, #ffffff);border-radius:var(--talos-radius-lg, 8px);position:relative;width:100%;overflow:hidden}.talos-data-grid-container.is-bordered{border:1px solid var(--talos-border-default, #cbd5e1)}.talos-data-grid-container.is-resizing{cursor:col-resize!important;-webkit-user-select:none!important;user-select:none!important}.talos-data-grid-container.is-resizing *{-webkit-user-select:none!important;user-select:none!important;cursor:col-resize!important}.talos-data-grid-table-wrapper{width:100%;overflow-x:auto;overflow-y:visible;position:relative;scrollbar-width:thin;scrollbar-color:var(--talos-border-default, #cbd5e1) transparent}.talos-data-grid-table-wrapper::-webkit-scrollbar{height:6px;width:6px}.talos-data-grid-table-wrapper::-webkit-scrollbar-thumb{background:var(--talos-border-default, #cbd5e1);border-radius:4px}.talos-data-grid-table{width:100%;min-width:100%;border-collapse:collapse;text-align:left;font-size:var(--talos-font-size-sm, 13px);line-height:var(--talos-line-height-normal, 1.5)}.talos-data-grid-table.has-resizable-columns{table-layout:fixed;width:max-content;min-width:100%}.talos-data-grid-container.density-compact{--grid-header-padding-y: 6px;--grid-header-padding-x: 10px;--grid-cell-padding-y: 5px;--grid-cell-padding-x: 10px;--grid-font-size: 12px;--grid-header-font-size: 11px;--grid-filter-height: 24px}.talos-data-grid-container.density-comfortable{--grid-header-padding-y: 10px;--grid-header-padding-x: 14px;--grid-cell-padding-y: 9px;--grid-cell-padding-x: 14px;--grid-font-size: 13.5px;--grid-header-font-size: 12px;--grid-filter-height: 28px}.talos-data-grid-container.density-spacious{--grid-header-padding-y: 14px;--grid-header-padding-x: 18px;--grid-cell-padding-y: 14px;--grid-cell-padding-x: 18px;--grid-font-size: 14.5px;--grid-header-font-size: 13px;--grid-filter-height: 32px}.talos-data-grid-table thead th{position:relative;background-color:var(--talos-bg-subtle, #f8fafc);color:var(--talos-text-secondary, #475569);font-size:var(--grid-header-font-size, 12px);font-weight:var(--talos-font-weight-semibold, 600);text-transform:uppercase;letter-spacing:.04em;padding:var(--grid-header-padding-y) 8px var(--grid-header-padding-y) var(--grid-header-padding-x);border-bottom:1px solid var(--talos-border-default, #cbd5e1);white-space:nowrap;-webkit-user-select:none;user-select:none;vertical-align:middle;overflow:hidden}.talos-data-grid-table thead th.is-sortable{cursor:pointer;transition:background-color var(--talos-transition, .15s ease)}.talos-data-grid-table thead th.is-sortable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f1f5f9);color:var(--talos-text-primary, #0f172a)}.talos-data-grid-table thead th.is-sorted{color:var(--talos-primary, #2563eb);background-color:var(--talos-primary-subtle-bg, #eff6ff)}.talos-data-grid-table thead th.is-resizable{padding-right:10px}.talos-data-grid-table thead th.is-resizing{background-color:var(--talos-neutral-subtle-bg-hover, #f1f5f9)}.header-content-wrapper{display:flex;align-items:center;gap:4px;width:100%;min-width:0;overflow:hidden}.header-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-tools{display:inline-flex;align-items:center;gap:2px;flex-shrink:0}.sort-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.45;transition:opacity var(--talos-transition, .15s ease),transform .15s ease}.sort-icon-wrapper ::ng-deep svg,.sort-icon-wrapper ::ng-deep .lucide,.sort-icon-wrapper svg,.sort-icon-wrapper .lucide{width:13px!important;height:13px!important;display:block}.is-sortable:hover .sort-icon-wrapper{opacity:.85}.is-sorted .sort-icon-wrapper{opacity:1;color:var(--talos-primary, #2563eb)}.header-sort-btn{width:22px!important;height:22px!important;min-width:22px!important;padding:0!important;border-radius:var(--talos-radius-sm, 4px)!important;border:1px solid transparent!important;background:transparent!important;color:var(--talos-text-muted, #94a3b8)!important;cursor:pointer;opacity:.45;transition:all var(--talos-transition, .15s ease);box-shadow:none!important}.header-sort-btn ::ng-deep svg,.header-sort-btn ::ng-deep .lucide,.header-sort-btn svg,.header-sort-btn .lucide{width:13px!important;height:13px!important;display:block;flex-shrink:0}th:hover .header-sort-btn{opacity:.85}.header-sort-btn:hover{opacity:1;color:var(--talos-text-primary, #0f172a)!important;background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .06))!important}.header-sort-btn.is-sorted{opacity:1;color:var(--talos-primary, #2563eb)!important;background:var(--talos-primary-subtle-bg, #eff6ff)!important}.align-left{text-align:left}.align-left .header-content-wrapper{justify-content:flex-start}.align-center{text-align:center}.align-center .header-content-wrapper{justify-content:center}.align-right{text-align:right}.align-right .header-content-wrapper{justify-content:flex-end}.talos-grid-resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;-webkit-user-select:none;user-select:none;touch-action:none;z-index:2;display:flex;align-items:center;justify-content:center}.talos-grid-resize-handle:after{content:\"\";display:block;width:2px;height:50%;border-radius:1px;background-color:transparent;transition:background-color var(--talos-transition, .15s ease),height var(--talos-transition, .15s ease)}.talos-grid-resize-handle:hover:after,.talos-grid-resize-handle:focus-visible:after,.talos-grid-resize-handle.is-resizing:after{background-color:var(--talos-primary, #2563eb);height:100%}.talos-grid-resize-handle:focus-visible{outline:none}.talos-grid-filter-anchor{position:relative;display:inline-flex;align-items:center}.header-filter-btn{display:inline-flex;align-items:center;justify-content:center;width:22px!important;height:22px!important;min-width:22px!important;padding:0!important;border-radius:var(--talos-radius-sm, 4px)!important;border:1px solid transparent!important;background:transparent!important;color:var(--talos-text-muted, #94a3b8)!important;cursor:pointer;opacity:.5;transition:all var(--talos-transition, .15s ease);box-shadow:none!important}.header-filter-btn ::ng-deep svg,.header-filter-btn ::ng-deep .lucide,.header-filter-btn svg,.header-filter-btn .lucide{width:13px!important;height:13px!important;display:block;flex-shrink:0}th:hover .header-filter-btn{opacity:.85}.header-filter-btn:hover,.header-filter-btn.is-open{opacity:1;color:var(--talos-text-primary, #0f172a)!important;background:var(--talos-neutral-subtle-bg-hover, rgba(0, 0, 0, .06))!important}.header-filter-btn.is-active{opacity:1;color:#fff!important;background:var(--talos-primary, #2563eb)!important;border-color:var(--talos-primary, #2563eb)!important}.talos-data-grid-table tbody tr{border-bottom:1px solid var(--talos-border-subtle, #f1f5f9);transition:background-color var(--talos-transition, .12s ease)}.talos-data-grid-table tbody tr.is-hoverable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f8fafc)}.talos-data-grid-table tbody tr.is-clickable{cursor:pointer}.talos-data-grid-container.is-striped .talos-data-grid-table tbody tr:nth-child(2n){background-color:var(--talos-bg-subtle, #fcfdfe)}.talos-data-grid-container.is-striped .talos-data-grid-table tbody tr:nth-child(2n).is-hoverable:hover{background-color:var(--talos-neutral-subtle-bg-hover, #f8fafc)}.talos-data-grid-table tbody td{padding:var(--grid-cell-padding-y) var(--grid-cell-padding-x);font-size:var(--grid-font-size, 13.5px);color:var(--talos-text-primary, #0f172a);vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.talos-data-grid-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--talos-text-muted, #64748b);text-align:center;gap:12px}.talos-data-grid-empty .empty-icon{opacity:.5;width:36px;height:36px;display:flex;align-items:center;justify-content:center}.talos-data-grid-empty .empty-icon ::ng-deep svg,.talos-data-grid-empty .empty-icon ::ng-deep .lucide,.talos-data-grid-empty .empty-icon svg,.talos-data-grid-empty .empty-icon .lucide{width:36px;height:36px}.talos-data-grid-empty .empty-text{font-size:var(--talos-font-size-base, 14px);font-weight:var(--talos-font-weight-medium, 500)}.talos-data-grid-pagination{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-top:1px solid var(--talos-border-default, #cbd5e1);background-color:var(--talos-bg-surface, #ffffff);gap:12px;flex-wrap:wrap}.pagination-left{display:flex;align-items:center;gap:12px}.pagination-info{font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-muted, #64748b)}.pagination-size-selector{display:flex;align-items:center;gap:6px;font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-secondary, #334155)}.pagination-size-selector select{height:28px;padding:0 8px;font-size:var(--talos-font-size-sm, 13px);border:1px solid var(--talos-border-default, #cbd5e1);border-radius:var(--talos-radius-sm, 4px);background-color:var(--talos-bg-surface, #ffffff);color:var(--talos-text-primary, #0f172a);cursor:pointer;outline:none}.pagination-size-selector select:focus{border-color:var(--talos-border-focus, #2563eb)}.pagination-right{display:flex;align-items:center;gap:4px}.pagination-right ::ng-deep button.talos-btn svg,.pagination-right ::ng-deep button.talos-btn .lucide{width:14px;height:14px}.page-indicator{font-size:var(--talos-font-size-sm, 13px);color:var(--talos-text-secondary, #334155);font-weight:var(--talos-font-weight-medium, 500);padding:0 8px}.talos-data-grid-loading-overlay{position:absolute;inset:0;background:#ffffffb3;display:flex;align-items:center;justify-content:center;z-index:10;-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}.talos-data-grid-loading-overlay ::ng-deep svg,.talos-data-grid-loading-overlay ::ng-deep .lucide,.talos-data-grid-loading-overlay svg,.talos-data-grid-loading-overlay .lucide{width:24px;height:24px;animation:talos-grid-spin .8s linear infinite}@keyframes talos-grid-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1585
- }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], clientSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientSort", required: false }] }], clientPagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientPagination", required: false }] }], clientFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientFilter", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }] } });
1586
-
1587
- class TalosDataGridModule {
1588
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1589
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridModule, imports: [TalosDataGridComponent,
1590
- TalosGridStatusCellComponent,
1591
- TalosGridActionsCellComponent,
1592
- TalosGridFilterDialogComponent,
1593
- TalosGridCellFormatPipe], exports: [TalosDataGridComponent,
1594
- TalosGridStatusCellComponent,
1595
- TalosGridActionsCellComponent,
1596
- TalosGridFilterDialogComponent,
1597
- TalosGridCellFormatPipe] });
1598
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridModule, imports: [TalosDataGridComponent,
1599
- TalosGridStatusCellComponent,
1600
- TalosGridFilterDialogComponent] });
1601
- }
1602
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDataGridModule, decorators: [{
1603
- type: NgModule,
1604
- args: [{
1605
- imports: [
1606
- TalosDataGridComponent,
1607
- TalosGridStatusCellComponent,
1608
- TalosGridActionsCellComponent,
1609
- TalosGridFilterDialogComponent,
1610
- TalosGridCellFormatPipe,
1611
- ],
1612
- exports: [
1613
- TalosDataGridComponent,
1614
- TalosGridStatusCellComponent,
1615
- TalosGridActionsCellComponent,
1616
- TalosGridFilterDialogComponent,
1617
- TalosGridCellFormatPipe,
1618
- ],
1619
- }]
1620
- }] });
1621
-
1622
- /**
1623
- * Generated bundle index. Do not edit.
1624
- */
1625
-
1626
- export { TalosDataGridComponent, TalosDataGridModule, TalosGridActionsCellComponent, TalosGridCellFormatPipe, TalosGridFilterDialogComponent, TalosGridStatusCellComponent };
1627
- //# sourceMappingURL=weeehaoooz-talos-ui-data-display-data-grid.mjs.map