@memberjunction/ng-entity-viewer 6.1.0-edge.5 → 6.1.0-edge.7

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 (48) hide show
  1. package/dist/lib/aggregate-panel/aggregate-panel.component.js +1 -1
  2. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +1 -1
  3. package/dist/lib/confirm-dialog/confirm-dialog.component.js +1 -1
  4. package/dist/lib/duplicate-view-dialog/duplicate-view-dialog.component.js +1 -1
  5. package/dist/lib/entity-cards/entity-cards.component.d.ts.map +1 -1
  6. package/dist/lib/entity-cards/entity-cards.component.js +20 -32
  7. package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
  8. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +50 -1
  9. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  10. package/dist/lib/entity-data-grid/entity-data-grid.component.js +383 -209
  11. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  12. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +1 -1
  13. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +5 -0
  14. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  15. package/dist/lib/entity-viewer/entity-viewer.component.js +51 -28
  16. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  17. package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +1 -1
  18. package/dist/lib/recycle-bin/recycle-bin.component.d.ts.map +1 -1
  19. package/dist/lib/recycle-bin/recycle-bin.component.js +6 -1
  20. package/dist/lib/recycle-bin/recycle-bin.component.js.map +1 -1
  21. package/dist/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.js +1 -1
  22. package/dist/lib/types.d.ts +21 -0
  23. package/dist/lib/types.d.ts.map +1 -1
  24. package/dist/lib/types.js +23 -0
  25. package/dist/lib/types.js.map +1 -1
  26. package/dist/lib/utils/record.util.d.ts.map +1 -1
  27. package/dist/lib/utils/record.util.js +1 -5
  28. package/dist/lib/utils/record.util.js.map +1 -1
  29. package/dist/lib/view-config-panel/view-config-panel.component.d.ts +9 -0
  30. package/dist/lib/view-config-panel/view-config-panel.component.d.ts.map +1 -1
  31. package/dist/lib/view-config-panel/view-config-panel.component.js +35 -11
  32. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  33. package/dist/lib/view-header/view-header.component.js +1 -1
  34. package/dist/lib/view-type-switcher/view-type-switcher.component.js +1 -1
  35. package/dist/lib/view-types/descriptors/map-view-type.d.ts +3 -2
  36. package/dist/lib/view-types/descriptors/map-view-type.d.ts.map +1 -1
  37. package/dist/lib/view-types/descriptors/map-view-type.js +5 -3
  38. package/dist/lib/view-types/descriptors/map-view-type.js.map +1 -1
  39. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +9 -3
  40. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -1
  41. package/dist/lib/view-types/renderers/grid-view-renderer.component.js +24 -20
  42. package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -1
  43. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts +2 -0
  44. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts.map +1 -1
  45. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js +12 -0
  46. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js.map +1 -1
  47. package/dist/lib/view-workspace/view-workspace.component.js +1 -1
  48. package/package.json +25 -25
@@ -3,7 +3,7 @@ import { trigger, transition, style, animate } from '@angular/animations';
3
3
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
4
  import { Subject } from 'rxjs';
5
5
  import { debounceTime, takeUntil } from 'rxjs/operators';
6
- import { RunView, RunViewParams } from '@memberjunction/core';
6
+ import { LogError, RunView, RunViewParams, CoerceImageSrc, ParseCssHexColor, CompositeKey } from '@memberjunction/core';
7
7
  import { UUIDsEqual } from '@memberjunction/global';
8
8
  import { EntityActionEngineBase } from '@memberjunction/actions-base';
9
9
  import { buildPkString, canonicalizeColumnFields, computeFieldsList } from '../utils/record.util';
@@ -23,303 +23,303 @@ import * as i6 from "@memberjunction/ng-entity-action-ux";
23
23
  import * as i7 from "../recycle-bin/recycle-bin-chip.component";
24
24
  const _c0 = ["gridContainer"];
25
25
  function EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
26
- const _r4 = i0.ɵɵgetCurrentView();
26
+ const _r3 = i0.ɵɵgetCurrentView();
27
27
  i0.ɵɵelementStart(0, "button", 38);
28
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.FilterText = ""); });
28
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.FilterText = ""); });
29
29
  i0.ɵɵelement(1, "i", 39);
30
30
  i0.ɵɵelementEnd();
31
31
  } }
32
32
  function EntityDataGridComponent_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
33
- const _r2 = i0.ɵɵgetCurrentView();
33
+ const _r1 = i0.ɵɵgetCurrentView();
34
34
  i0.ɵɵelementStart(0, "div", 14);
35
35
  i0.ɵɵelement(1, "i", 35);
36
36
  i0.ɵɵelementStart(2, "input", 36);
37
- i0.ɵɵlistener("input", function EntityDataGridComponent_Conditional_2_Conditional_2_Template_input_input_2_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FilterText = $event.target.value); });
37
+ i0.ɵɵlistener("input", function EntityDataGridComponent_Conditional_2_Conditional_2_Template_input_input_2_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.FilterText = $event.target.value); });
38
38
  i0.ɵɵelementEnd();
39
39
  i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template, 2, 0, "button", 37);
40
40
  i0.ɵɵelementEnd();
41
41
  } if (rf & 2) {
42
- const ctx_r2 = i0.ɵɵnextContext(2);
42
+ const ctx_r1 = i0.ɵɵnextContext(2);
43
43
  i0.ɵɵadvance(2);
44
- i0.ɵɵproperty("placeholder", ctx_r2.ToolbarConfig.searchPlaceholder || "Search...")("value", ctx_r2.FilterText);
44
+ i0.ɵɵproperty("placeholder", ctx_r1.ToolbarConfig.searchPlaceholder || "Search...")("value", ctx_r1.FilterText);
45
45
  i0.ɵɵadvance();
46
- i0.ɵɵconditional(ctx_r2.FilterText ? 3 : -1);
46
+ i0.ɵɵconditional(ctx_r1.FilterText ? 3 : -1);
47
47
  } }
48
48
  function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
49
49
  i0.ɵɵelement(0, "i");
50
50
  } if (rf & 2) {
51
- const button_r6 = i0.ɵɵnextContext(2).$implicit;
52
- i0.ɵɵclassMap(button_r6.icon);
51
+ const button_r5 = i0.ɵɵnextContext(2).$implicit;
52
+ i0.ɵɵclassMap(button_r5.icon);
53
53
  } }
54
54
  function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
55
55
  i0.ɵɵelementStart(0, "span");
56
56
  i0.ɵɵtext(1);
57
57
  i0.ɵɵelementEnd();
58
58
  } if (rf & 2) {
59
- const button_r6 = i0.ɵɵnextContext(2).$implicit;
59
+ const button_r5 = i0.ɵɵnextContext(2).$implicit;
60
60
  i0.ɵɵadvance();
61
- i0.ɵɵtextInterpolate(button_r6.text);
61
+ i0.ɵɵtextInterpolate(button_r5.text);
62
62
  } }
63
63
  function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
64
- const _r5 = i0.ɵɵgetCurrentView();
64
+ const _r4 = i0.ɵɵgetCurrentView();
65
65
  i0.ɵɵelementStart(0, "button", 41);
66
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const button_r6 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onToolbarButtonClick(button_r6)); });
66
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const button_r5 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onToolbarButtonClick(button_r5)); });
67
67
  i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_1_Template, 1, 2, "i", 42);
68
68
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_2_Template, 2, 1, "span");
69
69
  i0.ɵɵelementEnd();
70
70
  } if (rf & 2) {
71
- const button_r6 = i0.ɵɵnextContext().$implicit;
72
- const ctx_r2 = i0.ɵɵnextContext(2);
73
- i0.ɵɵclassMap(button_r6.cssClass);
74
- i0.ɵɵproperty("disabled", ctx_r2.isButtonDisabled(button_r6))("title", button_r6.tooltip || "");
71
+ const button_r5 = i0.ɵɵnextContext().$implicit;
72
+ const ctx_r1 = i0.ɵɵnextContext(2);
73
+ i0.ɵɵclassMap(button_r5.cssClass);
74
+ i0.ɵɵproperty("disabled", ctx_r1.isButtonDisabled(button_r5))("title", button_r5.tooltip || "");
75
75
  i0.ɵɵadvance();
76
- i0.ɵɵconditional(button_r6.icon ? 1 : -1);
76
+ i0.ɵɵconditional(button_r5.icon ? 1 : -1);
77
77
  i0.ɵɵadvance();
78
- i0.ɵɵconditional(button_r6.text ? 2 : -1);
78
+ i0.ɵɵconditional(button_r5.text ? 2 : -1);
79
79
  } }
80
80
  function EntityDataGridComponent_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
81
81
  i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template, 3, 6, "button", 40);
82
82
  } if (rf & 2) {
83
- const button_r6 = ctx.$implicit;
84
- const ctx_r2 = i0.ɵɵnextContext(2);
85
- i0.ɵɵconditional(button_r6.position !== "right" && ctx_r2.isButtonVisible(button_r6) ? 0 : -1);
83
+ const button_r5 = ctx.$implicit;
84
+ const ctx_r1 = i0.ɵɵnextContext(2);
85
+ i0.ɵɵconditional(button_r5.position !== "right" && ctx_r1.isButtonVisible(button_r5) ? 0 : -1);
86
86
  } }
87
87
  function EntityDataGridComponent_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
88
88
  i0.ɵɵelementStart(0, "span", 16);
89
89
  i0.ɵɵtext(1);
90
90
  i0.ɵɵelementEnd();
91
91
  } if (rf & 2) {
92
- const ctx_r2 = i0.ɵɵnextContext(2);
92
+ const ctx_r1 = i0.ɵɵnextContext(2);
93
93
  i0.ɵɵadvance();
94
- i0.ɵɵtextInterpolate2(" ", ctx_r2.totalRowCount, " ", ctx_r2.totalRowCount === 1 ? "row" : "rows", " ");
94
+ i0.ɵɵtextInterpolate2(" ", ctx_r1.totalRowCount, " ", ctx_r1.totalRowCount === 1 ? "row" : "rows", " ");
95
95
  } }
96
96
  function EntityDataGridComponent_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
97
97
  i0.ɵɵelementStart(0, "span", 17);
98
98
  i0.ɵɵtext(1);
99
99
  i0.ɵɵelementEnd();
100
100
  } if (rf & 2) {
101
- const ctx_r2 = i0.ɵɵnextContext(2);
101
+ const ctx_r1 = i0.ɵɵnextContext(2);
102
102
  i0.ɵɵadvance();
103
- i0.ɵɵtextInterpolate1(" (", ctx_r2.SelectedKeys.length, " selected) ");
103
+ i0.ɵɵtextInterpolate1(" (", ctx_r1.SelectedKeys.length, " selected) ");
104
104
  } }
105
105
  function EntityDataGridComponent_Conditional_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
106
106
  i0.ɵɵelement(0, "mj-recycle-bin-chip", 19);
107
107
  } if (rf & 2) {
108
- const ctx_r2 = i0.ɵɵnextContext(2);
109
- i0.ɵɵproperty("EntityName", ctx_r2.entityInfoName);
108
+ const ctx_r1 = i0.ɵɵnextContext(2);
109
+ i0.ɵɵproperty("EntityName", ctx_r1.entityInfoName);
110
110
  } }
111
111
  function EntityDataGridComponent_Conditional_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
112
- const _r7 = i0.ɵɵgetCurrentView();
112
+ const _r6 = i0.ɵɵgetCurrentView();
113
113
  i0.ɵɵelementStart(0, "button", 43);
114
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onAddClick()); });
114
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onAddClick()); });
115
115
  i0.ɵɵelement(1, "i", 44);
116
116
  i0.ɵɵelementStart(2, "span", 45);
117
117
  i0.ɵɵtext(3, "New");
118
118
  i0.ɵɵelementEnd()();
119
119
  } }
120
120
  function EntityDataGridComponent_Conditional_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
121
- const _r8 = i0.ɵɵgetCurrentView();
121
+ const _r7 = i0.ɵɵgetCurrentView();
122
122
  i0.ɵɵelementStart(0, "button", 46);
123
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onRefreshClick()); });
123
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onRefreshClick()); });
124
124
  i0.ɵɵelement(1, "i", 47);
125
125
  i0.ɵɵelementStart(2, "span", 45);
126
126
  i0.ɵɵtext(3, "Refresh");
127
127
  i0.ɵɵelementEnd()();
128
128
  } if (rf & 2) {
129
- const ctx_r2 = i0.ɵɵnextContext(2);
130
- i0.ɵɵproperty("disabled", ctx_r2.loading);
129
+ const ctx_r1 = i0.ɵɵnextContext(2);
130
+ i0.ɵɵproperty("disabled", ctx_r1.loading);
131
131
  i0.ɵɵadvance();
132
- i0.ɵɵclassProp("fa-spin", ctx_r2.loading);
132
+ i0.ɵɵclassProp("fa-spin", ctx_r1.loading);
133
133
  } }
134
134
  function EntityDataGridComponent_Conditional_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
135
- const _r9 = i0.ɵɵgetCurrentView();
135
+ const _r8 = i0.ɵɵgetCurrentView();
136
136
  i0.ɵɵelementStart(0, "button", 48);
137
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onExportClick()); });
137
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onExportClick()); });
138
138
  i0.ɵɵelement(1, "i", 49);
139
139
  i0.ɵɵelementStart(2, "span", 45);
140
140
  i0.ɵɵtext(3, "Export");
141
141
  i0.ɵɵelementEnd()();
142
142
  } if (rf & 2) {
143
- const ctx_r2 = i0.ɵɵnextContext(2);
144
- i0.ɵɵproperty("disabled", ctx_r2.IsPreparingExport);
143
+ const ctx_r1 = i0.ɵɵnextContext(2);
144
+ i0.ɵɵproperty("disabled", ctx_r1.IsPreparingExport);
145
145
  i0.ɵɵadvance();
146
- i0.ɵɵclassProp("fa-file-excel", !ctx_r2.IsPreparingExport)("fa-spinner", ctx_r2.IsPreparingExport)("fa-spin", ctx_r2.IsPreparingExport);
146
+ i0.ɵɵclassProp("fa-file-excel", !ctx_r1.IsPreparingExport)("fa-spinner", ctx_r1.IsPreparingExport)("fa-spin", ctx_r1.IsPreparingExport);
147
147
  } }
148
148
  function EntityDataGridComponent_Conditional_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
149
- const _r10 = i0.ɵɵgetCurrentView();
149
+ const _r9 = i0.ɵɵgetCurrentView();
150
150
  i0.ɵɵelementStart(0, "button", 50);
151
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onDeleteClick()); });
151
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDeleteClick()); });
152
152
  i0.ɵɵelement(1, "i", 51);
153
153
  i0.ɵɵelementStart(2, "span", 45);
154
154
  i0.ɵɵtext(3, "Delete");
155
155
  i0.ɵɵelementEnd()();
156
156
  } }
157
157
  function EntityDataGridComponent_Conditional_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
158
- const _r11 = i0.ɵɵgetCurrentView();
158
+ const _r10 = i0.ɵɵgetCurrentView();
159
159
  i0.ɵɵelementStart(0, "button", 52);
160
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onCompareClick()); });
160
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onCompareClick()); });
161
161
  i0.ɵɵelement(1, "i", 53);
162
162
  i0.ɵɵelementStart(2, "span", 45);
163
163
  i0.ɵɵtext(3, "Compare");
164
164
  i0.ɵɵelementEnd()();
165
165
  } if (rf & 2) {
166
- const ctx_r2 = i0.ɵɵnextContext(2);
167
- i0.ɵɵproperty("disabled", !ctx_r2.HasMultipleSelection);
166
+ const ctx_r1 = i0.ɵɵnextContext(2);
167
+ i0.ɵɵproperty("disabled", !ctx_r1.HasMultipleSelection);
168
168
  } }
169
169
  function EntityDataGridComponent_Conditional_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
170
- const _r12 = i0.ɵɵgetCurrentView();
170
+ const _r11 = i0.ɵɵgetCurrentView();
171
171
  i0.ɵɵelementStart(0, "button", 54);
172
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onMergeClick()); });
172
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onMergeClick()); });
173
173
  i0.ɵɵelement(1, "i", 55);
174
174
  i0.ɵɵelementStart(2, "span", 45);
175
175
  i0.ɵɵtext(3, "Merge");
176
176
  i0.ɵɵelementEnd()();
177
177
  } if (rf & 2) {
178
- const ctx_r2 = i0.ɵɵnextContext(2);
179
- i0.ɵɵproperty("disabled", !ctx_r2.HasMultipleSelection);
178
+ const ctx_r1 = i0.ɵɵnextContext(2);
179
+ i0.ɵɵproperty("disabled", !ctx_r1.HasMultipleSelection);
180
180
  } }
181
181
  function EntityDataGridComponent_Conditional_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
182
- const _r13 = i0.ɵɵgetCurrentView();
182
+ const _r12 = i0.ɵɵgetCurrentView();
183
183
  i0.ɵɵelementStart(0, "button", 56);
184
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onAddToListClick()); });
184
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onAddToListClick()); });
185
185
  i0.ɵɵelement(1, "i", 49);
186
186
  i0.ɵɵelementStart(2, "span", 45);
187
187
  i0.ɵɵtext(3, "Add to List");
188
188
  i0.ɵɵelementEnd()();
189
189
  } if (rf & 2) {
190
- const ctx_r2 = i0.ɵɵnextContext(2);
191
- i0.ɵɵproperty("title", ctx_r2.HasSelection ? "Add selected records to a list" : "Add all matching records to a list")("disabled", !ctx_r2.HasSelection && !ctx_r2.ExportDataProvider || ctx_r2.IsPreparingAddToList);
190
+ const ctx_r1 = i0.ɵɵnextContext(2);
191
+ i0.ɵɵproperty("title", ctx_r1.HasSelection ? "Add selected records to a list" : "Add all matching records to a list")("disabled", !ctx_r1.HasSelection && !ctx_r1.ExportDataProvider || ctx_r1.IsPreparingAddToList);
192
192
  i0.ɵɵadvance();
193
- i0.ɵɵclassProp("fa-list-check", !ctx_r2.IsPreparingAddToList)("fa-spinner", ctx_r2.IsPreparingAddToList)("fa-spin", ctx_r2.IsPreparingAddToList);
193
+ i0.ɵɵclassProp("fa-list-check", !ctx_r1.IsPreparingAddToList)("fa-spinner", ctx_r1.IsPreparingAddToList)("fa-spin", ctx_r1.IsPreparingAddToList);
194
194
  } }
195
195
  function EntityDataGridComponent_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
196
- const _r14 = i0.ɵɵgetCurrentView();
196
+ const _r13 = i0.ɵɵgetCurrentView();
197
197
  i0.ɵɵelementStart(0, "button", 57);
198
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_17_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onDuplicateSearchClick()); });
198
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_17_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDuplicateSearchClick()); });
199
199
  i0.ɵɵelement(1, "i", 58);
200
200
  i0.ɵɵelementStart(2, "span", 45);
201
201
  i0.ɵɵtext(3, "Find Duplicates");
202
202
  i0.ɵɵelementEnd()();
203
203
  } if (rf & 2) {
204
- const ctx_r2 = i0.ɵɵnextContext(2);
205
- i0.ɵɵproperty("disabled", !ctx_r2.HasMultipleSelection);
204
+ const ctx_r1 = i0.ɵɵnextContext(2);
205
+ i0.ɵɵproperty("disabled", !ctx_r1.HasMultipleSelection);
206
206
  } }
207
207
  function EntityDataGridComponent_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
208
- const _r15 = i0.ɵɵgetCurrentView();
208
+ const _r14 = i0.ɵɵgetCurrentView();
209
209
  i0.ɵɵelementStart(0, "button", 59);
210
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onCommunicationClick()); });
210
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onCommunicationClick()); });
211
211
  i0.ɵɵelement(1, "i", 60);
212
212
  i0.ɵɵelementStart(2, "span", 45);
213
213
  i0.ɵɵtext(3, "Send Message");
214
214
  i0.ɵɵelementEnd()();
215
215
  } if (rf & 2) {
216
- const ctx_r2 = i0.ɵɵnextContext(2);
217
- i0.ɵɵproperty("disabled", !ctx_r2.HasSelection);
216
+ const ctx_r1 = i0.ɵɵnextContext(2);
217
+ i0.ɵɵproperty("disabled", !ctx_r1.HasSelection);
218
218
  } }
219
219
  function EntityDataGridComponent_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
220
- const _r16 = i0.ɵɵgetCurrentView();
220
+ const _r15 = i0.ɵɵgetCurrentView();
221
221
  i0.ɵɵelementStart(0, "button", 61);
222
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onAddClick()); });
222
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onAddClick()); });
223
223
  i0.ɵɵelement(1, "i", 44);
224
224
  i0.ɵɵelementEnd();
225
225
  } }
226
226
  function EntityDataGridComponent_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
227
- const _r17 = i0.ɵɵgetCurrentView();
227
+ const _r16 = i0.ɵɵgetCurrentView();
228
228
  i0.ɵɵelementStart(0, "button", 62);
229
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onRefreshClick()); });
229
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onRefreshClick()); });
230
230
  i0.ɵɵelement(1, "i", 63);
231
231
  i0.ɵɵelementEnd();
232
232
  } if (rf & 2) {
233
- const ctx_r2 = i0.ɵɵnextContext(2);
234
- i0.ɵɵproperty("disabled", ctx_r2.loading);
233
+ const ctx_r1 = i0.ɵɵnextContext(2);
234
+ i0.ɵɵproperty("disabled", ctx_r1.loading);
235
235
  i0.ɵɵadvance();
236
- i0.ɵɵclassProp("fa-spin", ctx_r2.loading);
236
+ i0.ɵɵclassProp("fa-spin", ctx_r1.loading);
237
237
  } }
238
238
  function EntityDataGridComponent_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
239
- const _r18 = i0.ɵɵgetCurrentView();
239
+ const _r17 = i0.ɵɵgetCurrentView();
240
240
  i0.ɵɵelementStart(0, "button", 64);
241
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onDeleteClick()); });
241
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDeleteClick()); });
242
242
  i0.ɵɵelement(1, "i", 51);
243
243
  i0.ɵɵelementEnd();
244
244
  } }
245
245
  function EntityDataGridComponent_Conditional_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
246
- const _r19 = i0.ɵɵgetCurrentView();
246
+ const _r18 = i0.ɵɵgetCurrentView();
247
247
  i0.ɵɵelementStart(0, "button", 65);
248
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_22_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onExportClick()); });
248
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_22_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onExportClick()); });
249
249
  i0.ɵɵelement(1, "i", 66);
250
250
  i0.ɵɵelementEnd();
251
251
  } }
252
252
  function EntityDataGridComponent_Conditional_2_Conditional_23_Template(rf, ctx) { if (rf & 1) {
253
- const _r20 = i0.ɵɵgetCurrentView();
253
+ const _r19 = i0.ɵɵgetCurrentView();
254
254
  i0.ɵɵelementStart(0, "button", 67);
255
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_23_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onColumnChooserClick()); });
255
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_23_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onColumnChooserClick()); });
256
256
  i0.ɵɵelement(1, "i", 68);
257
257
  i0.ɵɵelementEnd();
258
258
  } }
259
259
  function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
260
260
  i0.ɵɵelement(0, "i");
261
261
  } if (rf & 2) {
262
- const button_r22 = i0.ɵɵnextContext(2).$implicit;
263
- i0.ɵɵclassMap(button_r22.icon);
262
+ const button_r21 = i0.ɵɵnextContext(2).$implicit;
263
+ i0.ɵɵclassMap(button_r21.icon);
264
264
  } }
265
265
  function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
266
266
  i0.ɵɵelementStart(0, "span");
267
267
  i0.ɵɵtext(1);
268
268
  i0.ɵɵelementEnd();
269
269
  } if (rf & 2) {
270
- const button_r22 = i0.ɵɵnextContext(2).$implicit;
270
+ const button_r21 = i0.ɵɵnextContext(2).$implicit;
271
271
  i0.ɵɵadvance();
272
- i0.ɵɵtextInterpolate(button_r22.text);
272
+ i0.ɵɵtextInterpolate(button_r21.text);
273
273
  } }
274
274
  function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template(rf, ctx) { if (rf & 1) {
275
- const _r21 = i0.ɵɵgetCurrentView();
275
+ const _r20 = i0.ɵɵgetCurrentView();
276
276
  i0.ɵɵelementStart(0, "button", 41);
277
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r21); const button_r22 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onToolbarButtonClick(button_r22)); });
277
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const button_r21 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onToolbarButtonClick(button_r21)); });
278
278
  i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_1_Template, 1, 2, "i", 42);
279
279
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_2_Template, 2, 1, "span");
280
280
  i0.ɵɵelementEnd();
281
281
  } if (rf & 2) {
282
- const button_r22 = i0.ɵɵnextContext().$implicit;
283
- const ctx_r2 = i0.ɵɵnextContext(2);
284
- i0.ɵɵclassMap(button_r22.cssClass);
285
- i0.ɵɵproperty("disabled", ctx_r2.isButtonDisabled(button_r22))("title", button_r22.tooltip || "");
282
+ const button_r21 = i0.ɵɵnextContext().$implicit;
283
+ const ctx_r1 = i0.ɵɵnextContext(2);
284
+ i0.ɵɵclassMap(button_r21.cssClass);
285
+ i0.ɵɵproperty("disabled", ctx_r1.isButtonDisabled(button_r21))("title", button_r21.tooltip || "");
286
286
  i0.ɵɵadvance();
287
- i0.ɵɵconditional(button_r22.icon ? 1 : -1);
287
+ i0.ɵɵconditional(button_r21.icon ? 1 : -1);
288
288
  i0.ɵɵadvance();
289
- i0.ɵɵconditional(button_r22.text ? 2 : -1);
289
+ i0.ɵɵconditional(button_r21.text ? 2 : -1);
290
290
  } }
291
291
  function EntityDataGridComponent_Conditional_2_For_25_Template(rf, ctx) { if (rf & 1) {
292
292
  i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template, 3, 6, "button", 40);
293
293
  } if (rf & 2) {
294
- const button_r22 = ctx.$implicit;
295
- const ctx_r2 = i0.ɵɵnextContext(2);
296
- i0.ɵɵconditional(button_r22.position === "right" && ctx_r2.isButtonVisible(button_r22) ? 0 : -1);
294
+ const button_r21 = ctx.$implicit;
295
+ const ctx_r1 = i0.ɵɵnextContext(2);
296
+ i0.ɵɵconditional(button_r21.position === "right" && ctx_r1.isButtonVisible(button_r21) ? 0 : -1);
297
297
  } }
298
298
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
299
- const _r24 = i0.ɵɵgetCurrentView();
299
+ const _r23 = i0.ɵɵgetCurrentView();
300
300
  i0.ɵɵelementStart(0, "button", 75);
301
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.onExportClick(); return i0.ɵɵresetView(ctx_r2.closeOverflowMenu()); });
301
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.onExportClick(); return i0.ɵɵresetView(ctx_r1.closeOverflowMenu()); });
302
302
  i0.ɵɵelement(1, "i", 76);
303
303
  i0.ɵɵelementStart(2, "span");
304
304
  i0.ɵɵtext(3, "Export");
305
305
  i0.ɵɵelementEnd()();
306
306
  } }
307
307
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
308
- const _r25 = i0.ɵɵgetCurrentView();
308
+ const _r24 = i0.ɵɵgetCurrentView();
309
309
  i0.ɵɵelementStart(0, "button", 79);
310
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template_button_click_0_listener() { const action_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.onEntityActionClick(action_r26); return i0.ɵɵresetView(ctx_r2.closeOverflowMenu()); });
310
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template_button_click_0_listener() { const action_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.onEntityActionClick(action_r25); return i0.ɵɵresetView(ctx_r1.closeOverflowMenu()); });
311
311
  i0.ɵɵelement(1, "i");
312
312
  i0.ɵɵelementStart(2, "span");
313
313
  i0.ɵɵtext(3);
314
314
  i0.ɵɵelementEnd()();
315
315
  } if (rf & 2) {
316
- const action_r26 = ctx.$implicit;
317
- const ctx_r2 = i0.ɵɵnextContext(5);
318
- i0.ɵɵproperty("disabled", !ctx_r2.isEntityActionEnabled(action_r26));
316
+ const action_r25 = ctx.$implicit;
317
+ const ctx_r1 = i0.ɵɵnextContext(5);
318
+ i0.ɵɵproperty("disabled", !ctx_r1.isEntityActionEnabled(action_r25));
319
319
  i0.ɵɵadvance();
320
- i0.ɵɵclassMap(action_r26.icon || "fa-solid fa-bolt");
320
+ i0.ɵɵclassMap(action_r25.icon || "fa-solid fa-bolt");
321
321
  i0.ɵɵadvance(2);
322
- i0.ɵɵtextInterpolate(action_r26.name);
322
+ i0.ɵɵtextInterpolate(action_r25.name);
323
323
  } }
324
324
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
325
325
  i0.ɵɵelement(0, "div", 74);
@@ -328,26 +328,26 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Cond
328
328
  i0.ɵɵelementEnd();
329
329
  i0.ɵɵrepeaterCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template, 4, 4, "button", 78, i0.ɵɵrepeaterTrackByIdentity);
330
330
  } if (rf & 2) {
331
- const ctx_r2 = i0.ɵɵnextContext(4);
331
+ const ctx_r1 = i0.ɵɵnextContext(4);
332
332
  i0.ɵɵadvance(3);
333
- i0.ɵɵrepeater(ctx_r2.EntityActions);
333
+ i0.ɵɵrepeater(ctx_r1.EntityActions);
334
334
  } }
335
335
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
336
336
  i0.ɵɵelement(0, "div", 74);
337
337
  } }
338
338
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
339
- const _r27 = i0.ɵɵgetCurrentView();
339
+ const _r26 = i0.ɵɵgetCurrentView();
340
340
  i0.ɵɵelementStart(0, "button", 75);
341
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.onColumnChooserClick(); return i0.ɵɵresetView(ctx_r2.closeOverflowMenu()); });
341
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.onColumnChooserClick(); return i0.ɵɵresetView(ctx_r1.closeOverflowMenu()); });
342
342
  i0.ɵɵelement(1, "i", 68);
343
343
  i0.ɵɵelementStart(2, "span");
344
344
  i0.ɵɵtext(3, "Manage Columns");
345
345
  i0.ɵɵelementEnd()();
346
346
  } }
347
347
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
348
- const _r28 = i0.ɵɵgetCurrentView();
348
+ const _r27 = i0.ɵɵgetCurrentView();
349
349
  i0.ɵɵelementStart(0, "button", 75);
350
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r28); const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.onCommunicationClick(); return i0.ɵɵresetView(ctx_r2.closeOverflowMenu()); });
350
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.onCommunicationClick(); return i0.ɵɵresetView(ctx_r1.closeOverflowMenu()); });
351
351
  i0.ɵɵelement(1, "i", 60);
352
352
  i0.ɵɵelementStart(2, "span");
353
353
  i0.ɵɵtext(3, "Send Message");
@@ -357,9 +357,9 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Cond
357
357
  i0.ɵɵelement(0, "div", 74);
358
358
  i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template, 4, 0, "button", 73);
359
359
  } if (rf & 2) {
360
- const ctx_r2 = i0.ɵɵnextContext(4);
360
+ const ctx_r1 = i0.ɵɵnextContext(4);
361
361
  i0.ɵɵadvance();
362
- i0.ɵɵconditional(ctx_r2.showCommunicationInOverflow ? 1 : -1);
362
+ i0.ɵɵconditional(ctx_r1.showCommunicationInOverflow ? 1 : -1);
363
363
  } }
364
364
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
365
365
  i0.ɵɵelementStart(0, "div", 72);
@@ -370,33 +370,33 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Temp
370
370
  i0.ɵɵconditionalCreate(5, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Template, 2, 1);
371
371
  i0.ɵɵelementEnd();
372
372
  } if (rf & 2) {
373
- const ctx_r2 = i0.ɵɵnextContext(3);
373
+ const ctx_r1 = i0.ɵɵnextContext(3);
374
374
  i0.ɵɵproperty("@fadeIn", undefined);
375
375
  i0.ɵɵadvance();
376
- i0.ɵɵconditional(ctx_r2.showExportInOverflow ? 1 : -1);
376
+ i0.ɵɵconditional(ctx_r1.showExportInOverflow ? 1 : -1);
377
377
  i0.ɵɵadvance();
378
- i0.ɵɵconditional(ctx_r2.ShowEntityActionButtons && ctx_r2.EntityActions.length > 0 ? 2 : -1);
378
+ i0.ɵɵconditional(ctx_r1.ShowEntityActionButtons && ctx_r1.EntityActions.length > 0 ? 2 : -1);
379
379
  i0.ɵɵadvance();
380
- i0.ɵɵconditional(ctx_r2.showColumnChooserInOverflow ? 3 : -1);
380
+ i0.ɵɵconditional(ctx_r1.showColumnChooserInOverflow ? 3 : -1);
381
381
  i0.ɵɵadvance();
382
- i0.ɵɵconditional(ctx_r2.showColumnChooserInOverflow ? 4 : -1);
382
+ i0.ɵɵconditional(ctx_r1.showColumnChooserInOverflow ? 4 : -1);
383
383
  i0.ɵɵadvance();
384
- i0.ɵɵconditional(ctx_r2.HasSelection && ctx_r2.hasSelectionDependentOverflowActions ? 5 : -1);
384
+ i0.ɵɵconditional(ctx_r1.HasSelection && ctx_r1.hasSelectionDependentOverflowActions ? 5 : -1);
385
385
  } }
386
386
  function EntityDataGridComponent_Conditional_2_Conditional_26_Template(rf, ctx) { if (rf & 1) {
387
- const _r23 = i0.ɵɵgetCurrentView();
387
+ const _r22 = i0.ɵɵgetCurrentView();
388
388
  i0.ɵɵelementStart(0, "div", 69);
389
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r23); return i0.ɵɵresetView($event.stopPropagation()); });
389
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
390
390
  i0.ɵɵelementStart(1, "button", 70);
391
- i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleOverflowMenu()); });
391
+ i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleOverflowMenu()); });
392
392
  i0.ɵɵelement(2, "i", 71);
393
393
  i0.ɵɵelementEnd();
394
394
  i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Template, 6, 6, "div", 72);
395
395
  i0.ɵɵelementEnd();
396
396
  } if (rf & 2) {
397
- const ctx_r2 = i0.ɵɵnextContext(2);
397
+ const ctx_r1 = i0.ɵɵnextContext(2);
398
398
  i0.ɵɵadvance(3);
399
- i0.ɵɵconditional(ctx_r2.showOverflowMenu ? 3 : -1);
399
+ i0.ɵɵconditional(ctx_r1.showOverflowMenu ? 3 : -1);
400
400
  } }
401
401
  function EntityDataGridComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
402
402
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 13);
@@ -427,58 +427,58 @@ function EntityDataGridComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
427
427
  i0.ɵɵconditionalCreate(26, EntityDataGridComponent_Conditional_2_Conditional_26_Template, 4, 1, "div", 34);
428
428
  i0.ɵɵelementEnd()();
429
429
  } if (rf & 2) {
430
- const ctx_r2 = i0.ɵɵnextContext();
430
+ const ctx_r1 = i0.ɵɵnextContext();
431
431
  i0.ɵɵadvance(2);
432
- i0.ɵɵconditional(ctx_r2.ShowSearch ? 2 : -1);
432
+ i0.ɵɵconditional(ctx_r1.ShowSearch ? 2 : -1);
433
433
  i0.ɵɵadvance();
434
- i0.ɵɵrepeater(ctx_r2.ToolbarConfig.customButtons);
434
+ i0.ɵɵrepeater(ctx_r1.ToolbarConfig.customButtons);
435
435
  i0.ɵɵadvance(3);
436
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showRowCount !== false ? 6 : -1);
436
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showRowCount !== false ? 6 : -1);
437
437
  i0.ɵɵadvance();
438
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showSelectionCount && ctx_r2.SelectedKeys.length > 0 ? 7 : -1);
438
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showSelectionCount && ctx_r1.SelectedKeys.length > 0 ? 7 : -1);
439
439
  i0.ɵɵadvance(2);
440
- i0.ɵɵconditional(ctx_r2.ShowRecycleBin ? 9 : -1);
440
+ i0.ɵɵconditional(ctx_r1.ShowRecycleBin ? 9 : -1);
441
441
  i0.ɵɵadvance();
442
- i0.ɵɵconditional(ctx_r2.ShowNewButton ? 10 : -1);
442
+ i0.ɵɵconditional(ctx_r1.ShowNewButton ? 10 : -1);
443
443
  i0.ɵɵadvance();
444
- i0.ɵɵconditional(ctx_r2.ShowRefreshButton ? 11 : -1);
444
+ i0.ɵɵconditional(ctx_r1.ShowRefreshButton ? 11 : -1);
445
445
  i0.ɵɵadvance();
446
- i0.ɵɵconditional(ctx_r2.ShowExportButton ? 12 : -1);
446
+ i0.ɵɵconditional(ctx_r1.ShowExportButton ? 12 : -1);
447
447
  i0.ɵɵadvance();
448
- i0.ɵɵconditional(ctx_r2.ShowDeleteButton && ctx_r2.HasSelection ? 13 : -1);
448
+ i0.ɵɵconditional(ctx_r1.ShowDeleteButton && ctx_r1.HasSelection ? 13 : -1);
449
449
  i0.ɵɵadvance();
450
- i0.ɵɵconditional(ctx_r2.ShowCompareButton ? 14 : -1);
450
+ i0.ɵɵconditional(ctx_r1.ShowCompareButton ? 14 : -1);
451
451
  i0.ɵɵadvance();
452
- i0.ɵɵconditional(ctx_r2.ShowMergeButton ? 15 : -1);
452
+ i0.ɵɵconditional(ctx_r1.ShowMergeButton ? 15 : -1);
453
453
  i0.ɵɵadvance();
454
- i0.ɵɵconditional(ctx_r2.ShowAddToListButton ? 16 : -1);
454
+ i0.ɵɵconditional(ctx_r1.ShowAddToListButton ? 16 : -1);
455
455
  i0.ɵɵadvance();
456
- i0.ɵɵconditional(ctx_r2.ShowDuplicateSearchButton ? 17 : -1);
456
+ i0.ɵɵconditional(ctx_r1.ShowDuplicateSearchButton ? 17 : -1);
457
457
  i0.ɵɵadvance();
458
- i0.ɵɵconditional(ctx_r2.ShowCommunicationButton ? 18 : -1);
458
+ i0.ɵɵconditional(ctx_r1.ShowCommunicationButton ? 18 : -1);
459
459
  i0.ɵɵadvance();
460
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showAdd && ctx_r2.AllowAdd && !ctx_r2.ShowNewButton ? 19 : -1);
460
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showAdd && ctx_r1.AllowAdd && !ctx_r1.ShowNewButton ? 19 : -1);
461
461
  i0.ɵɵadvance();
462
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showRefresh !== false && !ctx_r2.ShowRefreshButton ? 20 : -1);
462
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showRefresh !== false && !ctx_r1.ShowRefreshButton ? 20 : -1);
463
463
  i0.ɵɵadvance();
464
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showDelete && ctx_r2.AllowDelete && ctx_r2.HasSelection && !ctx_r2.ShowDeleteButton ? 21 : -1);
464
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showDelete && ctx_r1.AllowDelete && ctx_r1.HasSelection && !ctx_r1.ShowDeleteButton ? 21 : -1);
465
465
  i0.ɵɵadvance();
466
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showExport && !ctx_r2.ShowExportButton ? 22 : -1);
466
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showExport && !ctx_r1.ShowExportButton ? 22 : -1);
467
467
  i0.ɵɵadvance();
468
- i0.ɵɵconditional(ctx_r2.ToolbarConfig.showColumnChooser && ctx_r2.AllowColumnToggle ? 23 : -1);
468
+ i0.ɵɵconditional(ctx_r1.ToolbarConfig.showColumnChooser && ctx_r1.AllowColumnToggle ? 23 : -1);
469
469
  i0.ɵɵadvance();
470
- i0.ɵɵrepeater(ctx_r2.ToolbarConfig.customButtons);
470
+ i0.ɵɵrepeater(ctx_r1.ToolbarConfig.customButtons);
471
471
  i0.ɵɵadvance(2);
472
- i0.ɵɵconditional(ctx_r2.hasOverflowMenuItems ? 26 : -1);
472
+ i0.ɵɵconditional(ctx_r1.hasOverflowMenuItems ? 26 : -1);
473
473
  } }
474
474
  function EntityDataGridComponent_Conditional_3_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
475
475
  i0.ɵɵelementStart(0, "div", 82);
476
476
  i0.ɵɵelement(1, "i");
477
477
  i0.ɵɵelementEnd();
478
478
  } if (rf & 2) {
479
- const agg_r29 = i0.ɵɵnextContext().$implicit;
479
+ const agg_r28 = i0.ɵɵnextContext().$implicit;
480
480
  i0.ɵɵadvance();
481
- i0.ɵɵclassMap(agg_r29.icon);
481
+ i0.ɵɵclassMap(agg_r28.icon);
482
482
  } }
483
483
  function EntityDataGridComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
484
484
  i0.ɵɵelementStart(0, "div", 80);
@@ -490,14 +490,14 @@ function EntityDataGridComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf
490
490
  i0.ɵɵtext(6);
491
491
  i0.ɵɵelementEnd()()();
492
492
  } if (rf & 2) {
493
- const agg_r29 = ctx.$implicit;
494
- const ctx_r2 = i0.ɵɵnextContext(2);
493
+ const agg_r28 = ctx.$implicit;
494
+ const ctx_r1 = i0.ɵɵnextContext(2);
495
495
  i0.ɵɵadvance();
496
- i0.ɵɵconditional(agg_r29.icon ? 1 : -1);
496
+ i0.ɵɵconditional(agg_r28.icon ? 1 : -1);
497
497
  i0.ɵɵadvance(3);
498
- i0.ɵɵtextInterpolate(agg_r29.label);
498
+ i0.ɵɵtextInterpolate(agg_r28.label);
499
499
  i0.ɵɵadvance(2);
500
- i0.ɵɵtextInterpolate(ctx_r2.getAggregateValue(agg_r29));
500
+ i0.ɵɵtextInterpolate(ctx_r1.getAggregateValue(agg_r28));
501
501
  } }
502
502
  function EntityDataGridComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
503
503
  i0.ɵɵelementStart(0, "div", 81);
@@ -510,11 +510,11 @@ function EntityDataGridComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
510
510
  i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_3_Conditional_3_Template, 2, 0, "div", 81);
511
511
  i0.ɵɵelementEnd();
512
512
  } if (rf & 2) {
513
- const ctx_r2 = i0.ɵɵnextContext();
513
+ const ctx_r1 = i0.ɵɵnextContext();
514
514
  i0.ɵɵadvance();
515
- i0.ɵɵrepeater(ctx_r2.CardAggregates);
515
+ i0.ɵɵrepeater(ctx_r1.CardAggregates);
516
516
  i0.ɵɵadvance(2);
517
- i0.ɵɵconditional(ctx_r2.AggregatesLoading ? 3 : -1);
517
+ i0.ɵɵconditional(ctx_r1.AggregatesLoading ? 3 : -1);
518
518
  } }
519
519
  function EntityDataGridComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
520
520
  i0.ɵɵelementStart(0, "div", 4);
@@ -522,52 +522,52 @@ function EntityDataGridComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
522
522
  i0.ɵɵelementEnd();
523
523
  } }
524
524
  function EntityDataGridComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
525
- const _r30 = i0.ɵɵgetCurrentView();
525
+ const _r29 = i0.ɵɵgetCurrentView();
526
526
  i0.ɵɵelementStart(0, "mj-empty-state", 88);
527
- i0.ɵɵlistener("Action", function EntityDataGridComponent_Conditional_6_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r30); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Refresh()); });
527
+ i0.ɵɵlistener("Action", function EntityDataGridComponent_Conditional_6_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Refresh()); });
528
528
  i0.ɵɵelementEnd();
529
529
  } if (rf & 2) {
530
- const ctx_r2 = i0.ɵɵnextContext();
531
- i0.ɵɵproperty("Size", ctx_r2.EmptyStateSize)("Message", ctx_r2.errorMessage);
530
+ const ctx_r1 = i0.ɵɵnextContext();
531
+ i0.ɵɵproperty("Size", ctx_r1.EmptyStateSize)("Message", ctx_r1.FriendlyErrorMessage);
532
532
  } }
533
533
  function EntityDataGridComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
534
534
  i0.ɵɵelement(0, "mj-empty-state", 6);
535
535
  } if (rf & 2) {
536
- const ctx_r2 = i0.ɵɵnextContext();
537
- i0.ɵɵproperty("Size", ctx_r2.EmptyStateSize);
536
+ const ctx_r1 = i0.ɵɵnextContext();
537
+ i0.ɵɵproperty("Size", ctx_r1.EmptyStateSize);
538
538
  } }
539
539
  function EntityDataGridComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
540
- const _r31 = i0.ɵɵgetCurrentView();
540
+ const _r30 = i0.ɵɵgetCurrentView();
541
541
  i0.ɵɵelementStart(0, "ag-grid-angular", 89);
542
- i0.ɵɵlistener("gridReady", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_gridReady_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridReady($event)); })("cellClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_cellClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgCellClicked($event)); })("rowClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_rowClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgRowClicked($event)); })("rowDoubleClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_rowDoubleClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgRowDoubleClicked($event)); })("sortChanged", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_sortChanged_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgSortChanged($event)); })("selectionChanged", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_selectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgSelectionChanged($event)); })("columnResized", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_columnResized_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgColumnResized($event)); })("columnMoved", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_columnMoved_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgColumnMoved($event)); });
542
+ i0.ɵɵlistener("gridReady", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_gridReady_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onGridReady($event)); })("cellClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_cellClicked_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgCellClicked($event)); })("rowClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_rowClicked_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgRowClicked($event)); })("rowDoubleClicked", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_rowDoubleClicked_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgRowDoubleClicked($event)); })("sortChanged", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_sortChanged_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgSortChanged($event)); })("selectionChanged", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_selectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgSelectionChanged($event)); })("columnResized", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_columnResized_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgColumnResized($event)); })("columnMoved", function EntityDataGridComponent_Conditional_8_Template_ag_grid_angular_columnMoved_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgColumnMoved($event)); });
543
543
  i0.ɵɵelementEnd();
544
544
  } if (rf & 2) {
545
- const ctx_r2 = i0.ɵɵnextContext();
546
- i0.ɵɵproperty("theme", ctx_r2.agGridTheme)("columnDefs", ctx_r2.agColumnDefs)("rowData", ctx_r2.rowData)("defaultColDef", ctx_r2.defaultColDef)("rowSelection", ctx_r2.agRowSelection)("getRowId", ctx_r2.getRowId)("suppressCellFocus", true)("rowHeight", ctx_r2.RowHeight)("headerHeight", ctx_r2.ShowHeader ? undefined : 0);
545
+ const ctx_r1 = i0.ɵɵnextContext();
546
+ i0.ɵɵproperty("theme", ctx_r1.agGridTheme)("columnDefs", ctx_r1.agColumnDefs)("rowData", ctx_r1.rowData)("defaultColDef", ctx_r1.defaultColDef)("rowSelection", ctx_r1.agRowSelection)("getRowId", ctx_r1.getRowId)("suppressCellFocus", true)("rowHeight", ctx_r1.RowHeight)("headerHeight", ctx_r1.ShowHeader ? undefined : 0);
547
547
  } }
548
548
  function EntityDataGridComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
549
- const _r32 = i0.ɵɵgetCurrentView();
549
+ const _r31 = i0.ɵɵgetCurrentView();
550
550
  i0.ɵɵelementStart(0, "ag-grid-angular", 90);
551
- i0.ɵɵlistener("gridReady", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_gridReady_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridReady($event)); })("cellClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_cellClicked_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgCellClicked($event)); })("rowClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_rowClicked_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgRowClicked($event)); })("rowDoubleClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_rowDoubleClicked_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgRowDoubleClicked($event)); })("sortChanged", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_sortChanged_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgSortChanged($event)); })("selectionChanged", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_selectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgSelectionChanged($event)); })("columnResized", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_columnResized_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgColumnResized($event)); })("columnMoved", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_columnMoved_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgColumnMoved($event)); });
551
+ i0.ɵɵlistener("gridReady", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_gridReady_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onGridReady($event)); })("cellClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_cellClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgCellClicked($event)); })("rowClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_rowClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgRowClicked($event)); })("rowDoubleClicked", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_rowDoubleClicked_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgRowDoubleClicked($event)); })("sortChanged", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_sortChanged_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgSortChanged($event)); })("selectionChanged", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_selectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgSelectionChanged($event)); })("columnResized", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_columnResized_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgColumnResized($event)); })("columnMoved", function EntityDataGridComponent_Conditional_9_Template_ag_grid_angular_columnMoved_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAgColumnMoved($event)); });
552
552
  i0.ɵɵelementEnd();
553
553
  } if (rf & 2) {
554
- const ctx_r2 = i0.ɵɵnextContext();
555
- i0.ɵɵproperty("theme", ctx_r2.agGridTheme)("columnDefs", ctx_r2.agColumnDefs)("defaultColDef", ctx_r2.defaultColDef)("rowSelection", ctx_r2.agRowSelection)("getRowId", ctx_r2.getRowId)("suppressCellFocus", true)("rowHeight", ctx_r2.RowHeight)("headerHeight", ctx_r2.ShowHeader ? undefined : 0)("rowModelType", "infinite")("cacheBlockSize", ctx_r2.CacheBlockSize)("maxBlocksInCache", ctx_r2.MaxBlocksInCache)("infiniteInitialRowCount", 1)("cacheOverflowSize", 2);
554
+ const ctx_r1 = i0.ɵɵnextContext();
555
+ i0.ɵɵproperty("theme", ctx_r1.agGridTheme)("columnDefs", ctx_r1.agColumnDefs)("defaultColDef", ctx_r1.defaultColDef)("rowSelection", ctx_r1.agRowSelection)("getRowId", ctx_r1.getRowId)("suppressCellFocus", true)("rowHeight", ctx_r1.RowHeight)("headerHeight", ctx_r1.ShowHeader ? undefined : 0)("rowModelType", "infinite")("cacheBlockSize", ctx_r1.CacheBlockSize)("maxBlocksInCache", ctx_r1.MaxBlocksInCache)("infiniteInitialRowCount", 1)("cacheOverflowSize", 2);
556
556
  } }
557
557
  function EntityDataGridComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
558
- const _r33 = i0.ɵɵgetCurrentView();
558
+ const _r32 = i0.ɵɵgetCurrentView();
559
559
  i0.ɵɵelementStart(0, "mj-pagination", 91);
560
- i0.ɵɵlistener("PageChange", function EntityDataGridComponent_Conditional_10_Template_mj_pagination_PageChange_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.PageChange.emit($event)); });
560
+ i0.ɵɵlistener("PageChange", function EntityDataGridComponent_Conditional_10_Template_mj_pagination_PageChange_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.PageChange.emit($event)); });
561
561
  i0.ɵɵelementEnd();
562
562
  } if (rf & 2) {
563
- const ctx_r2 = i0.ɵɵnextContext();
564
- i0.ɵɵproperty("TotalRowCount", ctx_r2.totalRowCount)("PageNumber", ctx_r2.PagerPageNumber)("PageSize", ctx_r2.PageSize)("IsLoading", ctx_r2.loading);
563
+ const ctx_r1 = i0.ɵɵnextContext();
564
+ i0.ɵɵproperty("TotalRowCount", ctx_r1.totalRowCount)("PageNumber", ctx_r1.PagerPageNumber)("PageSize", ctx_r1.PageSize)("IsLoading", ctx_r1.loading);
565
565
  } }
566
566
  function EntityDataGridComponent_Conditional_11_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
567
567
  i0.ɵɵelement(0, "i");
568
568
  } if (rf & 2) {
569
- const agg_r34 = i0.ɵɵnextContext().$implicit;
570
- i0.ɵɵclassMap(agg_r34.icon);
569
+ const agg_r33 = i0.ɵɵnextContext().$implicit;
570
+ i0.ɵɵclassMap(agg_r33.icon);
571
571
  } }
572
572
  function EntityDataGridComponent_Conditional_11_For_3_Template(rf, ctx) { if (rf & 1) {
573
573
  i0.ɵɵelementStart(0, "div", 93);
@@ -579,14 +579,14 @@ function EntityDataGridComponent_Conditional_11_For_3_Template(rf, ctx) { if (rf
579
579
  i0.ɵɵtext(5);
580
580
  i0.ɵɵelementEnd()();
581
581
  } if (rf & 2) {
582
- const agg_r34 = ctx.$implicit;
583
- const ctx_r2 = i0.ɵɵnextContext(2);
582
+ const agg_r33 = ctx.$implicit;
583
+ const ctx_r1 = i0.ɵɵnextContext(2);
584
584
  i0.ɵɵadvance();
585
- i0.ɵɵconditional(agg_r34.icon ? 1 : -1);
585
+ i0.ɵɵconditional(agg_r33.icon ? 1 : -1);
586
586
  i0.ɵɵadvance(2);
587
- i0.ɵɵtextInterpolate1("", agg_r34.label, ":");
587
+ i0.ɵɵtextInterpolate1("", agg_r33.label, ":");
588
588
  i0.ɵɵadvance(2);
589
- i0.ɵɵtextInterpolate(ctx_r2.getAggregateValue(agg_r34));
589
+ i0.ɵɵtextInterpolate(ctx_r1.getAggregateValue(agg_r33));
590
590
  } }
591
591
  function EntityDataGridComponent_Conditional_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
592
592
  i0.ɵɵelementStart(0, "div", 94);
@@ -600,20 +600,20 @@ function EntityDataGridComponent_Conditional_11_Template(rf, ctx) { if (rf & 1)
600
600
  i0.ɵɵconditionalCreate(4, EntityDataGridComponent_Conditional_11_Conditional_4_Template, 2, 0, "div", 94);
601
601
  i0.ɵɵelementEnd();
602
602
  } if (rf & 2) {
603
- const ctx_r2 = i0.ɵɵnextContext();
603
+ const ctx_r1 = i0.ɵɵnextContext();
604
604
  i0.ɵɵadvance(2);
605
- i0.ɵɵrepeater(ctx_r2.ColumnAggregates);
605
+ i0.ɵɵrepeater(ctx_r1.ColumnAggregates);
606
606
  i0.ɵɵadvance(2);
607
- i0.ɵɵconditional(ctx_r2.AggregatesLoading ? 4 : -1);
607
+ i0.ɵɵconditional(ctx_r1.AggregatesLoading ? 4 : -1);
608
608
  } }
609
609
  function EntityDataGridComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
610
- const _r35 = i0.ɵɵgetCurrentView();
610
+ const _r34 = i0.ɵɵgetCurrentView();
611
611
  i0.ɵɵelementStart(0, "mj-entity-action-ux-host", 97);
612
- i0.ɵɵlistener("Completed", function EntityDataGridComponent_Conditional_13_Template_mj_entity_action_ux_host_Completed_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnRuntimeDriverCompleted($event)); })("Cancelled", function EntityDataGridComponent_Conditional_13_Template_mj_entity_action_ux_host_Cancelled_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnRuntimeDriverCancelled()); });
612
+ i0.ɵɵlistener("Completed", function EntityDataGridComponent_Conditional_13_Template_mj_entity_action_ux_host_Completed_0_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRuntimeDriverCompleted($event)); })("Cancelled", function EntityDataGridComponent_Conditional_13_Template_mj_entity_action_ux_host_Cancelled_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRuntimeDriverCancelled()); });
613
613
  i0.ɵɵelementEnd();
614
614
  } if (rf & 2) {
615
- const ctx_r2 = i0.ɵɵnextContext();
616
- i0.ɵɵproperty("DriverClass", ctx_r2.ActiveRuntimeDriver.DriverClass)("Context", ctx_r2.ActiveRuntimeDriver.Context);
615
+ const ctx_r1 = i0.ɵɵnextContext();
616
+ i0.ɵɵproperty("DriverClass", ctx_r1.ActiveRuntimeDriver.DriverClass)("Context", ctx_r1.ActiveRuntimeDriver.Context);
617
617
  } }
618
618
  // Register AG Grid modules (required for v34+)
619
619
  ModuleRegistry.registerModules([AllCommunityModule]);
@@ -1802,7 +1802,30 @@ export class EntityDataGridComponent extends BaseAngularComponent {
1802
1802
  }
1803
1803
  // Loading state
1804
1804
  loading = false;
1805
- errorMessage = '';
1805
+ _errorMessage = '';
1806
+ /**
1807
+ * Raw technical error from the last failed load. Kept for callers and the
1808
+ * console; the error STATE shown to users leads with FriendlyErrorMessage.
1809
+ * Setting a non-empty value logs the technical detail.
1810
+ */
1811
+ get errorMessage() {
1812
+ return this._errorMessage;
1813
+ }
1814
+ set errorMessage(value) {
1815
+ this._errorMessage = value;
1816
+ if (value) {
1817
+ LogError(`EntityDataGrid data load failed: ${value}`);
1818
+ }
1819
+ }
1820
+ /**
1821
+ * Human-first message for the error empty-state. Users see what happened and
1822
+ * what to do; the raw error rides along as a de-emphasized parenthetical so a
1823
+ * screenshot still carries the detail support needs.
1824
+ */
1825
+ get FriendlyErrorMessage() {
1826
+ const friendly = 'The server may be busy or briefly unreachable — retrying usually fixes this.';
1827
+ return this._errorMessage ? `${friendly} (Detail: ${this._errorMessage})` : friendly;
1828
+ }
1806
1829
  totalRowCount = 0;
1807
1830
  _loadDataPromise = null;
1808
1831
  // Cleanup
@@ -2120,9 +2143,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2120
2143
  // stale columns from a previously viewed entity leaking into the query.
2121
2144
  // This can happen when user defaults were saved for a different view of
2122
2145
  // the same entity with different columns, or when settings are mismatched.
2123
- const validColumns = this._entityInfo
2124
- ? gridState.columnSettings.filter(col => this._entityInfo.Fields.some(f => f.Name === col.Name))
2125
- : gridState.columnSettings;
2146
+ const validColumns = this.filterToExistingFields(gridState.columnSettings, col => col.Name);
2126
2147
  if (validColumns.length > 0) {
2127
2148
  this._gridState = {
2128
2149
  columnSettings: validColumns,
@@ -2134,9 +2155,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2134
2155
  }
2135
2156
  // Apply sort state if not already set — validate sort fields exist on current entity
2136
2157
  if (this._sortState.length === 0 && gridState.sortSettings?.length) {
2137
- const validSorts = this._entityInfo
2138
- ? gridState.sortSettings.filter(s => this._entityInfo.Fields.some(f => f.Name === s.field))
2139
- : gridState.sortSettings;
2158
+ const validSorts = this.filterToSortableFields(gridState.sortSettings, s => s.field);
2140
2159
  this._sortState = validSorts.map((s, index) => ({
2141
2160
  field: s.field,
2142
2161
  direction: s.dir,
@@ -2219,9 +2238,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2219
2238
  if (sortInfo?.length) {
2220
2239
  // Validate sort fields exist on the current entity to prevent stale
2221
2240
  // sort fields from a previously viewed entity leaking into ORDER BY
2222
- const validSorts = this._entityInfo
2223
- ? sortInfo.filter(s => this._entityInfo.Fields.some(f => f.Name === s.field))
2224
- : sortInfo;
2241
+ const validSorts = this.filterToSortableFields(sortInfo, s => s.field);
2225
2242
  this._sortState = validSorts.map((s, index) => ({
2226
2243
  field: s.field,
2227
2244
  direction: (typeof s.direction === 'string' ? s.direction.toLowerCase() : s.direction === 2 ? 'desc' : 'asc') === 'desc' ? 'desc' : 'asc',
@@ -2235,9 +2252,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2235
2252
  // empty and buildOrderByClause() returns '' — causing the SQL to omit
2236
2253
  // ORDER BY on the first page load.
2237
2254
  // Validate sort fields exist on the current entity
2238
- const validSorts = this._entityInfo
2239
- ? this._gridState.sortSettings.filter(s => this._entityInfo.Fields.some(f => f.Name === s.field))
2240
- : this._gridState.sortSettings;
2255
+ const validSorts = this.filterToSortableFields(this._gridState.sortSettings, s => s.field);
2241
2256
  this._sortState = validSorts.map((sortSetting, index) => ({
2242
2257
  field: sortSetting.field,
2243
2258
  direction: sortSetting.dir,
@@ -2263,9 +2278,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2263
2278
  // Apply sort if present - support multi-column sort
2264
2279
  // Validate sort fields against current entity to prevent stale sort from a previous entity
2265
2280
  if (this._gridState.sortSettings?.length && this.gridApi && !this.gridApi.isDestroyed()) {
2266
- const validSorts = this._entityInfo
2267
- ? this._gridState.sortSettings.filter(s => this._entityInfo.Fields.some(f => f.Name === s.field))
2268
- : this._gridState.sortSettings;
2281
+ const validSorts = this.filterToSortableFields(this._gridState.sortSettings, s => s.field);
2269
2282
  this._sortState = validSorts.map((sortSetting, index) => ({
2270
2283
  field: sortSetting.field,
2271
2284
  direction: sortSetting.dir,
@@ -2403,6 +2416,14 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2403
2416
  * This logic is aligned with MJUserViewEntity.SetDefaultsFromEntity() to ensure
2404
2417
  * consistent column visibility between initial load and saved views.
2405
2418
  */
2419
+ /**
2420
+ * NOTE: field security is deliberately NOT applied here. This decides the column MODEL, and
2421
+ * the user's saved column preference is captured from what ends up rendered — so filtering a
2422
+ * denied field out at this level writes a temporary restriction into a durable preference,
2423
+ * and the column never returns when access is restored. The denial is applied where columns
2424
+ * are RENDERED ({@link buildAgColumnDefs}), and {@link buildCurrentGridState} carries the
2425
+ * hidden entries forward so the saved preference stays complete.
2426
+ */
2406
2427
  shouldShowField(field) {
2407
2428
  // Always exclude system fields
2408
2429
  if (field.Name.startsWith('__mj_'))
@@ -2416,6 +2437,50 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2416
2437
  // ensuring users see the same columns before and after saving a view
2417
2438
  return field.DefaultInView === true;
2418
2439
  }
2440
+ /**
2441
+ * Field names field-level security denies the current user READ on, lowercased — empty when
2442
+ * there is no entity or no resolved user, when the entity has field security switched off,
2443
+ * or when nothing is denied, so callers can treat it as "nothing to filter".
2444
+ *
2445
+ * Deliberately the BULK primitive: `EntityInfo.GetDeniedReadFields` documents that the
2446
+ * per-field form costs `fields x rows` aggregations when called inside a loop, and every
2447
+ * caller here is a loop over fields or saved settings.
2448
+ */
2449
+ deniedReadFieldsFor(entity) {
2450
+ const user = this.ProviderToUse?.CurrentUser;
2451
+ if (!entity || !user) {
2452
+ return new Set();
2453
+ }
2454
+ return entity.GetDeniedReadFields(user);
2455
+ }
2456
+ /**
2457
+ * Drops saved settings naming a field that no longer EXISTS on the current entity — stale
2458
+ * state from another view, or a column the schema lost.
2459
+ *
2460
+ * Deliberately does NOT drop denied fields. A denial is temporary and reversible, so removing
2461
+ * the column here would launder a restriction into the user's saved column PREFERENCE and the
2462
+ * column would not return when access was restored. Field security is applied where the
2463
+ * columns are RENDERED ({@link buildAgColumnDefs}), which hides the column while leaving the
2464
+ * preference that mentions it intact.
2465
+ */
2466
+ filterToExistingFields(items, nameOf) {
2467
+ const entity = this._entityInfo;
2468
+ if (!entity) {
2469
+ return items;
2470
+ }
2471
+ return items.filter(item => entity.Fields.some(f => f.Name === nameOf(item)));
2472
+ }
2473
+ /**
2474
+ * The same existence check, plus dropping fields the user cannot read — for SORT settings
2475
+ * only. A denied field in ORDER BY is rejected outright by the server, so unlike a column it
2476
+ * cannot be carried along harmlessly; the query would fail rather than degrade. A user also
2477
+ * cannot meaningfully sort by a column they cannot see.
2478
+ */
2479
+ filterToSortableFields(items, nameOf) {
2480
+ const denied = this.deniedReadFieldsFor(this._entityInfo);
2481
+ return this.filterToExistingFields(items, nameOf)
2482
+ .filter(item => !denied.has(nameOf(item)?.trim().toLowerCase()));
2483
+ }
2419
2484
  /**
2420
2485
  * Estimate an appropriate column width based on field metadata.
2421
2486
  * Takes into account: metadata DefaultColumnWidth, header text length, data type, and field patterns.
@@ -2568,6 +2633,16 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2568
2633
  else {
2569
2634
  this.agColumnDefs = [];
2570
2635
  }
2636
+ // Field security, applied to EVERY branch above rather than inside each one. This is the
2637
+ // only point all three column sources meet: a saved view's `columnSettings` (the usual path
2638
+ // in the entity browser) and a host-supplied `[Columns]` array both bypass the metadata
2639
+ // filter in shouldShowField(), so gating only there leaves the denied column rendered in
2640
+ // exactly the case that matters most. Runs BEFORE the row-number and filler columns are
2641
+ // appended — those are synthetic and have no entity field to check.
2642
+ const deniedReadFields = this.deniedReadFieldsFor(this._entityInfo);
2643
+ if (deniedReadFields.size > 0) {
2644
+ this.agColumnDefs = this.agColumnDefs.filter(c => !c.field || !deniedReadFields.has(c.field.trim().toLowerCase()));
2645
+ }
2571
2646
  // Add row number column if enabled
2572
2647
  if (this._showRowNumbers && this.agColumnDefs.length > 0) {
2573
2648
  this.agColumnDefs.unshift({
@@ -2887,6 +2962,12 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2887
2962
  (!extendedType && (fieldNameLower.includes('url') ||
2888
2963
  fieldNameLower.includes('website') ||
2889
2964
  fieldNameLower.includes('link')));
2965
+ // Image cells key off ExtendedType (or a User View format override). Field-name
2966
+ // heuristics (PhotoURL/LogoURL) are not used — those columns are classified as
2967
+ // ExtendedType='Image' in metadata.
2968
+ const isImage = customFormat?.type === 'image' ||
2969
+ extendedType === 'image';
2970
+ const isColor = extendedType === 'color';
2890
2971
  // Use ExtendedType='Tel' from metadata, fallback to field name pattern
2891
2972
  const isPhone = extendedType === 'tel' ||
2892
2973
  (!extendedType && (fieldNameLower.includes('phone') ||
@@ -2918,6 +2999,14 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2918
2999
  colDef.cellClass = 'cell-align-right';
2919
3000
  colDef.headerClass = 'header-align-right';
2920
3001
  }
3002
+ if (isImage) {
3003
+ colDef.cellClass = `${colDef.cellClass || ''} mj-grid-image-cell`.trim();
3004
+ colDef.headerClass = `${colDef.headerClass || ''} mj-grid-image-header`.trim();
3005
+ colDef.width = 48;
3006
+ colDef.minWidth = 44;
3007
+ colDef.maxWidth = 56;
3008
+ colDef.resizable = false;
3009
+ }
2921
3010
  // Apply custom header style if provided
2922
3011
  if (customFormat?.headerStyle) {
2923
3012
  const headerStyle = this.buildCssStyle(customFormat.headerStyle);
@@ -2932,6 +3021,27 @@ export class EntityDataGridComponent extends BaseAngularComponent {
2932
3021
  if (params.value === null || params.value === undefined) {
2933
3022
  return '<span class="cell-empty">—</span>';
2934
3023
  }
3024
+ if (isImage) {
3025
+ const raw = String(params.value).trim();
3026
+ const src = CoerceImageSrc(raw);
3027
+ if (src) {
3028
+ const escaped = HighlightUtil.escapeHtml(src);
3029
+ const img = `<img src="${escaped}" alt="" class="cell-image" width="28" height="28" style="width:28px;height:28px;max-width:28px;max-height:28px;object-fit:cover;object-position:center;border-radius:50%;display:block" />`;
3030
+ const inner = src.startsWith('data:')
3031
+ ? img
3032
+ : `<a href="${escaped}" target="_blank" rel="noopener noreferrer" class="cell-image-link" onclick="event.stopPropagation()">${img}</a>`;
3033
+ return this.wrapWithStyle(inner, customFormat?.cellStyle ? this.buildCssStyle(customFormat.cellStyle) : '');
3034
+ }
3035
+ }
3036
+ if (isColor) {
3037
+ const raw = String(params.value).trim();
3038
+ const hex = ParseCssHexColor(raw);
3039
+ const escaped = HighlightUtil.escapeHtml(raw);
3040
+ const swatch = hex
3041
+ ? `<span style="width:14px;height:14px;border-radius:3px;background:${HighlightUtil.escapeHtml(hex)};border:1px solid rgba(0,0,0,.2);display:inline-block;flex-shrink:0"></span>`
3042
+ : '';
3043
+ return this.wrapWithStyle(`<span style="display:inline-flex;align-items:center;gap:6px">${swatch}${escaped}</span>`, customFormat?.cellStyle ? this.buildCssStyle(customFormat.cellStyle) : '');
3044
+ }
2935
3045
  // Handle foreign key fields - render as clickable links
2936
3046
  // Only apply FK rendering if no custom format is specified
2937
3047
  if (isForeignKey && !customFormat && fkField?.RelatedEntityID) {
@@ -4046,6 +4156,69 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4046
4156
  });
4047
4157
  }
4048
4158
  }
4159
+ // Carry forward the settings for columns FIELD SECURITY hid from this user.
4160
+ //
4161
+ // This state is captured from the rendered AG Grid, and a denied column is not rendered —
4162
+ // so without this it would be missing from the captured state, that state is persisted as
4163
+ // the user's column PREFERENCE, and the column is gone permanently. It would not come back
4164
+ // when the denial was lifted, because by then the saved preference genuinely no longer
4165
+ // lists it. A temporary restriction must never be recorded as a durable preference.
4166
+ //
4167
+ // Ordering is intentionally not recomputed: the retained entries keep their previous
4168
+ // orderIndex, so restoring access puts the column back roughly where it was rather than
4169
+ // appending it to the end.
4170
+ const deniedReadFields = this.deniedReadFieldsFor(this._entityInfo);
4171
+ if (deniedReadFields.size > 0) {
4172
+ const captured = new Set(columnSettings.map(c => c.Name.toLowerCase()));
4173
+ // Prefer the settings the user already had; fall back to the column MODEL, which still
4174
+ // lists denied fields, for the case where they are saving grid state for the first time
4175
+ // while the restriction is in force and there is no prior entry to preserve.
4176
+ const priorByName = new Map();
4177
+ for (const prior of this._gridState?.columnSettings ?? []) {
4178
+ priorByName.set(prior.Name.trim().toLowerCase(), prior);
4179
+ }
4180
+ // Position is resolved against the column that preceded it in the PRIOR state, not by its
4181
+ // own old orderIndex: the captured entries were renumbered by render position, so the two
4182
+ // index spaces no longer line up once a hidden column has been removed from the middle.
4183
+ // A fractional index slots the retained column back between its old neighbours; the whole
4184
+ // list is renumbered to integers afterwards.
4185
+ const capturedIndexByName = new Map(columnSettings.map((c, i) => [c.Name.toLowerCase(), i]));
4186
+ const priorOrdered = [...(this._gridState?.columnSettings ?? [])]
4187
+ .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0));
4188
+ const positionFor = (name) => {
4189
+ const priorIndex = priorOrdered.findIndex(c => c.Name.trim().toLowerCase() === name);
4190
+ for (let back = priorIndex - 1; back >= 0; back--) {
4191
+ const anchor = capturedIndexByName.get(priorOrdered[back].Name.toLowerCase());
4192
+ if (anchor !== undefined) {
4193
+ return anchor + 0.5;
4194
+ }
4195
+ }
4196
+ return priorIndex >= 0 ? -0.5 : columnSettings.length;
4197
+ };
4198
+ for (const denied of deniedReadFields) {
4199
+ if (captured.has(denied)) {
4200
+ continue;
4201
+ }
4202
+ const prior = priorByName.get(denied);
4203
+ if (prior) {
4204
+ columnSettings.push({ ...prior, orderIndex: positionFor(denied) });
4205
+ continue;
4206
+ }
4207
+ const modelled = this._columns.find(c => c.field.trim().toLowerCase() === denied);
4208
+ const field = this._entityInfo.Fields.find(f => f.Name.trim().toLowerCase() === denied);
4209
+ if (modelled && field) {
4210
+ columnSettings.push({
4211
+ ID: field.ID,
4212
+ Name: field.Name,
4213
+ DisplayName: field.DisplayNameOrName,
4214
+ hidden: false,
4215
+ orderIndex: columnSettings.length
4216
+ });
4217
+ }
4218
+ }
4219
+ columnSettings.sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0));
4220
+ columnSettings.forEach((c, i) => { c.orderIndex = i; });
4221
+ }
4049
4222
  // Sort by sortIndex to maintain correct multi-sort priority order
4050
4223
  sortedColumns.sort((a, b) => a.sortIndex - b.sortIndex);
4051
4224
  const sortSettings = sortedColumns.map(s => ({
@@ -4571,10 +4744,12 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4571
4744
  /** Builds the driver context from the current entity + selection and mounts the named driver. */
4572
4745
  mountRuntimeDriver(action) {
4573
4746
  const entity = this._entityInfo;
4574
- const pkName = entity.FirstPrimaryKey?.Name;
4575
- const selectedRecordIDs = pkName
4576
- ? this.GetSelectedRows().map(r => String(r[pkName])).filter(id => id.length > 0)
4577
- : [];
4747
+ // The grid's entity is arbitrary (any key column name, possibly composite), so each selected row's
4748
+ // identity is its full primary key in the compact record-id form the record-process engine reads
4749
+ // back with CompositeKey.FromURLSegment — a bare value for single-column keys, `F1|v1||F2|v2` otherwise.
4750
+ const selectedRecordIDs = this.GetSelectedRows()
4751
+ .map(r => CompositeKey.FromEntityRecord(entity, r).ToCompactURLSegment())
4752
+ .filter(id => id.length > 0);
4578
4753
  this.ActiveRuntimeDriver = {
4579
4754
  DriverClass: action.runtimeUXDriverClass,
4580
4755
  Context: {
@@ -4779,8 +4954,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4779
4954
  } if (rf & 2) {
4780
4955
  let _t;
4781
4956
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.gridContainer = _t.first);
4782
- } }, inputs: { Params: "Params", AllowLoad: "AllowLoad", AutoRefreshOnParamsChange: "AutoRefreshOnParamsChange", PaginationMode: "PaginationMode", PageSize: "PageSize", CacheBlockSize: "CacheBlockSize", MaxBlocksInCache: "MaxBlocksInCache", ShowPager: "ShowPager", ExportDataProvider: "ExportDataProvider", ShowRecycleBin: "ShowRecycleBin", PagerPageNumber: "PagerPageNumber", TotalRowCount: "TotalRowCount", Data: "Data", Columns: "Columns", GridState: "GridState", AllowColumnReorder: "AllowColumnReorder", AllowColumnResize: "AllowColumnResize", AllowColumnToggle: "AllowColumnToggle", ShowHeader: "ShowHeader", AllowSorting: "AllowSorting", AllowMultiSort: "AllowMultiSort", ServerSideSorting: "ServerSideSorting", AllowColumnFilters: "AllowColumnFilters", ShowSearch: "ShowSearch", SelectionMode: "SelectionMode", SelectedKeys: "SelectedKeys", KeyField: "KeyField", EditMode: "EditMode", AllowAdd: "AllowAdd", AllowDelete: "AllowDelete", Height: "Height", RowHeight: "RowHeight", WrapText: "WrapText", VirtualScroll: "VirtualScroll", ShowRowNumbers: "ShowRowNumbers", FillWidth: "FillWidth", Striped: "Striped", GridLines: "GridLines", VisualConfig: "VisualConfig", ShowToolbar: "ShowToolbar", ToolbarConfig: "ToolbarConfig", StateKey: "StateKey", AutoPersistState: "AutoPersistState", StatePersistDebounce: "StatePersistDebounce", RefreshDebounce: "RefreshDebounce", FilterText: "FilterText", ShowNewButton: "ShowNewButton", ShowRefreshButton: "ShowRefreshButton", ShowExportButton: "ShowExportButton", ShowDeleteButton: "ShowDeleteButton", ShowCompareButton: "ShowCompareButton", ShowMergeButton: "ShowMergeButton", ShowAddToListButton: "ShowAddToListButton", ShowDuplicateSearchButton: "ShowDuplicateSearchButton", ShowCommunicationButton: "ShowCommunicationButton", AutoNavigate: "AutoNavigate", NavigateOnDoubleClick: "NavigateOnDoubleClick", CreateRecordMode: "CreateRecordMode", NewRecordValues: "NewRecordValues", ShowEntityActionButtons: "ShowEntityActionButtons", EntityActions: "EntityActions", AutoLoadEntityActions: "AutoLoadEntityActions", AggregatesConfig: "AggregatesConfig" }, outputs: { PageChange: "PageChange", AggregatesLoaded: "AggregatesLoaded", BeforeRowSelect: "BeforeRowSelect", AfterRowSelect: "AfterRowSelect", BeforeRowDeselect: "BeforeRowDeselect", AfterRowDeselect: "AfterRowDeselect", SelectionChange: "SelectionChange", BeforeRowClick: "BeforeRowClick", AfterRowClick: "AfterRowClick", BeforeRowDoubleClick: "BeforeRowDoubleClick", AfterRowDoubleClick: "AfterRowDoubleClick", ForeignKeyClick: "ForeignKeyClick", BeforeCellEdit: "BeforeCellEdit", AfterCellEditBegin: "AfterCellEditBegin", BeforeCellEditCommit: "BeforeCellEditCommit", AfterCellEditCommit: "AfterCellEditCommit", BeforeCellEditCancel: "BeforeCellEditCancel", AfterCellEditCancel: "AfterCellEditCancel", BeforeRowSave: "BeforeRowSave", AfterRowSave: "AfterRowSave", BeforeRowDelete: "BeforeRowDelete", AfterRowDelete: "AfterRowDelete", BeforeDataLoad: "BeforeDataLoad", AfterDataLoad: "AfterDataLoad", BeforeDataRefresh: "BeforeDataRefresh", AfterDataRefresh: "AfterDataRefresh", BeforeSort: "BeforeSort", AfterSort: "AfterSort", BeforeColumnReorder: "BeforeColumnReorder", AfterColumnReorder: "AfterColumnReorder", BeforeColumnResize: "BeforeColumnResize", AfterColumnResize: "AfterColumnResize", BeforeColumnVisibilityChange: "BeforeColumnVisibilityChange", AfterColumnVisibilityChange: "AfterColumnVisibilityChange", GridStateChanged: "GridStateChanged", AddRequested: "AddRequested", DeleteRequested: "DeleteRequested", ExportRequested: "ExportRequested", NewButtonClick: "NewButtonClick", RefreshButtonClick: "RefreshButtonClick", ExportButtonClick: "ExportButtonClick", DeleteButtonClick: "DeleteButtonClick", CompareButtonClick: "CompareButtonClick", MergeButtonClick: "MergeButtonClick", AddToListButtonClick: "AddToListButtonClick", DuplicateSearchButtonClick: "DuplicateSearchButtonClick", CommunicationButtonClick: "CommunicationButtonClick", ManageColumnsRequested: "ManageColumnsRequested", NavigationRequested: "NavigationRequested", NewRecordDialogRequested: "NewRecordDialogRequested", NewRecordTabRequested: "NewRecordTabRequested", CompareRecordsRequested: "CompareRecordsRequested", MergeRecordsRequested: "MergeRecordsRequested", CommunicationRequested: "CommunicationRequested", DuplicateSearchRequested: "DuplicateSearchRequested", AddToListRequested: "AddToListRequested", LoadEntityActionsRequested: "LoadEntityActionsRequested", EntityActionRequested: "EntityActionRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 16, consts: [["gridContainer", ""], [1, "mj-grid-toolbar"], [1, "mj-aggregate-cards"], [1, "mj-grid-content"], [1, "mj-grid-loading-overlay"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Could not load data", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 1, "mj-grid-state-fill", 3, "Size", "Message"], ["Icon", "fa-solid fa-inbox", "Title", "No data to display", 1, "mj-grid-state-fill", 3, "Size"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "theme", "columnDefs", "rowData", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "theme", "columnDefs", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight", "rowModelType", "cacheBlockSize", "maxBlocksInCache", "infiniteInitialRowCount", "cacheOverflowSize"], [3, "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "mj-aggregate-summary"], [3, "closed", "visible", "config"], [3, "DriverClass", "Context"], [1, "toolbar-left"], [1, "toolbar-search"], [1, "toolbar-center"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], [3, "EntityName"], ["title", "Create new record", 1, "toolbar-button"], ["title", "Refresh data", 1, "toolbar-button", 3, "disabled"], ["title", "Export", 1, "toolbar-button", 3, "disabled"], ["title", "Delete selected records", 1, "toolbar-button", "toolbar-button-danger"], ["title", "Compare selected records", 1, "toolbar-button", 3, "disabled"], ["title", "Merge selected records", 1, "toolbar-button", 3, "disabled"], [1, "toolbar-button", 3, "title", "disabled"], ["title", "Search for duplicate records", 1, "toolbar-button", 3, "disabled"], ["title", "Send message to selected records", 1, "toolbar-button", 3, "disabled"], ["title", "Add New", 1, "toolbar-button"], ["title", "Refresh", 1, "toolbar-button", 3, "disabled"], ["title", "Delete Selected", 1, "toolbar-button", "toolbar-button-danger"], ["title", "Export", 1, "toolbar-button"], ["title", "Column Chooser", 1, "toolbar-button"], [1, "toolbar-overflow"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", 1, "search-input", 3, "input", "placeholder", "value"], ["aria-label", "Clear search", 1, "search-clear"], ["aria-label", "Clear search", 1, "search-clear", 3, "click"], [1, "fa-solid", "fa-times"], [1, "toolbar-button", 3, "class", "disabled", "title"], [1, "toolbar-button", 3, "click", "disabled", "title"], [3, "class"], ["title", "Create new record", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "button-text"], ["title", "Refresh data", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["title", "Export", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid"], ["title", "Delete selected records", 1, "toolbar-button", "toolbar-button-danger", 3, "click"], [1, "fa-solid", "fa-trash"], ["title", "Compare selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-code-compare"], ["title", "Merge selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-code-merge"], [1, "toolbar-button", 3, "click", "title", "disabled"], ["title", "Search for duplicate records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-magnifying-glass-plus"], ["title", "Send message to selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-envelope"], ["title", "Add New", 1, "toolbar-button", 3, "click"], ["title", "Refresh", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], ["title", "Delete Selected", 1, "toolbar-button", "toolbar-button-danger", 3, "click"], ["title", "Export", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-download"], ["title", "Column Chooser", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-columns"], [1, "toolbar-overflow", 3, "click"], ["title", "More actions", 1, "toolbar-button", "overflow-trigger", 3, "click"], [1, "fa-solid", "fa-ellipsis-vertical"], [1, "overflow-menu"], [1, "overflow-item"], [1, "overflow-divider"], [1, "overflow-item", 3, "click"], [1, "fa-solid", "fa-file-excel"], [1, "overflow-section-label"], [1, "overflow-item", 3, "disabled"], [1, "overflow-item", 3, "click", "disabled"], [1, "aggregate-card"], [1, "aggregate-card-loading"], [1, "aggregate-card-icon"], [1, "aggregate-card-content"], [1, "aggregate-card-label"], [1, "aggregate-card-value"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["text", "Loading..."], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Could not load data", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 1, "mj-grid-state-fill", 3, "Action", "Size", "Message"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "gridReady", "cellClicked", "rowClicked", "rowDoubleClicked", "sortChanged", "selectionChanged", "columnResized", "columnMoved", "theme", "columnDefs", "rowData", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "gridReady", "cellClicked", "rowClicked", "rowDoubleClicked", "sortChanged", "selectionChanged", "columnResized", "columnMoved", "theme", "columnDefs", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight", "rowModelType", "cacheBlockSize", "maxBlocksInCache", "infiniteInitialRowCount", "cacheOverflowSize"], [3, "PageChange", "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "aggregate-summary-content"], [1, "aggregate-summary-item"], [1, "aggregate-loading"], [1, "agg-summary-label"], [1, "agg-summary-value"], [3, "Completed", "Cancelled", "DriverClass", "Context"]], template: function EntityDataGridComponent_Template(rf, ctx) { if (rf & 1) {
4783
- const _r1 = i0.ɵɵgetCurrentView();
4957
+ } }, inputs: { Params: "Params", AllowLoad: "AllowLoad", AutoRefreshOnParamsChange: "AutoRefreshOnParamsChange", PaginationMode: "PaginationMode", PageSize: "PageSize", CacheBlockSize: "CacheBlockSize", MaxBlocksInCache: "MaxBlocksInCache", ShowPager: "ShowPager", ExportDataProvider: "ExportDataProvider", ShowRecycleBin: "ShowRecycleBin", PagerPageNumber: "PagerPageNumber", TotalRowCount: "TotalRowCount", Data: "Data", Columns: "Columns", GridState: "GridState", AllowColumnReorder: "AllowColumnReorder", AllowColumnResize: "AllowColumnResize", AllowColumnToggle: "AllowColumnToggle", ShowHeader: "ShowHeader", AllowSorting: "AllowSorting", AllowMultiSort: "AllowMultiSort", ServerSideSorting: "ServerSideSorting", AllowColumnFilters: "AllowColumnFilters", ShowSearch: "ShowSearch", SelectionMode: "SelectionMode", SelectedKeys: "SelectedKeys", KeyField: "KeyField", EditMode: "EditMode", AllowAdd: "AllowAdd", AllowDelete: "AllowDelete", Height: "Height", RowHeight: "RowHeight", WrapText: "WrapText", VirtualScroll: "VirtualScroll", ShowRowNumbers: "ShowRowNumbers", FillWidth: "FillWidth", Striped: "Striped", GridLines: "GridLines", VisualConfig: "VisualConfig", ShowToolbar: "ShowToolbar", ToolbarConfig: "ToolbarConfig", StateKey: "StateKey", AutoPersistState: "AutoPersistState", StatePersistDebounce: "StatePersistDebounce", RefreshDebounce: "RefreshDebounce", FilterText: "FilterText", ShowNewButton: "ShowNewButton", ShowRefreshButton: "ShowRefreshButton", ShowExportButton: "ShowExportButton", ShowDeleteButton: "ShowDeleteButton", ShowCompareButton: "ShowCompareButton", ShowMergeButton: "ShowMergeButton", ShowAddToListButton: "ShowAddToListButton", ShowDuplicateSearchButton: "ShowDuplicateSearchButton", ShowCommunicationButton: "ShowCommunicationButton", AutoNavigate: "AutoNavigate", NavigateOnDoubleClick: "NavigateOnDoubleClick", CreateRecordMode: "CreateRecordMode", NewRecordValues: "NewRecordValues", ShowEntityActionButtons: "ShowEntityActionButtons", EntityActions: "EntityActions", AutoLoadEntityActions: "AutoLoadEntityActions", AggregatesConfig: "AggregatesConfig" }, outputs: { PageChange: "PageChange", AggregatesLoaded: "AggregatesLoaded", BeforeRowSelect: "BeforeRowSelect", AfterRowSelect: "AfterRowSelect", BeforeRowDeselect: "BeforeRowDeselect", AfterRowDeselect: "AfterRowDeselect", SelectionChange: "SelectionChange", BeforeRowClick: "BeforeRowClick", AfterRowClick: "AfterRowClick", BeforeRowDoubleClick: "BeforeRowDoubleClick", AfterRowDoubleClick: "AfterRowDoubleClick", ForeignKeyClick: "ForeignKeyClick", BeforeCellEdit: "BeforeCellEdit", AfterCellEditBegin: "AfterCellEditBegin", BeforeCellEditCommit: "BeforeCellEditCommit", AfterCellEditCommit: "AfterCellEditCommit", BeforeCellEditCancel: "BeforeCellEditCancel", AfterCellEditCancel: "AfterCellEditCancel", BeforeRowSave: "BeforeRowSave", AfterRowSave: "AfterRowSave", BeforeRowDelete: "BeforeRowDelete", AfterRowDelete: "AfterRowDelete", BeforeDataLoad: "BeforeDataLoad", AfterDataLoad: "AfterDataLoad", BeforeDataRefresh: "BeforeDataRefresh", AfterDataRefresh: "AfterDataRefresh", BeforeSort: "BeforeSort", AfterSort: "AfterSort", BeforeColumnReorder: "BeforeColumnReorder", AfterColumnReorder: "AfterColumnReorder", BeforeColumnResize: "BeforeColumnResize", AfterColumnResize: "AfterColumnResize", BeforeColumnVisibilityChange: "BeforeColumnVisibilityChange", AfterColumnVisibilityChange: "AfterColumnVisibilityChange", GridStateChanged: "GridStateChanged", AddRequested: "AddRequested", DeleteRequested: "DeleteRequested", ExportRequested: "ExportRequested", NewButtonClick: "NewButtonClick", RefreshButtonClick: "RefreshButtonClick", ExportButtonClick: "ExportButtonClick", DeleteButtonClick: "DeleteButtonClick", CompareButtonClick: "CompareButtonClick", MergeButtonClick: "MergeButtonClick", AddToListButtonClick: "AddToListButtonClick", DuplicateSearchButtonClick: "DuplicateSearchButtonClick", CommunicationButtonClick: "CommunicationButtonClick", ManageColumnsRequested: "ManageColumnsRequested", NavigationRequested: "NavigationRequested", NewRecordDialogRequested: "NewRecordDialogRequested", NewRecordTabRequested: "NewRecordTabRequested", CompareRecordsRequested: "CompareRecordsRequested", MergeRecordsRequested: "MergeRecordsRequested", CommunicationRequested: "CommunicationRequested", DuplicateSearchRequested: "DuplicateSearchRequested", AddToListRequested: "AddToListRequested", LoadEntityActionsRequested: "LoadEntityActionsRequested", EntityActionRequested: "EntityActionRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 16, consts: [["gridContainer", ""], [1, "mj-grid-toolbar"], [1, "mj-aggregate-cards"], [1, "mj-grid-content"], [1, "mj-grid-loading-overlay"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load this data", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 1, "mj-grid-state-fill", 3, "Size", "Message"], ["Icon", "fa-solid fa-inbox", "Title", "No data to display", 1, "mj-grid-state-fill", 3, "Size"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "theme", "columnDefs", "rowData", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "theme", "columnDefs", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight", "rowModelType", "cacheBlockSize", "maxBlocksInCache", "infiniteInitialRowCount", "cacheOverflowSize"], [3, "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "mj-aggregate-summary"], [3, "closed", "visible", "config"], [3, "DriverClass", "Context"], [1, "toolbar-left"], [1, "toolbar-search"], [1, "toolbar-center"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], [3, "EntityName"], ["title", "Create new record", 1, "toolbar-button"], ["title", "Refresh data", 1, "toolbar-button", 3, "disabled"], ["title", "Export", 1, "toolbar-button", 3, "disabled"], ["title", "Delete selected records", 1, "toolbar-button", "toolbar-button-danger"], ["title", "Compare selected records", 1, "toolbar-button", 3, "disabled"], ["title", "Merge selected records", 1, "toolbar-button", 3, "disabled"], [1, "toolbar-button", 3, "title", "disabled"], ["title", "Search for duplicate records", 1, "toolbar-button", 3, "disabled"], ["title", "Send message to selected records", 1, "toolbar-button", 3, "disabled"], ["title", "Add New", 1, "toolbar-button"], ["title", "Refresh", 1, "toolbar-button", 3, "disabled"], ["title", "Delete Selected", 1, "toolbar-button", "toolbar-button-danger"], ["title", "Export", 1, "toolbar-button"], ["title", "Column Chooser", 1, "toolbar-button"], [1, "toolbar-overflow"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", 1, "search-input", 3, "input", "placeholder", "value"], ["aria-label", "Clear search", 1, "search-clear"], ["aria-label", "Clear search", 1, "search-clear", 3, "click"], [1, "fa-solid", "fa-times"], [1, "toolbar-button", 3, "class", "disabled", "title"], [1, "toolbar-button", 3, "click", "disabled", "title"], [3, "class"], ["title", "Create new record", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "button-text"], ["title", "Refresh data", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["title", "Export", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid"], ["title", "Delete selected records", 1, "toolbar-button", "toolbar-button-danger", 3, "click"], [1, "fa-solid", "fa-trash"], ["title", "Compare selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-code-compare"], ["title", "Merge selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-code-merge"], [1, "toolbar-button", 3, "click", "title", "disabled"], ["title", "Search for duplicate records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-magnifying-glass-plus"], ["title", "Send message to selected records", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-envelope"], ["title", "Add New", 1, "toolbar-button", 3, "click"], ["title", "Refresh", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], ["title", "Delete Selected", 1, "toolbar-button", "toolbar-button-danger", 3, "click"], ["title", "Export", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-download"], ["title", "Column Chooser", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-columns"], [1, "toolbar-overflow", 3, "click"], ["title", "More actions", 1, "toolbar-button", "overflow-trigger", 3, "click"], [1, "fa-solid", "fa-ellipsis-vertical"], [1, "overflow-menu"], [1, "overflow-item"], [1, "overflow-divider"], [1, "overflow-item", 3, "click"], [1, "fa-solid", "fa-file-excel"], [1, "overflow-section-label"], [1, "overflow-item", 3, "disabled"], [1, "overflow-item", 3, "click", "disabled"], [1, "aggregate-card"], [1, "aggregate-card-loading"], [1, "aggregate-card-icon"], [1, "aggregate-card-content"], [1, "aggregate-card-label"], [1, "aggregate-card-value"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["text", "Loading..."], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load this data", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 1, "mj-grid-state-fill", 3, "Action", "Size", "Message"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "gridReady", "cellClicked", "rowClicked", "rowDoubleClicked", "sortChanged", "selectionChanged", "columnResized", "columnMoved", "theme", "columnDefs", "rowData", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight"], [1, "mj-ag-grid", "ag-theme-alpine", 3, "gridReady", "cellClicked", "rowClicked", "rowDoubleClicked", "sortChanged", "selectionChanged", "columnResized", "columnMoved", "theme", "columnDefs", "defaultColDef", "rowSelection", "getRowId", "suppressCellFocus", "rowHeight", "headerHeight", "rowModelType", "cacheBlockSize", "maxBlocksInCache", "infiniteInitialRowCount", "cacheOverflowSize"], [3, "PageChange", "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "aggregate-summary-content"], [1, "aggregate-summary-item"], [1, "aggregate-loading"], [1, "agg-summary-label"], [1, "agg-summary-value"], [3, "Completed", "Cancelled", "DriverClass", "Context"]], template: function EntityDataGridComponent_Template(rf, ctx) { if (rf & 1) {
4784
4958
  i0.ɵɵelementStart(0, "div", null, 0);
4785
4959
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_Template, 27, 19, "div", 1);
4786
4960
  i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_3_Template, 4, 1, "div", 2);
@@ -4795,7 +4969,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4795
4969
  i0.ɵɵconditionalCreate(11, EntityDataGridComponent_Conditional_11_Template, 5, 1, "div", 10);
4796
4970
  i0.ɵɵelementEnd();
4797
4971
  i0.ɵɵelementStart(12, "mj-export-dialog", 11);
4798
- i0.ɵɵlistener("closed", function EntityDataGridComponent_Template_mj_export_dialog_closed_12_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportDialogClosed($event)); });
4972
+ i0.ɵɵlistener("closed", function EntityDataGridComponent_Template_mj_export_dialog_closed_12_listener($event) { return ctx.onExportDialogClosed($event); });
4799
4973
  i0.ɵɵelementEnd();
4800
4974
  i0.ɵɵconditionalCreate(13, EntityDataGridComponent_Conditional_13_Template, 1, 2, "mj-entity-action-ux-host", 12);
4801
4975
  } if (rf & 2) {
@@ -4823,7 +4997,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4823
4997
  i0.ɵɵproperty("visible", ctx.showExportDialog)("config", ctx.exportDialogConfig);
4824
4998
  i0.ɵɵadvance();
4825
4999
  i0.ɵɵconditional(ctx.ActiveRuntimeDriver ? 13 : -1);
4826
- } }, dependencies: [i2.AgGridAngular, i3.LoadingComponent, i4.PaginationComponent, i1.ExportDialogComponent, i5.MJEmptyStateComponent, i6.EntityActionUXHostComponent, i7.RecycleBinChipComponent], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --grid-border-color: var(--mj-border-default);\n --grid-border-radius: 0px;\n --grid-background: var(--mj-bg-surface);\n\n \n\n --grid-header-bg: var(--mj-bg-surface-card);\n --grid-header-text: var(--mj-text-primary);\n --grid-header-font-weight: 600;\n --grid-header-height: 40px;\n --grid-header-border-color: var(--mj-border-default);\n\n \n\n --grid-row-height: 40px;\n --grid-row-bg: var(--mj-bg-surface);\n --grid-row-bg-alt: var(--mj-bg-surface-card);\n --grid-row-hover-bg: var(--mj-bg-surface-hover);\n --grid-row-selected-bg: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --grid-row-selected-hover-bg: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n\n \n\n --grid-cell-padding: 8px 12px;\n --grid-cell-text: var(--mj-text-primary);\n --grid-cell-border-color: var(--mj-border-subtle);\n\n \n\n --grid-checkbox-color: var(--mj-brand-primary);\n --grid-selection-indicator-color: var(--mj-status-warning);\n\n \n\n --grid-edit-cell-bg: var(--mj-bg-surface);\n --grid-edit-cell-border: var(--mj-brand-primary);\n --grid-edit-cell-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n\n \n\n --grid-sort-indicator-color: var(--mj-brand-primary);\n\n \n\n --grid-toolbar-bg: var(--mj-bg-surface);\n --grid-toolbar-height: 48px;\n --grid-toolbar-border-color: var(--mj-border-default);\n\n \n\n --grid-loading-overlay-bg: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n\n \n\n --grid-empty-text-color: var(--mj-text-disabled);\n --grid-empty-icon-color: var(--mj-border-strong);\n\n display: block;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n\n\n\n\n\n.mj-grid-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--grid-border-color);\n border-radius: var(--grid-border-radius);\n background: var(--grid-background);\n overflow: hidden;\n}\n\n\n\n\n\n\n.mj-grid-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--grid-toolbar-height);\n padding: 0 12px;\n background: var(--grid-toolbar-bg);\n border-bottom: 1px solid var(--grid-toolbar-border-color);\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%], \n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toolbar-center[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.toolbar-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n padding: 6px 30px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-size: 13px;\n width: 200px;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--grid-selection-indicator-color);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.search-clear[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.toolbar-button-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.toolbar-button-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.row-count[_ngcontent-%COMP%], \n.selection-count[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n\n\n\n.mj-grid-content[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n}\n\n.mj-grid-scroll-container[_ngcontent-%COMP%] {\n height: 100%;\n overflow: auto;\n}\n\n\n\n\n\n\n.mj-grid-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--grid-loading-overlay-bg);\n z-index: 10;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.mj-grid-state-fill[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n}\n\n\n\n\n\n\n.mj-grid-header[_ngcontent-%COMP%] {\n display: flex;\n min-height: var(--grid-header-height);\n background: var(--grid-header-bg);\n border-bottom: 2px solid var(--grid-header-border-color);\n position: sticky;\n top: 0;\n z-index: 5;\n}\n\n.mj-grid-header-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n font-weight: var(--grid-header-font-weight);\n color: var(--grid-header-text);\n font-size: 13px;\n user-select: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right: 1px solid var(--grid-cell-border-color);\n flex-shrink: 0;\n}\n\n.mj-grid-header-cell[_ngcontent-%COMP%]:last-child {\n border-right: none;\n}\n\n.mj-grid-header-cell.sortable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.mj-grid-header-cell.sortable[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.header-text[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sort-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 6px;\n color: var(--grid-sort-indicator-color);\n}\n\n.sort-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.sort-index[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 2px;\n font-weight: normal;\n}\n\n\n\n\n\n\n.mj-grid-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n background: var(--grid-row-bg);\n transition: background-color 0.15s;\n cursor: default;\n}\n\n.mj-grid-row[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-alt[_ngcontent-%COMP%] {\n background: var(--grid-row-bg-alt);\n}\n\n.mj-grid-row.grid-row-alt[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-selected[_ngcontent-%COMP%] {\n background: var(--grid-row-selected-bg);\n}\n\n.mj-grid-row.grid-row-selected[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-selected-hover-bg);\n}\n\n.mj-grid-row.grid-row-editing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.mj-grid-row.grid-row-dirty[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n\n\n\n\n\n.mj-grid-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n color: var(--grid-cell-text);\n font-size: 13px;\n overflow: hidden;\n border-right: 1px solid transparent;\n flex-shrink: 0;\n}\n\n.mj-grid-cell[_ngcontent-%COMP%]:last-child {\n border-right: none;\n}\n\n\n\n.grid-lines-horizontal[_ngcontent-%COMP%] .mj-grid-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-vertical[_ngcontent-%COMP%] .mj-grid-cell[_ngcontent-%COMP%] {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both[_ngcontent-%COMP%] .mj-grid-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both[_ngcontent-%COMP%] .mj-grid-cell[_ngcontent-%COMP%] {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n\n\n.mj-grid-cell.align-left[_ngcontent-%COMP%] {\n justify-content: flex-start;\n}\n\n.mj-grid-cell.align-center[_ngcontent-%COMP%] {\n justify-content: center;\n}\n\n.mj-grid-cell.align-right[_ngcontent-%COMP%] {\n justify-content: flex-end;\n}\n\n.cell-content[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.row-number-cell[_ngcontent-%COMP%] {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n background: var(--grid-header-bg);\n}\n\n.checkbox-cell[_ngcontent-%COMP%] {\n width: 40px;\n min-width: 40px;\n max-width: 40px;\n justify-content: center;\n}\n\n.checkbox-cell[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--grid-checkbox-color);\n}\n\n\n\n\n\n\n.mj-grid-virtual-spacer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n\n\n\n@media (max-width: 768px) {\n .mj-grid-toolbar[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n padding: 8px;\n }\n\n .toolbar-search[_ngcontent-%COMP%] {\n order: 3;\n width: 100%;\n margin-top: 8px;\n }\n\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .toolbar-center[_ngcontent-%COMP%] {\n order: 2;\n }\n\n \n\n .toolbar-button[_ngcontent-%COMP%] .button-text[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n\n.toolbar-button[_ngcontent-%COMP%] .button-text[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n\n\n\n.toolbar-overflow[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.overflow-trigger[_ngcontent-%COMP%] {\n padding: 6px 8px !important;\n}\n\n.overflow-trigger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.overflow-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 220px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);\n z-index: 1000;\n overflow: hidden;\n}\n\n.overflow-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n text-align: left;\n gap: 12px;\n transition: background-color 0.15s;\n}\n\n.overflow-item[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n}\n\n.overflow-item[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.overflow-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.overflow-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overflow-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n.overflow-section-label[_ngcontent-%COMP%] {\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n letter-spacing: 0.5px;\n}\n\n\n\n.overflow-item.action-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n\n .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n padding: 0 1px;\n}\n\n\n\n\n\n\n.mj-ag-grid[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n\n\n\n .ag-row-selected {\n box-shadow: inset 4px 0 0 0 var(--mj-status-warning);\n}\n\n\n\n .ag-checkbox-input-wrapper {\n width: 18px;\n height: 18px;\n}\n\n .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n\n\n\n\n\n\n\n.header-style-flat[_ngcontent-%COMP%] .ag-header {\n background: var(--grid-header-bg, var(--mj-bg-surface-card));\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n\n\n.header-style-elevated[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n.header-style-elevated.header-shadow[_ngcontent-%COMP%] .ag-header {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n\n\n.header-style-gradient[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-bg-surface-sunken);\n border-bottom: none;\n}\n\n.header-style-gradient.header-shadow[_ngcontent-%COMP%] .ag-header {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-text-secondary);\n border-bottom: none;\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-cell-text {\n color: var(--mj-text-inverse);\n font-weight: 600;\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-icon {\n color: color-mix(in srgb, var(--mj-text-inverse) 70%, transparent);\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-cell:hover {\n background: color-mix(in srgb, var(--mj-text-inverse) 10%, transparent);\n}\n\n\n\n .ag-header-cell-sorted-asc .ag-icon-asc, \n .ag-header-cell-sorted-desc .ag-icon-desc {\n color: var(--grid-accent-color, var(--grid-sort-indicator-color, var(--mj-brand-primary)));\n}\n\n\n\n\n\n\n\n\n.alternate-rows-subtle[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.015);\n}\n\n.alternate-rows-subtle[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n\n.alternate-rows-medium[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.025);\n}\n\n.alternate-rows-medium[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n\n.alternate-rows-strong[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.alternate-rows-strong[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n\n\n\n\n.hover-transitions[_ngcontent-%COMP%] .ag-row {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n.hover-transitions[_ngcontent-%COMP%] .ag-cell {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n\n\n\n\n\n.cell-padding-compact[_ngcontent-%COMP%] .ag-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-compact[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-normal[_ngcontent-%COMP%] .ag-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-normal[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-comfortable[_ngcontent-%COMP%] .ag-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n.cell-padding-comfortable[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n\n\n\n\n\n\n\n.checkbox-style-rounded[_ngcontent-%COMP%] .ag-checkbox-input-wrapper {\n border-radius: 4px;\n}\n\n.checkbox-style-rounded[_ngcontent-%COMP%] .ag-checkbox-input-wrapper::after {\n border-radius: 3px;\n}\n\n\n\n.checkbox-style-filled[_ngcontent-%COMP%] .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n border-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n.checkbox-style-filled[_ngcontent-%COMP%] .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n\n\n\n\n\n\n\n .cell-align-right {\n text-align: right;\n justify-content: flex-end;\n}\n\n .header-align-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n\n\n .cell-empty {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n\n\n .cell-boolean-true {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n .cell-boolean-false {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n\n\n .cell-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n transition: color 0.15s;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\n\n .cell-link:hover {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n}\n\n\n\n .cell-email {\n font-family: inherit;\n font-size: 13px;\n}\n\n\n\n .cell-fk-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s, text-decoration 0.15s;\n}\n\n .cell-fk-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n .cell-fk-link:active {\n color: var(--mj-brand-primary-active);\n}\n\n\n\n .cell-url {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n font-size: 13px;\n}\n\n\n\n .cell-phone {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.3px;\n}\n\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_skeleton-shimmer {\n 0% {\n background-position: -200px 0;\n }\n 100% {\n background-position: calc(200px + 100%) 0;\n }\n}\n\n.skeleton-row[_ngcontent-%COMP%] {\n display: flex;\n height: 40px;\n align-items: center;\n padding: 0 12px;\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n.skeleton-cell[_ngcontent-%COMP%] {\n height: 16px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n var(--mj-bg-surface-sunken) 0px,\n var(--mj-bg-surface-hover) 40px,\n var(--mj-bg-surface-sunken) 80px\n );\n background-size: 200px 100%;\n animation: _ngcontent-%COMP%_skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-cell-short[_ngcontent-%COMP%] {\n width: 60px;\n}\n\n.skeleton-cell-medium[_ngcontent-%COMP%] {\n width: 120px;\n}\n\n.skeleton-cell-long[_ngcontent-%COMP%] {\n width: 180px;\n}\n\n\n\n .ag-header-select-all {\n margin-right: 0;\n}\n\n\n\n\n\n\n .ag-theme-alpine .ag-row {\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n .ag-theme-alpine .ag-row:last-child {\n border-bottom: none;\n}\n\n\n\n\n\n\n .ag-theme-alpine .ag-cell-focus {\n border: none !important;\n outline: none !important;\n}\n\n .ag-theme-alpine .ag-header-cell:focus {\n outline: 2px solid var(--grid-accent-color, var(--mj-brand-primary));\n outline-offset: -2px;\n}\n\n\n\n\n\n\n .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n\n\n\n .ag-theme-alpine .ag-pinned-left-cols-container {\n border-right: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n .ag-theme-alpine .ag-pinned-right-cols-container {\n border-left: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n\n\n\n\n\n .ag-theme-alpine .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n .ag-theme-alpine .ag-header-cell:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n .ag-theme-alpine .ag-header-cell-sortable:hover .ag-header-cell-label {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n}\n\n\n\n .ag-theme-alpine .ag-sort-indicator-icon {\n transition: transform 0.2s ease;\n}\n\n .ag-theme-alpine .ag-header-cell:hover .ag-sort-indicator-icon {\n transform: scale(1.1);\n}\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-brand-primary);\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-status-error);\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc .ag-header-cell-text {\n color: var(--mj-brand-primary) !important;\n font-weight: 700 !important;\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc .ag-header-cell-text {\n color: var(--mj-status-error) !important;\n font-weight: 700 !important;\n}\n\n\n\n\n\n[_nghost-%COMP%] .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n\n\n[_nghost-%COMP%] .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n[_nghost-%COMP%] .ag-sort-ascending-icon .ag-icon, \n[_nghost-%COMP%] .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-brand-primary) !important;\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc .ag-sort-order {\n color: var(--mj-status-error) !important;\n}\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n[_nghost-%COMP%] .ag-header-cell-sortable:hover .ag-header-cell-text {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n\n.mj-aggregate-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n min-height: 44px;\n}\n\n.aggregate-summary-content[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n align-items: center;\n}\n\n.aggregate-summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n}\n\n.aggregate-summary-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.agg-summary-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.agg-summary-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n.aggregate-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n\n\n\n.mj-aggregate-cards[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.aggregate-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n min-width: 140px;\n transition: all 0.15s ease;\n}\n\n.aggregate-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);\n}\n\n.aggregate-card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.aggregate-card-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.aggregate-card-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.aggregate-card-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.aggregate-card-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-card-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n\n\n\n\n\n\n\n .cell-wrap-text {\n white-space: normal !important;\n word-wrap: break-word;\n line-height: 1.4;\n padding-top: 8px !important;\n padding-bottom: 8px !important;\n}\n\n\n\n .ag-cell.cell-wrap-text {\n overflow: visible;\n text-overflow: clip;\n}\n\n\n\n .ag-row[style*=\"auto-height\"] {\n min-height: 40px;\n}\n\n\n\n\n\n\n\n\n\n\n .ag-header-cell.mj-grid-filler-header, \n .ag-cell.mj-grid-filler-cell {\n border-left: none !important;\n border-right: none !important;\n cursor: default;\n}\n\n\n\n\n\n\n .ag-header-cell.mj-grid-filler-header:hover {\n background-color: transparent !important;\n}"], data: { animation: [
5000
+ } }, dependencies: [i2.AgGridAngular, i3.LoadingComponent, i4.PaginationComponent, i1.ExportDialogComponent, i5.MJEmptyStateComponent, i6.EntityActionUXHostComponent, i7.RecycleBinChipComponent], styles: ["\n\n\n\n[_nghost-%COMP%] {\n \n --grid-border-color: var(--mj-border-default);\n --grid-border-radius: 0px;\n --grid-background: var(--mj-bg-surface);\n\n \n --grid-header-bg: var(--mj-bg-surface-card);\n --grid-header-text: var(--mj-text-primary);\n --grid-header-font-weight: 600;\n --grid-header-height: 40px;\n --grid-header-border-color: var(--mj-border-default);\n\n \n --grid-row-height: 40px;\n --grid-row-bg: var(--mj-bg-surface);\n --grid-row-bg-alt: var(--mj-bg-surface-card);\n --grid-row-hover-bg: var(--mj-bg-surface-hover);\n --grid-row-selected-bg: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --grid-row-selected-hover-bg: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n\n \n --grid-cell-padding: 8px 12px;\n --grid-cell-text: var(--mj-text-primary);\n --grid-cell-border-color: var(--mj-border-subtle);\n\n \n --grid-checkbox-color: var(--mj-brand-primary);\n --grid-selection-indicator-color: var(--mj-status-warning);\n\n \n --grid-edit-cell-bg: var(--mj-bg-surface);\n --grid-edit-cell-border: var(--mj-brand-primary);\n --grid-edit-cell-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n\n \n --grid-sort-indicator-color: var(--mj-brand-primary);\n\n \n --grid-toolbar-bg: var(--mj-bg-surface);\n --grid-toolbar-height: 48px;\n --grid-toolbar-border-color: var(--mj-border-default);\n\n \n --grid-loading-overlay-bg: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n\n \n --grid-empty-text-color: var(--mj-text-disabled);\n --grid-empty-icon-color: var(--mj-border-strong);\n\n display: block;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n\n\n\n\n.mj-grid-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--grid-border-color);\n border-radius: var(--grid-border-radius);\n background: var(--grid-background);\n overflow: hidden;\n}\n\n\n\n\n\n.mj-grid-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--grid-toolbar-height);\n padding: 0 12px;\n background: var(--grid-toolbar-bg);\n border-bottom: 1px solid var(--grid-toolbar-border-color);\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%], \n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toolbar-center[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.toolbar-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n padding: 6px 30px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-size: 13px;\n width: 200px;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--grid-selection-indicator-color);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.search-clear[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.toolbar-button-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.toolbar-button-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.row-count[_ngcontent-%COMP%], \n.selection-count[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n\n\n.mj-grid-content[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n}\n\n.mj-grid-scroll-container[_ngcontent-%COMP%] {\n height: 100%;\n overflow: auto;\n}\n\n\n\n\n\n.mj-grid-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--grid-loading-overlay-bg);\n z-index: 10;\n}\n\n\n\n\n\n\n\n\n\n\n\n.mj-grid-state-fill[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n}\n\n\n\n\n\n.mj-grid-header[_ngcontent-%COMP%] {\n display: flex;\n min-height: var(--grid-header-height);\n background: var(--grid-header-bg);\n border-bottom: 2px solid var(--grid-header-border-color);\n position: sticky;\n top: 0;\n z-index: 5;\n}\n\n.mj-grid-header-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n font-weight: var(--grid-header-font-weight);\n color: var(--grid-header-text);\n font-size: 13px;\n user-select: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right: 1px solid var(--grid-cell-border-color);\n flex-shrink: 0;\n}\n\n.mj-grid-header-cell[_ngcontent-%COMP%]:last-child {\n border-right: none;\n}\n\n.mj-grid-header-cell.sortable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.mj-grid-header-cell.sortable[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.header-text[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sort-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-left: 6px;\n color: var(--grid-sort-indicator-color);\n}\n\n.sort-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.sort-index[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 2px;\n font-weight: normal;\n}\n\n\n\n\n\n.mj-grid-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n background: var(--grid-row-bg);\n transition: background-color 0.15s;\n cursor: default;\n}\n\n.mj-grid-row[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-alt[_ngcontent-%COMP%] {\n background: var(--grid-row-bg-alt);\n}\n\n.mj-grid-row.grid-row-alt[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-selected[_ngcontent-%COMP%] {\n background: var(--grid-row-selected-bg);\n}\n\n.mj-grid-row.grid-row-selected[_ngcontent-%COMP%]:hover {\n background: var(--grid-row-selected-hover-bg);\n}\n\n.mj-grid-row.grid-row-editing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.mj-grid-row.grid-row-dirty[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n\n\n\n\n.mj-grid-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n color: var(--grid-cell-text);\n font-size: 13px;\n overflow: hidden;\n border-right: 1px solid transparent;\n flex-shrink: 0;\n}\n\n.mj-grid-cell[_ngcontent-%COMP%]:last-child {\n border-right: none;\n}\n\n\n.grid-lines-horizontal[_ngcontent-%COMP%] .mj-grid-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-vertical[_ngcontent-%COMP%] .mj-grid-cell[_ngcontent-%COMP%] {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both[_ngcontent-%COMP%] .mj-grid-row[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both[_ngcontent-%COMP%] .mj-grid-cell[_ngcontent-%COMP%] {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n\n.mj-grid-cell.align-left[_ngcontent-%COMP%] {\n justify-content: flex-start;\n}\n\n.mj-grid-cell.align-center[_ngcontent-%COMP%] {\n justify-content: center;\n}\n\n.mj-grid-cell.align-right[_ngcontent-%COMP%] {\n justify-content: flex-end;\n}\n\n.cell-content[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.row-number-cell[_ngcontent-%COMP%] {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n background: var(--grid-header-bg);\n}\n\n.checkbox-cell[_ngcontent-%COMP%] {\n width: 40px;\n min-width: 40px;\n max-width: 40px;\n justify-content: center;\n}\n\n.checkbox-cell[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--grid-checkbox-color);\n}\n\n\n\n\n\n.mj-grid-virtual-spacer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .mj-grid-toolbar[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n padding: 8px;\n }\n\n .toolbar-search[_ngcontent-%COMP%] {\n order: 3;\n width: 100%;\n margin-top: 8px;\n }\n\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .toolbar-center[_ngcontent-%COMP%] {\n order: 2;\n }\n\n \n .toolbar-button[_ngcontent-%COMP%] .button-text[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n.toolbar-button[_ngcontent-%COMP%] .button-text[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n\n\n.toolbar-overflow[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.overflow-trigger[_ngcontent-%COMP%] {\n padding: 6px 8px !important;\n}\n\n.overflow-trigger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.overflow-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 220px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);\n z-index: 1000;\n overflow: hidden;\n}\n\n.overflow-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n text-align: left;\n gap: 12px;\n transition: background-color 0.15s;\n}\n\n.overflow-item[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n}\n\n.overflow-item[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.overflow-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.overflow-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.overflow-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n.overflow-section-label[_ngcontent-%COMP%] {\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n letter-spacing: 0.5px;\n}\n\n\n.overflow-item.action-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n padding: 0 1px;\n}\n\n\n\n\n\n.mj-ag-grid[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n\n .ag-row-selected {\n box-shadow: inset 4px 0 0 0 var(--mj-status-warning);\n}\n\n\n .ag-checkbox-input-wrapper {\n width: 18px;\n height: 18px;\n}\n\n .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n\n\n\n\n\n.header-style-flat[_ngcontent-%COMP%] .ag-header {\n background: var(--grid-header-bg, var(--mj-bg-surface-card));\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n\n.header-style-elevated[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n.header-style-elevated.header-shadow[_ngcontent-%COMP%] .ag-header {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n\n.header-style-gradient[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-bg-surface-sunken);\n border-bottom: none;\n}\n\n.header-style-gradient.header-shadow[_ngcontent-%COMP%] .ag-header {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header {\n background: var(--mj-text-secondary);\n border-bottom: none;\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-cell-text {\n color: var(--mj-text-inverse);\n font-weight: 600;\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-icon {\n color: color-mix(in srgb, var(--mj-text-inverse) 70%, transparent);\n}\n\n.header-style-bold[_ngcontent-%COMP%] .ag-header-cell:hover {\n background: color-mix(in srgb, var(--mj-text-inverse) 10%, transparent);\n}\n\n\n .ag-header-cell-sorted-asc .ag-icon-asc, \n .ag-header-cell-sorted-desc .ag-icon-desc {\n color: var(--grid-accent-color, var(--grid-sort-indicator-color, var(--mj-brand-primary)));\n}\n\n\n\n\n\n\n.alternate-rows-subtle[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.015);\n}\n\n.alternate-rows-subtle[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n.alternate-rows-medium[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.025);\n}\n\n.alternate-rows-medium[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n.alternate-rows-strong[_ngcontent-%COMP%] .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.alternate-rows-strong[_ngcontent-%COMP%] .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n\n\n\n\n.hover-transitions[_ngcontent-%COMP%] .ag-row {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n.hover-transitions[_ngcontent-%COMP%] .ag-cell {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n\n\n\n\n.cell-padding-compact[_ngcontent-%COMP%] .ag-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-compact[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-normal[_ngcontent-%COMP%] .ag-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-normal[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-comfortable[_ngcontent-%COMP%] .ag-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n.cell-padding-comfortable[_ngcontent-%COMP%] .ag-header-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n\n\n\n\n\n.checkbox-style-rounded[_ngcontent-%COMP%] .ag-checkbox-input-wrapper {\n border-radius: 4px;\n}\n\n.checkbox-style-rounded[_ngcontent-%COMP%] .ag-checkbox-input-wrapper::after {\n border-radius: 3px;\n}\n\n\n.checkbox-style-filled[_ngcontent-%COMP%] .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n border-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n.checkbox-style-filled[_ngcontent-%COMP%] .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n\n\n\n\n\n .cell-align-right {\n text-align: right;\n justify-content: flex-end;\n}\n\n .header-align-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n\n .cell-empty {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n\n .cell-boolean-true {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n .cell-boolean-false {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n\n .cell-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n transition: color 0.15s;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\n\n .cell-link:hover {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n}\n\n\n .cell-email {\n font-family: inherit;\n font-size: 13px;\n}\n\n\n .cell-fk-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s, text-decoration 0.15s;\n}\n\n .cell-fk-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n .cell-fk-link:active {\n color: var(--mj-brand-primary-active);\n}\n\n\n .cell-url {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n font-size: 13px;\n}\n\n\n .cell-phone {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.3px;\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_skeleton-shimmer {\n 0% {\n background-position: -200px 0;\n }\n 100% {\n background-position: calc(200px + 100%) 0;\n }\n}\n\n.skeleton-row[_ngcontent-%COMP%] {\n display: flex;\n height: 40px;\n align-items: center;\n padding: 0 12px;\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n.skeleton-cell[_ngcontent-%COMP%] {\n height: 16px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n var(--mj-bg-surface-sunken) 0px,\n var(--mj-bg-surface-hover) 40px,\n var(--mj-bg-surface-sunken) 80px\n );\n background-size: 200px 100%;\n animation: _ngcontent-%COMP%_skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-cell-short[_ngcontent-%COMP%] {\n width: 60px;\n}\n\n.skeleton-cell-medium[_ngcontent-%COMP%] {\n width: 120px;\n}\n\n.skeleton-cell-long[_ngcontent-%COMP%] {\n width: 180px;\n}\n\n\n .ag-header-select-all {\n margin-right: 0;\n}\n\n\n\n\n\n .ag-theme-alpine .ag-row {\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n .ag-theme-alpine .ag-row:last-child {\n border-bottom: none;\n}\n\n\n\n\n\n .ag-theme-alpine .ag-cell-focus {\n border: none !important;\n outline: none !important;\n}\n\n .ag-theme-alpine .ag-header-cell:focus {\n outline: 2px solid var(--grid-accent-color, var(--mj-brand-primary));\n outline-offset: -2px;\n}\n\n\n\n\n\n .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n\n\n .ag-theme-alpine .ag-pinned-left-cols-container {\n border-right: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n .ag-theme-alpine .ag-pinned-right-cols-container {\n border-left: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n\n\n\n\n .ag-theme-alpine .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n .ag-theme-alpine .ag-header-cell:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n .ag-theme-alpine .ag-header-cell-sortable:hover .ag-header-cell-label {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n}\n\n\n .ag-theme-alpine .ag-sort-indicator-icon {\n transition: transform 0.2s ease;\n}\n\n .ag-theme-alpine .ag-header-cell:hover .ag-sort-indicator-icon {\n transform: scale(1.1);\n}\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-brand-primary);\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-status-error);\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-asc .ag-header-cell-text {\n color: var(--mj-brand-primary) !important;\n font-weight: 700 !important;\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc .ag-header-cell-text {\n color: var(--mj-status-error) !important;\n font-weight: 700 !important;\n}\n\n\n\n[_nghost-%COMP%] .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n\n[_nghost-%COMP%] .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n[_nghost-%COMP%] .ag-sort-ascending-icon .ag-icon, \n[_nghost-%COMP%] .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n\n\n\n\n[_nghost-%COMP%] .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-brand-primary) !important;\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sorted-desc .ag-sort-order {\n color: var(--mj-status-error) !important;\n}\n\n\n[_nghost-%COMP%] .ag-header-cell-sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n[_nghost-%COMP%] .ag-header-cell-sortable:hover .ag-header-cell-text {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n.mj-aggregate-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n min-height: 44px;\n}\n\n.aggregate-summary-content[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n align-items: center;\n}\n\n.aggregate-summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n}\n\n.aggregate-summary-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.agg-summary-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.agg-summary-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n.aggregate-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n\n\n.mj-aggregate-cards[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.aggregate-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n min-width: 140px;\n transition: all 0.15s ease;\n}\n\n.aggregate-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);\n}\n\n.aggregate-card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.aggregate-card-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.aggregate-card-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.aggregate-card-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.aggregate-card-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-card-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n\n\n\n\n\n .cell-wrap-text {\n white-space: normal !important;\n word-wrap: break-word;\n line-height: 1.4;\n padding-top: 8px !important;\n padding-bottom: 8px !important;\n}\n\n\n .ag-cell.cell-wrap-text {\n overflow: visible;\n text-overflow: clip;\n}\n\n\n .ag-row[style*=\"auto-height\"] {\n min-height: 40px;\n}\n\n\n\n\n\n\n\n\n\n .ag-header-cell.mj-grid-filler-header, \n .ag-cell.mj-grid-filler-cell {\n border-left: none !important;\n border-right: none !important;\n cursor: default;\n}\n\n\n\n\n\n .ag-header-cell.mj-grid-filler-header:hover {\n background-color: transparent !important;\n}\n\n\n\n .ag-cell.mj-grid-image-cell {\n display: flex !important;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 4px !important;\n}\n .ag-header-cell.mj-grid-image-header .ag-header-cell-label {\n justify-content: center;\n}\n .cell-image-link {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n overflow: hidden;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n .cell-image {\n width: 100%;\n height: 100%;\n max-width: 28px;\n max-height: 28px;\n object-fit: cover;\n object-position: center;\n display: block;\n}"], data: { animation: [
4827
5001
  trigger('fadeIn', [
4828
5002
  transition(':enter', [
4829
5003
  style({ opacity: 0, transform: 'translateY(-8px)' }),
@@ -4847,7 +5021,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4847
5021
  animate('100ms ease-in', style({ opacity: 0, transform: 'translateY(-8px)' }))
4848
5022
  ])
4849
5023
  ])
4850
- ], template: "<!-- Grid Container -->\n<div\n #gridContainer\n [class]=\"gridContainerClasses.join(' ')\"\n [style.height]=\"gridHeightStyle\">\n\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Search -->\n @if (ShowSearch) {\n <div class=\"toolbar-search\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"search-input\"\n [placeholder]=\"ToolbarConfig.searchPlaceholder || 'Search...'\"\n [value]=\"FilterText\"\n (input)=\"FilterText = $any($event.target).value\" />\n @if (FilterText) {\n <button\n class=\"search-clear\"\n (click)=\"FilterText = ''\"\n aria-label=\"Clear search\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n <!-- Custom Left Buttons -->\n @for (button of ToolbarConfig.customButtons; track button) {\n @if (button.position !== 'right' && isButtonVisible(button)) {\n <button\n class=\"toolbar-button\"\n [class]=\"button.cssClass\"\n [disabled]=\"isButtonDisabled(button)\"\n [title]=\"button.tooltip || ''\"\n (click)=\"onToolbarButtonClick(button)\">\n @if (button.icon) {\n <i [class]=\"button.icon\"></i>\n }\n @if (button.text) {\n <span>{{ button.text }}</span>\n }\n </button>\n }\n }\n </div>\n <div class=\"toolbar-center\">\n <!-- Row Count -->\n @if (ToolbarConfig.showRowCount !== false) {\n <span class=\"row-count\">\n {{ totalRowCount }} {{ totalRowCount === 1 ? 'row' : 'rows' }}\n </span>\n }\n <!-- Selection Count -->\n @if (ToolbarConfig.showSelectionCount && SelectedKeys.length > 0) {\n <span class=\"selection-count\">\n ({{ SelectedKeys.length }} selected)\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Recycle Bin chip \u2014 auto-hides when no deleted records, no tracking,\n or user lacks Delete permission. -->\n @if (ShowRecycleBin) {\n <mj-recycle-bin-chip [EntityName]=\"entityInfoName\"></mj-recycle-bin-chip>\n }\n <!-- New/Add Button (predefined) -->\n @if (ShowNewButton) {\n <button\n class=\"toolbar-button\"\n title=\"Create new record\"\n (click)=\"onAddClick()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"button-text\">New</span>\n </button>\n }\n <!-- Refresh Button (predefined) -->\n @if (ShowRefreshButton) {\n <button\n class=\"toolbar-button\"\n title=\"Refresh data\"\n [disabled]=\"loading\"\n (click)=\"onRefreshClick()\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"loading\"></i>\n <span class=\"button-text\">Refresh</span>\n </button>\n }\n <!-- Export Button (predefined) -->\n @if (ShowExportButton) {\n <button\n class=\"toolbar-button\"\n title=\"Export\"\n [disabled]=\"IsPreparingExport\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid\" [class.fa-file-excel]=\"!IsPreparingExport\" [class.fa-spinner]=\"IsPreparingExport\" [class.fa-spin]=\"IsPreparingExport\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n <!-- Delete Button (predefined) -->\n @if (ShowDeleteButton && HasSelection) {\n <button\n class=\"toolbar-button toolbar-button-danger\"\n title=\"Delete selected records\"\n (click)=\"onDeleteClick()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span class=\"button-text\">Delete</span>\n </button>\n }\n <!-- Compare Button (predefined) -->\n @if (ShowCompareButton) {\n <button\n class=\"toolbar-button\"\n title=\"Compare selected records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onCompareClick()\">\n <i class=\"fa-solid fa-code-compare\"></i>\n <span class=\"button-text\">Compare</span>\n </button>\n }\n <!-- Merge Button (predefined) -->\n @if (ShowMergeButton) {\n <button\n class=\"toolbar-button\"\n title=\"Merge selected records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onMergeClick()\">\n <i class=\"fa-solid fa-code-merge\"></i>\n <span class=\"button-text\">Merge</span>\n </button>\n }\n <!-- Add to List Button (predefined) -->\n @if (ShowAddToListButton) {\n <button\n class=\"toolbar-button\"\n [title]=\"HasSelection ? 'Add selected records to a list' : 'Add all matching records to a list'\"\n [disabled]=\"(!HasSelection && !ExportDataProvider) || IsPreparingAddToList\"\n (click)=\"onAddToListClick()\">\n <i class=\"fa-solid\" [class.fa-list-check]=\"!IsPreparingAddToList\" [class.fa-spinner]=\"IsPreparingAddToList\" [class.fa-spin]=\"IsPreparingAddToList\"></i>\n <span class=\"button-text\">Add to List</span>\n </button>\n }\n <!-- Search for Duplicates Button (predefined) -->\n @if (ShowDuplicateSearchButton) {\n <button\n class=\"toolbar-button\"\n title=\"Search for duplicate records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onDuplicateSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass-plus\"></i>\n <span class=\"button-text\">Find Duplicates</span>\n </button>\n }\n <!-- Communication Button (predefined) -->\n @if (ShowCommunicationButton) {\n <button\n class=\"toolbar-button\"\n title=\"Send message to selected records\"\n [disabled]=\"!HasSelection\"\n (click)=\"onCommunicationClick()\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span class=\"button-text\">Send Message</span>\n </button>\n }\n <!-- Legacy ToolbarConfig buttons -->\n <!-- Add Button (legacy) -->\n @if (ToolbarConfig.showAdd && AllowAdd && !ShowNewButton) {\n <button\n class=\"toolbar-button\"\n title=\"Add New\"\n (click)=\"onAddClick()\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n <!-- Refresh Button (legacy) -->\n @if (ToolbarConfig.showRefresh !== false && !ShowRefreshButton) {\n <button\n class=\"toolbar-button\"\n title=\"Refresh\"\n [disabled]=\"loading\"\n (click)=\"onRefreshClick()\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"loading\"></i>\n </button>\n }\n <!-- Delete Button (legacy) -->\n @if (ToolbarConfig.showDelete && AllowDelete && HasSelection && !ShowDeleteButton) {\n <button\n class=\"toolbar-button toolbar-button-danger\"\n title=\"Delete Selected\"\n (click)=\"onDeleteClick()\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <!-- Export Button (legacy) -->\n @if (ToolbarConfig.showExport && !ShowExportButton) {\n <button\n class=\"toolbar-button\"\n title=\"Export\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n }\n <!-- Column Chooser Button -->\n @if (ToolbarConfig.showColumnChooser && AllowColumnToggle) {\n <button\n class=\"toolbar-button\"\n title=\"Column Chooser\"\n (click)=\"onColumnChooserClick()\">\n <i class=\"fa-solid fa-columns\"></i>\n </button>\n }\n <!-- Custom Right Buttons -->\n @for (button of ToolbarConfig.customButtons; track button) {\n @if (button.position === 'right' && isButtonVisible(button)) {\n <button\n class=\"toolbar-button\"\n [class]=\"button.cssClass\"\n [disabled]=\"isButtonDisabled(button)\"\n [title]=\"button.tooltip || ''\"\n (click)=\"onToolbarButtonClick(button)\">\n @if (button.icon) {\n <i [class]=\"button.icon\"></i>\n }\n @if (button.text) {\n <span>{{ button.text }}</span>\n }\n </button>\n }\n }\n <!-- Overflow Menu -->\n @if (hasOverflowMenuItems) {\n <div class=\"toolbar-overflow\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"toolbar-button overflow-trigger\"\n title=\"More actions\"\n (click)=\"toggleOverflowMenu()\">\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </button>\n @if (showOverflowMenu) {\n <div class=\"overflow-menu\" [@fadeIn]>\n <!-- Export (if in overflow) -->\n @if (showExportInOverflow) {\n <button class=\"overflow-item\" (click)=\"onExportClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-file-excel\"></i>\n <span>Export</span>\n </button>\n }\n <!-- Entity Actions -->\n @if (ShowEntityActionButtons && EntityActions.length > 0) {\n <div class=\"overflow-divider\"></div>\n <div class=\"overflow-section-label\">Actions</div>\n @for (action of EntityActions; track action) {\n <button\n class=\"overflow-item\"\n [disabled]=\"!isEntityActionEnabled(action)\"\n (click)=\"onEntityActionClick(action); closeOverflowMenu()\">\n <i [class]=\"action.icon || 'fa-solid fa-bolt'\"></i>\n <span>{{ action.name }}</span>\n </button>\n }\n }\n <!-- Column Chooser (if in overflow) -->\n @if (showColumnChooserInOverflow) {\n <div class=\"overflow-divider\"></div>\n }\n @if (showColumnChooserInOverflow) {\n <button class=\"overflow-item\" (click)=\"onColumnChooserClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>Manage Columns</span>\n </button>\n }\n <!-- Selection-dependent actions in overflow -->\n @if (HasSelection && hasSelectionDependentOverflowActions) {\n <div class=\"overflow-divider\"></div>\n @if (showCommunicationInOverflow) {\n <button class=\"overflow-item\" (click)=\"onCommunicationClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span>Send Message</span>\n </button>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Aggregate Cards (displayed as summary cards above the grid) -->\n @if (ShowAggregatePanel) {\n <div class=\"mj-aggregate-cards\">\n @for (agg of CardAggregates; track agg) {\n <div class=\"aggregate-card\">\n @if (agg.icon) {\n <div class=\"aggregate-card-icon\">\n <i [class]=\"agg.icon\"></i>\n </div>\n }\n <div class=\"aggregate-card-content\">\n <span class=\"aggregate-card-label\">{{ agg.label }}</span>\n <span class=\"aggregate-card-value\">{{ getAggregateValue(agg) }}</span>\n </div>\n </div>\n }\n @if (AggregatesLoading) {\n <div class=\"aggregate-card-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n </div>\n }\n\n <!-- Grid Content -->\n <div class=\"mj-grid-content\">\n <!-- Loading Overlay -->\n @if (loading && rowData.length === 0) {\n <div class=\"mj-grid-loading-overlay\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (errorMessage && !loading) {\n <mj-empty-state\n class=\"mj-grid-state-fill\"\n [Size]=\"EmptyStateSize\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Could not load data\"\n [Message]=\"errorMessage\"\n ActionText=\"Retry\"\n ActionIcon=\"fa-solid fa-arrows-rotate\"\n (Action)=\"Refresh()\" />\n }\n\n <!-- Empty State -->\n @if (!loading && !errorMessage && rowData.length === 0) {\n <mj-empty-state\n class=\"mj-grid-state-fill\"\n [Size]=\"EmptyStateSize\"\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\" />\n }\n\n <!-- AG Grid (Client-side mode) -->\n @if (!errorMessage && PaginationMode === 'client' && (rowData.length > 0 || loading)) {\n <ag-grid-angular\n class=\"mj-ag-grid ag-theme-alpine\"\n [theme]=\"agGridTheme\"\n [columnDefs]=\"agColumnDefs\"\n [rowData]=\"rowData\"\n [defaultColDef]=\"defaultColDef\"\n [rowSelection]=\"agRowSelection\"\n [getRowId]=\"getRowId\"\n [suppressCellFocus]=\"true\"\n [rowHeight]=\"RowHeight\"\n [headerHeight]=\"ShowHeader ? undefined : 0\"\n (gridReady)=\"onGridReady($event)\"\n (cellClicked)=\"onAgCellClicked($event)\"\n (rowClicked)=\"onAgRowClicked($event)\"\n (rowDoubleClicked)=\"onAgRowDoubleClicked($event)\"\n (sortChanged)=\"onAgSortChanged($event)\"\n (selectionChanged)=\"onAgSelectionChanged($event)\"\n (columnResized)=\"onAgColumnResized($event)\"\n (columnMoved)=\"onAgColumnMoved($event)\">\n </ag-grid-angular>\n }\n\n <!-- AG Grid (Infinite Scroll mode) -->\n @if (!errorMessage && PaginationMode === 'infinite') {\n <ag-grid-angular\n class=\"mj-ag-grid ag-theme-alpine\"\n [theme]=\"agGridTheme\"\n [columnDefs]=\"agColumnDefs\"\n [defaultColDef]=\"defaultColDef\"\n [rowSelection]=\"agRowSelection\"\n [getRowId]=\"getRowId\"\n [suppressCellFocus]=\"true\"\n [rowHeight]=\"RowHeight\"\n [headerHeight]=\"ShowHeader ? undefined : 0\"\n [rowModelType]=\"'infinite'\"\n [cacheBlockSize]=\"CacheBlockSize\"\n [maxBlocksInCache]=\"MaxBlocksInCache\"\n [infiniteInitialRowCount]=\"1\"\n [cacheOverflowSize]=\"2\"\n (gridReady)=\"onGridReady($event)\"\n (cellClicked)=\"onAgCellClicked($event)\"\n (rowClicked)=\"onAgRowClicked($event)\"\n (rowDoubleClicked)=\"onAgRowDoubleClicked($event)\"\n (sortChanged)=\"onAgSortChanged($event)\"\n (selectionChanged)=\"onAgSelectionChanged($event)\"\n (columnResized)=\"onAgColumnResized($event)\"\n (columnMoved)=\"onAgColumnMoved($event)\">\n </ag-grid-angular>\n }\n\n </div>\n\n <!-- Pagination (opt-in via ShowPager input) -->\n @if (ShowPager) {\n <mj-pagination\n [TotalRowCount]=\"totalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"loading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Aggregate Summary Row (outside mj-grid-content so it's always visible) -->\n @if (ShowAggregateSummary) {\n <div class=\"mj-aggregate-summary\">\n <div class=\"aggregate-summary-content\">\n @for (agg of ColumnAggregates; track agg) {\n <div class=\"aggregate-summary-item\">\n @if (agg.icon) {\n <i [class]=\"agg.icon\"></i>\n }\n <span class=\"agg-summary-label\">{{ agg.label }}:</span>\n <span class=\"agg-summary-value\">{{ getAggregateValue(agg) }}</span>\n </div>\n }\n </div>\n @if (AggregatesLoading) {\n <div class=\"aggregate-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"showExportDialog\"\n [config]=\"exportDialogConfig\"\n (closed)=\"onExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Runtime-UX driver for an entity action that names a RuntimeUXDriverClass (e.g. the Record Process\n bulk-update runner). Mounted in-place over the grid \u2014 no parent wiring required. -->\n@if (ActiveRuntimeDriver) {\n <mj-entity-action-ux-host\n [DriverClass]=\"ActiveRuntimeDriver.DriverClass\"\n [Context]=\"ActiveRuntimeDriver.Context\"\n (Completed)=\"OnRuntimeDriverCompleted($event)\"\n (Cancelled)=\"OnRuntimeDriverCancelled()\">\n </mj-entity-action-ux-host>\n}\n", styles: ["/* ========================================\n CSS Custom Properties (Theme Variables)\n ======================================== */\n\n:host {\n /* Grid container */\n --grid-border-color: var(--mj-border-default);\n --grid-border-radius: 0px;\n --grid-background: var(--mj-bg-surface);\n\n /* Header */\n --grid-header-bg: var(--mj-bg-surface-card);\n --grid-header-text: var(--mj-text-primary);\n --grid-header-font-weight: 600;\n --grid-header-height: 40px;\n --grid-header-border-color: var(--mj-border-default);\n\n /* Rows */\n --grid-row-height: 40px;\n --grid-row-bg: var(--mj-bg-surface);\n --grid-row-bg-alt: var(--mj-bg-surface-card);\n --grid-row-hover-bg: var(--mj-bg-surface-hover);\n --grid-row-selected-bg: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --grid-row-selected-hover-bg: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n\n /* Cells */\n --grid-cell-padding: 8px 12px;\n --grid-cell-text: var(--mj-text-primary);\n --grid-cell-border-color: var(--mj-border-subtle);\n\n /* Selection - mellow yellow to avoid conflict with blue hyperlinks */\n --grid-checkbox-color: var(--mj-brand-primary);\n --grid-selection-indicator-color: var(--mj-status-warning);\n\n /* Editing */\n --grid-edit-cell-bg: var(--mj-bg-surface);\n --grid-edit-cell-border: var(--mj-brand-primary);\n --grid-edit-cell-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n\n /* Sorting */\n --grid-sort-indicator-color: var(--mj-brand-primary);\n\n /* Toolbar */\n --grid-toolbar-bg: var(--mj-bg-surface);\n --grid-toolbar-height: 48px;\n --grid-toolbar-border-color: var(--mj-border-default);\n\n /* Loading */\n --grid-loading-overlay-bg: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n\n /* Empty state */\n --grid-empty-text-color: var(--mj-text-disabled);\n --grid-empty-icon-color: var(--mj-border-strong);\n\n display: block;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* ========================================\n Grid Container\n ======================================== */\n\n.mj-grid-container {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--grid-border-color);\n border-radius: var(--grid-border-radius);\n background: var(--grid-background);\n overflow: hidden;\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.mj-grid-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--grid-toolbar-height);\n padding: 0 12px;\n background: var(--grid-toolbar-bg);\n border-bottom: 1px solid var(--grid-toolbar-border-color);\n gap: 12px;\n}\n\n.toolbar-left,\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toolbar-center {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.toolbar-search {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.search-icon {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.search-input {\n padding: 6px 30px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-size: 13px;\n width: 200px;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--grid-selection-indicator-color);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.search-clear:hover {\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-button i {\n font-size: 14px;\n}\n\n.toolbar-button-danger {\n color: var(--mj-status-error);\n}\n\n.toolbar-button-danger:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.row-count,\n.selection-count {\n font-weight: 500;\n}\n\n/* ========================================\n Grid Content\n ======================================== */\n\n.mj-grid-content {\n flex: 1;\n position: relative;\n overflow: hidden;\n}\n\n.mj-grid-scroll-container {\n height: 100%;\n overflow: auto;\n}\n\n/* ========================================\n Loading Overlay\n ======================================== */\n\n.mj-grid-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--grid-loading-overlay-bg);\n z-index: 10;\n}\n\n/* ========================================\n Error State\n ======================================== */\n\n/* ========================================\n Empty / Error State\n ======================================== */\n\n/* Flex-fill so <mj-empty-state> placeholders occupy the grid content area\n (the host centers its content but does not grow to fill the parent). */\n.mj-grid-state-fill {\n flex: 1 1 auto;\n}\n\n/* ========================================\n Header Row\n ======================================== */\n\n.mj-grid-header {\n display: flex;\n min-height: var(--grid-header-height);\n background: var(--grid-header-bg);\n border-bottom: 2px solid var(--grid-header-border-color);\n position: sticky;\n top: 0;\n z-index: 5;\n}\n\n.mj-grid-header-cell {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n font-weight: var(--grid-header-font-weight);\n color: var(--grid-header-text);\n font-size: 13px;\n user-select: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right: 1px solid var(--grid-cell-border-color);\n flex-shrink: 0;\n}\n\n.mj-grid-header-cell:last-child {\n border-right: none;\n}\n\n.mj-grid-header-cell.sortable {\n cursor: pointer;\n}\n\n.mj-grid-header-cell.sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.header-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sort-indicator {\n display: flex;\n align-items: center;\n margin-left: 6px;\n color: var(--grid-sort-indicator-color);\n}\n\n.sort-indicator i {\n font-size: 12px;\n}\n\n.sort-index {\n font-size: 10px;\n margin-left: 2px;\n font-weight: normal;\n}\n\n/* ========================================\n Data Rows\n ======================================== */\n\n.mj-grid-row {\n display: flex;\n align-items: stretch;\n background: var(--grid-row-bg);\n transition: background-color 0.15s;\n cursor: default;\n}\n\n.mj-grid-row:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-alt {\n background: var(--grid-row-bg-alt);\n}\n\n.mj-grid-row.grid-row-alt:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-selected {\n background: var(--grid-row-selected-bg);\n}\n\n.mj-grid-row.grid-row-selected:hover {\n background: var(--grid-row-selected-hover-bg);\n}\n\n.mj-grid-row.grid-row-editing {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.mj-grid-row.grid-row-dirty {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n/* ========================================\n Data Cells\n ======================================== */\n\n.mj-grid-cell {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n color: var(--grid-cell-text);\n font-size: 13px;\n overflow: hidden;\n border-right: 1px solid transparent;\n flex-shrink: 0;\n}\n\n.mj-grid-cell:last-child {\n border-right: none;\n}\n\n/* Grid lines modes */\n.grid-lines-horizontal .mj-grid-row {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-vertical .mj-grid-cell {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both .mj-grid-row {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both .mj-grid-cell {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n/* Cell alignment */\n.mj-grid-cell.align-left {\n justify-content: flex-start;\n}\n\n.mj-grid-cell.align-center {\n justify-content: center;\n}\n\n.mj-grid-cell.align-right {\n justify-content: flex-end;\n}\n\n.cell-content {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Special cells */\n.row-number-cell {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n background: var(--grid-header-bg);\n}\n\n.checkbox-cell {\n width: 40px;\n min-width: 40px;\n max-width: 40px;\n justify-content: center;\n}\n\n.checkbox-cell input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--grid-checkbox-color);\n}\n\n/* ========================================\n Virtual Scrolling\n ======================================== */\n\n.mj-grid-virtual-spacer {\n flex-shrink: 0;\n}\n\n/* ========================================\n Responsive Adjustments\n ======================================== */\n\n@media (max-width: 768px) {\n .mj-grid-toolbar {\n flex-wrap: wrap;\n padding: 8px;\n }\n\n .toolbar-search {\n order: 3;\n width: 100%;\n margin-top: 8px;\n }\n\n .search-input {\n width: 100%;\n }\n\n .toolbar-center {\n order: 2;\n }\n\n /* Hide button text on mobile */\n .toolbar-button .button-text {\n display: none;\n }\n}\n\n/* ========================================\n Toolbar Button Text\n ======================================== */\n\n.toolbar-button .button-text {\n font-size: 13px;\n}\n\n/* ========================================\n Overflow Menu\n ======================================== */\n\n.toolbar-overflow {\n position: relative;\n}\n\n.overflow-trigger {\n padding: 6px 8px !important;\n}\n\n.overflow-trigger i {\n font-size: 16px;\n}\n\n.overflow-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 220px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);\n z-index: 1000;\n overflow: hidden;\n}\n\n.overflow-item {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n text-align: left;\n gap: 12px;\n transition: background-color 0.15s;\n}\n\n.overflow-item:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n}\n\n.overflow-item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.overflow-item i {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.overflow-item span {\n flex: 1;\n}\n\n.overflow-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n.overflow-section-label {\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n letter-spacing: 0.5px;\n}\n\n/* Entity Actions submenu styling */\n.overflow-item.action-item i {\n color: var(--mj-brand-primary);\n}\n\n/* ========================================\n Highlight Matches\n ======================================== */\n\n::ng-deep .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n padding: 0 1px;\n}\n\n/* ========================================\n AG Grid Customizations\n ======================================== */\n\n.mj-ag-grid {\n width: 100%;\n height: 100%;\n}\n\n/* AG Grid v35 uses JS-based theming (colorSchemeVariable) \u2014 no CSS variable overrides needed */\n\n/* Selected row styling - left indicator bar only, background handled by AG Grid theme */\n::ng-deep .ag-row-selected {\n box-shadow: inset 4px 0 0 0 var(--mj-status-warning);\n}\n\n/* Selection checkbox styling */\n::ng-deep .ag-checkbox-input-wrapper {\n width: 18px;\n height: 18px;\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n/* ========================================\n Visual Config: Header Styles\n ======================================== */\n\n/* Flat header (minimal) */\n.header-style-flat ::ng-deep .ag-header {\n background: var(--grid-header-bg, var(--mj-bg-surface-card));\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n/* Elevated header (default - subtle shadow) */\n.header-style-elevated ::ng-deep .ag-header {\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n.header-style-elevated.header-shadow ::ng-deep .ag-header {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n/* Gradient header (more prominent) */\n.header-style-gradient ::ng-deep .ag-header {\n background: var(--mj-bg-surface-sunken);\n border-bottom: none;\n}\n\n.header-style-gradient.header-shadow ::ng-deep .ag-header {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n/* Bold header (high contrast) */\n.header-style-bold ::ng-deep .ag-header {\n background: var(--mj-text-secondary);\n border-bottom: none;\n}\n\n.header-style-bold ::ng-deep .ag-header-cell-text {\n color: var(--mj-text-inverse);\n font-weight: 600;\n}\n\n.header-style-bold ::ng-deep .ag-header-icon {\n color: color-mix(in srgb, var(--mj-text-inverse) 70%, transparent);\n}\n\n.header-style-bold ::ng-deep .ag-header-cell:hover {\n background: color-mix(in srgb, var(--mj-text-inverse) 10%, transparent);\n}\n\n/* Header sort icons enhancement */\n::ng-deep .ag-header-cell-sorted-asc .ag-icon-asc,\n::ng-deep .ag-header-cell-sorted-desc .ag-icon-desc {\n color: var(--grid-accent-color, var(--grid-sort-indicator-color, var(--mj-brand-primary)));\n}\n\n/* ========================================\n Visual Config: Zebra Striping\n ======================================== */\n\n/* Subtle contrast */\n.alternate-rows-subtle ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.015);\n}\n\n.alternate-rows-subtle ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* Medium contrast (default) */\n.alternate-rows-medium ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.025);\n}\n\n.alternate-rows-medium ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* Strong contrast */\n.alternate-rows-strong ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.alternate-rows-strong ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* ========================================\n Visual Config: Hover Transitions\n ======================================== */\n\n.hover-transitions ::ng-deep .ag-row {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n.hover-transitions ::ng-deep .ag-cell {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n/* ========================================\n Visual Config: Cell Padding\n ======================================== */\n\n.cell-padding-compact ::ng-deep .ag-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-compact ::ng-deep .ag-header-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-normal ::ng-deep .ag-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-normal ::ng-deep .ag-header-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-comfortable ::ng-deep .ag-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n.cell-padding-comfortable ::ng-deep .ag-header-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n/* ========================================\n Visual Config: Checkbox Styles\n ======================================== */\n\n/* Rounded checkbox */\n.checkbox-style-rounded ::ng-deep .ag-checkbox-input-wrapper {\n border-radius: 4px;\n}\n\n.checkbox-style-rounded ::ng-deep .ag-checkbox-input-wrapper::after {\n border-radius: 3px;\n}\n\n/* Filled checkbox */\n.checkbox-style-filled ::ng-deep .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n border-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n.checkbox-style-filled ::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n/* ========================================\n Cell Content Formatting\n ======================================== */\n\n/* Right-aligned cells (numbers) */\n::ng-deep .cell-align-right {\n text-align: right;\n justify-content: flex-end;\n}\n\n::ng-deep .header-align-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n/* Empty cell placeholder */\n::ng-deep .cell-empty {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n/* Boolean icons */\n::ng-deep .cell-boolean-true {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n::ng-deep .cell-boolean-false {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n/* Clickable links */\n::ng-deep .cell-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n transition: color 0.15s;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\n\n::ng-deep .cell-link:hover {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n}\n\n/* Email cells */\n::ng-deep .cell-email {\n font-family: inherit;\n font-size: 13px;\n}\n\n/* Foreign key link cells */\n::ng-deep .cell-fk-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s, text-decoration 0.15s;\n}\n\n::ng-deep .cell-fk-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n::ng-deep .cell-fk-link:active {\n color: var(--mj-brand-primary-active);\n}\n\n/* URL cells */\n::ng-deep .cell-url {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n font-size: 13px;\n}\n\n/* Phone cells */\n::ng-deep .cell-phone {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.3px;\n}\n\n/* ========================================\n Skeleton Loading Animation\n ======================================== */\n\n@keyframes skeleton-shimmer {\n 0% {\n background-position: -200px 0;\n }\n 100% {\n background-position: calc(200px + 100%) 0;\n }\n}\n\n.skeleton-row {\n display: flex;\n height: 40px;\n align-items: center;\n padding: 0 12px;\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n.skeleton-cell {\n height: 16px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n var(--mj-bg-surface-sunken) 0px,\n var(--mj-bg-surface-hover) 40px,\n var(--mj-bg-surface-sunken) 80px\n );\n background-size: 200px 100%;\n animation: skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-cell-short {\n width: 60px;\n}\n\n.skeleton-cell-medium {\n width: 120px;\n}\n\n.skeleton-cell-long {\n width: 180px;\n}\n\n/* Selection checkbox column header */\n::ng-deep .ag-header-select-all {\n margin-right: 0;\n}\n\n/* ========================================\n Row Border Enhancement\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-row {\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n::ng-deep .ag-theme-alpine .ag-row:last-child {\n border-bottom: none;\n}\n\n/* ========================================\n Focus States\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-cell-focus {\n border: none !important;\n outline: none !important;\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:focus {\n outline: 2px solid var(--grid-accent-color, var(--mj-brand-primary));\n outline-offset: -2px;\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* ========================================\n Pinned Column Styling\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-pinned-left-cols-container {\n border-right: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n::ng-deep .ag-theme-alpine .ag-pinned-right-cols-container {\n border-left: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n/* ========================================\n Header Cell Enhancements\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell-sortable:hover .ag-header-cell-label {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n}\n\n/* Sort icon animation */\n::ng-deep .ag-theme-alpine .ag-sort-indicator-icon {\n transition: transform 0.2s ease;\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:hover .ag-sort-indicator-icon {\n transform: scale(1.1);\n}\n\n/* ========================================\n Enhanced Multi-Sort Indicators\n These styles use :host to ensure they're scoped to this component\n and !important to override AG Grid's built-in styles\n ======================================== */\n\n/* Highlight sorted column headers with eye-catching background */\n/* Ascending = blue tint */\n:host ::ng-deep .ag-header-cell-sorted-asc {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n/* Descending = pink tint */\n:host ::ng-deep .ag-header-cell-sorted-desc {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n/* Bottom border accent for sorted columns - ascending = blue */\n:host ::ng-deep .ag-header-cell-sorted-asc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-brand-primary);\n}\n\n/* Bottom border accent for sorted columns - descending = pink */\n:host ::ng-deep .ag-header-cell-sorted-desc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-status-error);\n}\n\n/* Sorted column header text - ascending = blue, bold */\n:host ::ng-deep .ag-header-cell-sorted-asc .ag-header-cell-text {\n color: var(--mj-brand-primary) !important;\n font-weight: 700 !important;\n}\n\n/* Sorted column header text - descending = pink, bold */\n:host ::ng-deep .ag-header-cell-sorted-desc .ag-header-cell-text {\n color: var(--mj-status-error) !important;\n font-weight: 700 !important;\n}\n\n/* Sort icons - larger and more prominent */\n/* Ascending = blue */\n:host ::ng-deep .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n/* Descending = pink/magenta */\n:host ::ng-deep .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n:host ::ng-deep .ag-sort-ascending-icon .ag-icon,\n:host ::ng-deep .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n/* Sort order number (1, 2, 3) - show as plain number, no bubble */\n/* This avoids AG Grid bug where .ag-sort-order is always present but empty when unsorted */\n/* The number is only visible when AG Grid populates it (i.e., when column is sorted) */\n/* Default blue for ascending */\n:host ::ng-deep .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-brand-primary) !important;\n}\n\n/* Sort order number - pink for descending */\n:host ::ng-deep .ag-header-cell-sorted-desc .ag-sort-order {\n color: var(--mj-status-error) !important;\n}\n\n/* Hover state for sortable headers */\n:host ::ng-deep .ag-header-cell-sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n:host ::ng-deep .ag-header-cell-sortable:hover .ag-header-cell-text {\n color: var(--mj-brand-primary);\n}\n\n/* ========================================\n Aggregate Summary Row\n ======================================== */\n\n.mj-aggregate-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n min-height: 44px;\n}\n\n.aggregate-summary-content {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n align-items: center;\n}\n\n.aggregate-summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n}\n\n.aggregate-summary-item i {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.agg-summary-label {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.agg-summary-value {\n color: var(--mj-text-primary);\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n.aggregate-loading {\n display: flex;\n align-items: center;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-loading i {\n font-size: 14px;\n}\n\n/* ========================================\n AGGREGATE CARDS (displayed above grid)\n ======================================== */\n\n.mj-aggregate-cards {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.aggregate-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n min-width: 140px;\n transition: all 0.15s ease;\n}\n\n.aggregate-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);\n}\n\n.aggregate-card-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.aggregate-card-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.aggregate-card-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.aggregate-card-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.aggregate-card-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-card-loading i {\n font-size: 16px;\n}\n\n/* ========================================\n Text Wrapping Styles\n ======================================== */\n\n/* Cell class for wrapped text */\n::ng-deep .cell-wrap-text {\n white-space: normal !important;\n word-wrap: break-word;\n line-height: 1.4;\n padding-top: 8px !important;\n padding-bottom: 8px !important;\n}\n\n/* Ensure AG Grid cells allow wrapping */\n::ng-deep .ag-cell.cell-wrap-text {\n overflow: visible;\n text-overflow: clip;\n}\n\n/* Maintain minimum row height when wrapping */\n::ng-deep .ag-row[style*=\"auto-height\"] {\n min-height: 40px;\n}\n\n/* ========================================\n Width filler column ([FillWidth])\n ========================================\n The trailing filler exists so row banding and horizontal rules reach the container's right edge\n instead of stopping wherever the last real column ends. For that to read as \"the table extends\"\n rather than \"there is an empty column here\", it must lose every affordance that makes a column\n look like a column: its own vertical rule, the header hover/menu, and the resize handle. What is\n left is bare row background \u2014 which is exactly the point. */\n::ng-deep .ag-header-cell.mj-grid-filler-header,\n::ng-deep .ag-cell.mj-grid-filler-cell {\n border-left: none !important;\n border-right: none !important;\n cursor: default;\n}\n\n/* The hover tint is OURS (see \".ag-theme-alpine .ag-header-cell:hover\" above), not AG Grid's, so it\n has to be switched off here or the filler lights up as though it were interactive. Everything else\n the filler needs suppressed \u2014 resize grip, header menu, moving, tool-panel entry \u2014 is handled by\n native colDef flags on the column itself, not by CSS. */\n::ng-deep .ag-header-cell.mj-grid-filler-header:hover {\n background-color: transparent !important;\n}\n"] }]
5024
+ ], template: "<!-- Grid Container -->\n<div\n #gridContainer\n [class]=\"gridContainerClasses.join(' ')\"\n [style.height]=\"gridHeightStyle\">\n\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Search -->\n @if (ShowSearch) {\n <div class=\"toolbar-search\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"search-input\"\n [placeholder]=\"ToolbarConfig.searchPlaceholder || 'Search...'\"\n [value]=\"FilterText\"\n (input)=\"FilterText = $any($event.target).value\" />\n @if (FilterText) {\n <button\n class=\"search-clear\"\n (click)=\"FilterText = ''\"\n aria-label=\"Clear search\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n <!-- Custom Left Buttons -->\n @for (button of ToolbarConfig.customButtons; track button) {\n @if (button.position !== 'right' && isButtonVisible(button)) {\n <button\n class=\"toolbar-button\"\n [class]=\"button.cssClass\"\n [disabled]=\"isButtonDisabled(button)\"\n [title]=\"button.tooltip || ''\"\n (click)=\"onToolbarButtonClick(button)\">\n @if (button.icon) {\n <i [class]=\"button.icon\"></i>\n }\n @if (button.text) {\n <span>{{ button.text }}</span>\n }\n </button>\n }\n }\n </div>\n <div class=\"toolbar-center\">\n <!-- Row Count -->\n @if (ToolbarConfig.showRowCount !== false) {\n <span class=\"row-count\">\n {{ totalRowCount }} {{ totalRowCount === 1 ? 'row' : 'rows' }}\n </span>\n }\n <!-- Selection Count -->\n @if (ToolbarConfig.showSelectionCount && SelectedKeys.length > 0) {\n <span class=\"selection-count\">\n ({{ SelectedKeys.length }} selected)\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Recycle Bin chip \u2014 auto-hides when no deleted records, no tracking,\n or user lacks Delete permission. -->\n @if (ShowRecycleBin) {\n <mj-recycle-bin-chip [EntityName]=\"entityInfoName\"></mj-recycle-bin-chip>\n }\n <!-- New/Add Button (predefined) -->\n @if (ShowNewButton) {\n <button\n class=\"toolbar-button\"\n title=\"Create new record\"\n (click)=\"onAddClick()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"button-text\">New</span>\n </button>\n }\n <!-- Refresh Button (predefined) -->\n @if (ShowRefreshButton) {\n <button\n class=\"toolbar-button\"\n title=\"Refresh data\"\n [disabled]=\"loading\"\n (click)=\"onRefreshClick()\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"loading\"></i>\n <span class=\"button-text\">Refresh</span>\n </button>\n }\n <!-- Export Button (predefined) -->\n @if (ShowExportButton) {\n <button\n class=\"toolbar-button\"\n title=\"Export\"\n [disabled]=\"IsPreparingExport\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid\" [class.fa-file-excel]=\"!IsPreparingExport\" [class.fa-spinner]=\"IsPreparingExport\" [class.fa-spin]=\"IsPreparingExport\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n <!-- Delete Button (predefined) -->\n @if (ShowDeleteButton && HasSelection) {\n <button\n class=\"toolbar-button toolbar-button-danger\"\n title=\"Delete selected records\"\n (click)=\"onDeleteClick()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span class=\"button-text\">Delete</span>\n </button>\n }\n <!-- Compare Button (predefined) -->\n @if (ShowCompareButton) {\n <button\n class=\"toolbar-button\"\n title=\"Compare selected records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onCompareClick()\">\n <i class=\"fa-solid fa-code-compare\"></i>\n <span class=\"button-text\">Compare</span>\n </button>\n }\n <!-- Merge Button (predefined) -->\n @if (ShowMergeButton) {\n <button\n class=\"toolbar-button\"\n title=\"Merge selected records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onMergeClick()\">\n <i class=\"fa-solid fa-code-merge\"></i>\n <span class=\"button-text\">Merge</span>\n </button>\n }\n <!-- Add to List Button (predefined) -->\n @if (ShowAddToListButton) {\n <button\n class=\"toolbar-button\"\n [title]=\"HasSelection ? 'Add selected records to a list' : 'Add all matching records to a list'\"\n [disabled]=\"(!HasSelection && !ExportDataProvider) || IsPreparingAddToList\"\n (click)=\"onAddToListClick()\">\n <i class=\"fa-solid\" [class.fa-list-check]=\"!IsPreparingAddToList\" [class.fa-spinner]=\"IsPreparingAddToList\" [class.fa-spin]=\"IsPreparingAddToList\"></i>\n <span class=\"button-text\">Add to List</span>\n </button>\n }\n <!-- Search for Duplicates Button (predefined) -->\n @if (ShowDuplicateSearchButton) {\n <button\n class=\"toolbar-button\"\n title=\"Search for duplicate records\"\n [disabled]=\"!HasMultipleSelection\"\n (click)=\"onDuplicateSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass-plus\"></i>\n <span class=\"button-text\">Find Duplicates</span>\n </button>\n }\n <!-- Communication Button (predefined) -->\n @if (ShowCommunicationButton) {\n <button\n class=\"toolbar-button\"\n title=\"Send message to selected records\"\n [disabled]=\"!HasSelection\"\n (click)=\"onCommunicationClick()\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span class=\"button-text\">Send Message</span>\n </button>\n }\n <!-- Legacy ToolbarConfig buttons -->\n <!-- Add Button (legacy) -->\n @if (ToolbarConfig.showAdd && AllowAdd && !ShowNewButton) {\n <button\n class=\"toolbar-button\"\n title=\"Add New\"\n (click)=\"onAddClick()\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n <!-- Refresh Button (legacy) -->\n @if (ToolbarConfig.showRefresh !== false && !ShowRefreshButton) {\n <button\n class=\"toolbar-button\"\n title=\"Refresh\"\n [disabled]=\"loading\"\n (click)=\"onRefreshClick()\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"loading\"></i>\n </button>\n }\n <!-- Delete Button (legacy) -->\n @if (ToolbarConfig.showDelete && AllowDelete && HasSelection && !ShowDeleteButton) {\n <button\n class=\"toolbar-button toolbar-button-danger\"\n title=\"Delete Selected\"\n (click)=\"onDeleteClick()\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <!-- Export Button (legacy) -->\n @if (ToolbarConfig.showExport && !ShowExportButton) {\n <button\n class=\"toolbar-button\"\n title=\"Export\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n }\n <!-- Column Chooser Button -->\n @if (ToolbarConfig.showColumnChooser && AllowColumnToggle) {\n <button\n class=\"toolbar-button\"\n title=\"Column Chooser\"\n (click)=\"onColumnChooserClick()\">\n <i class=\"fa-solid fa-columns\"></i>\n </button>\n }\n <!-- Custom Right Buttons -->\n @for (button of ToolbarConfig.customButtons; track button) {\n @if (button.position === 'right' && isButtonVisible(button)) {\n <button\n class=\"toolbar-button\"\n [class]=\"button.cssClass\"\n [disabled]=\"isButtonDisabled(button)\"\n [title]=\"button.tooltip || ''\"\n (click)=\"onToolbarButtonClick(button)\">\n @if (button.icon) {\n <i [class]=\"button.icon\"></i>\n }\n @if (button.text) {\n <span>{{ button.text }}</span>\n }\n </button>\n }\n }\n <!-- Overflow Menu -->\n @if (hasOverflowMenuItems) {\n <div class=\"toolbar-overflow\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"toolbar-button overflow-trigger\"\n title=\"More actions\"\n (click)=\"toggleOverflowMenu()\">\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </button>\n @if (showOverflowMenu) {\n <div class=\"overflow-menu\" [@fadeIn]>\n <!-- Export (if in overflow) -->\n @if (showExportInOverflow) {\n <button class=\"overflow-item\" (click)=\"onExportClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-file-excel\"></i>\n <span>Export</span>\n </button>\n }\n <!-- Entity Actions -->\n @if (ShowEntityActionButtons && EntityActions.length > 0) {\n <div class=\"overflow-divider\"></div>\n <div class=\"overflow-section-label\">Actions</div>\n @for (action of EntityActions; track action) {\n <button\n class=\"overflow-item\"\n [disabled]=\"!isEntityActionEnabled(action)\"\n (click)=\"onEntityActionClick(action); closeOverflowMenu()\">\n <i [class]=\"action.icon || 'fa-solid fa-bolt'\"></i>\n <span>{{ action.name }}</span>\n </button>\n }\n }\n <!-- Column Chooser (if in overflow) -->\n @if (showColumnChooserInOverflow) {\n <div class=\"overflow-divider\"></div>\n }\n @if (showColumnChooserInOverflow) {\n <button class=\"overflow-item\" (click)=\"onColumnChooserClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>Manage Columns</span>\n </button>\n }\n <!-- Selection-dependent actions in overflow -->\n @if (HasSelection && hasSelectionDependentOverflowActions) {\n <div class=\"overflow-divider\"></div>\n @if (showCommunicationInOverflow) {\n <button class=\"overflow-item\" (click)=\"onCommunicationClick(); closeOverflowMenu()\">\n <i class=\"fa-solid fa-envelope\"></i>\n <span>Send Message</span>\n </button>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Aggregate Cards (displayed as summary cards above the grid) -->\n @if (ShowAggregatePanel) {\n <div class=\"mj-aggregate-cards\">\n @for (agg of CardAggregates; track agg) {\n <div class=\"aggregate-card\">\n @if (agg.icon) {\n <div class=\"aggregate-card-icon\">\n <i [class]=\"agg.icon\"></i>\n </div>\n }\n <div class=\"aggregate-card-content\">\n <span class=\"aggregate-card-label\">{{ agg.label }}</span>\n <span class=\"aggregate-card-value\">{{ getAggregateValue(agg) }}</span>\n </div>\n </div>\n }\n @if (AggregatesLoading) {\n <div class=\"aggregate-card-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n </div>\n }\n\n <!-- Grid Content -->\n <div class=\"mj-grid-content\">\n <!-- Loading Overlay -->\n @if (loading && rowData.length === 0) {\n <div class=\"mj-grid-loading-overlay\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (errorMessage && !loading) {\n <mj-empty-state\n class=\"mj-grid-state-fill\"\n [Size]=\"EmptyStateSize\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load this data\"\n [Message]=\"FriendlyErrorMessage\"\n ActionText=\"Retry\"\n ActionIcon=\"fa-solid fa-arrows-rotate\"\n (Action)=\"Refresh()\" />\n }\n\n <!-- Empty State -->\n @if (!loading && !errorMessage && rowData.length === 0) {\n <mj-empty-state\n class=\"mj-grid-state-fill\"\n [Size]=\"EmptyStateSize\"\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\" />\n }\n\n <!-- AG Grid (Client-side mode) -->\n @if (!errorMessage && PaginationMode === 'client' && (rowData.length > 0 || loading)) {\n <ag-grid-angular\n class=\"mj-ag-grid ag-theme-alpine\"\n [theme]=\"agGridTheme\"\n [columnDefs]=\"agColumnDefs\"\n [rowData]=\"rowData\"\n [defaultColDef]=\"defaultColDef\"\n [rowSelection]=\"agRowSelection\"\n [getRowId]=\"getRowId\"\n [suppressCellFocus]=\"true\"\n [rowHeight]=\"RowHeight\"\n [headerHeight]=\"ShowHeader ? undefined : 0\"\n (gridReady)=\"onGridReady($event)\"\n (cellClicked)=\"onAgCellClicked($event)\"\n (rowClicked)=\"onAgRowClicked($event)\"\n (rowDoubleClicked)=\"onAgRowDoubleClicked($event)\"\n (sortChanged)=\"onAgSortChanged($event)\"\n (selectionChanged)=\"onAgSelectionChanged($event)\"\n (columnResized)=\"onAgColumnResized($event)\"\n (columnMoved)=\"onAgColumnMoved($event)\">\n </ag-grid-angular>\n }\n\n <!-- AG Grid (Infinite Scroll mode) -->\n @if (!errorMessage && PaginationMode === 'infinite') {\n <ag-grid-angular\n class=\"mj-ag-grid ag-theme-alpine\"\n [theme]=\"agGridTheme\"\n [columnDefs]=\"agColumnDefs\"\n [defaultColDef]=\"defaultColDef\"\n [rowSelection]=\"agRowSelection\"\n [getRowId]=\"getRowId\"\n [suppressCellFocus]=\"true\"\n [rowHeight]=\"RowHeight\"\n [headerHeight]=\"ShowHeader ? undefined : 0\"\n [rowModelType]=\"'infinite'\"\n [cacheBlockSize]=\"CacheBlockSize\"\n [maxBlocksInCache]=\"MaxBlocksInCache\"\n [infiniteInitialRowCount]=\"1\"\n [cacheOverflowSize]=\"2\"\n (gridReady)=\"onGridReady($event)\"\n (cellClicked)=\"onAgCellClicked($event)\"\n (rowClicked)=\"onAgRowClicked($event)\"\n (rowDoubleClicked)=\"onAgRowDoubleClicked($event)\"\n (sortChanged)=\"onAgSortChanged($event)\"\n (selectionChanged)=\"onAgSelectionChanged($event)\"\n (columnResized)=\"onAgColumnResized($event)\"\n (columnMoved)=\"onAgColumnMoved($event)\">\n </ag-grid-angular>\n }\n\n </div>\n\n <!-- Pagination (opt-in via ShowPager input) -->\n @if (ShowPager) {\n <mj-pagination\n [TotalRowCount]=\"totalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"loading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Aggregate Summary Row (outside mj-grid-content so it's always visible) -->\n @if (ShowAggregateSummary) {\n <div class=\"mj-aggregate-summary\">\n <div class=\"aggregate-summary-content\">\n @for (agg of ColumnAggregates; track agg) {\n <div class=\"aggregate-summary-item\">\n @if (agg.icon) {\n <i [class]=\"agg.icon\"></i>\n }\n <span class=\"agg-summary-label\">{{ agg.label }}:</span>\n <span class=\"agg-summary-value\">{{ getAggregateValue(agg) }}</span>\n </div>\n }\n </div>\n @if (AggregatesLoading) {\n <div class=\"aggregate-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n </div>\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"showExportDialog\"\n [config]=\"exportDialogConfig\"\n (closed)=\"onExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Runtime-UX driver for an entity action that names a RuntimeUXDriverClass (e.g. the Record Process\n bulk-update runner). Mounted in-place over the grid \u2014 no parent wiring required. -->\n@if (ActiveRuntimeDriver) {\n <mj-entity-action-ux-host\n [DriverClass]=\"ActiveRuntimeDriver.DriverClass\"\n [Context]=\"ActiveRuntimeDriver.Context\"\n (Completed)=\"OnRuntimeDriverCompleted($event)\"\n (Cancelled)=\"OnRuntimeDriverCancelled()\">\n </mj-entity-action-ux-host>\n}\n", styles: ["/* ========================================\n CSS Custom Properties (Theme Variables)\n ======================================== */\n\n:host {\n /* Grid container */\n --grid-border-color: var(--mj-border-default);\n --grid-border-radius: 0px;\n --grid-background: var(--mj-bg-surface);\n\n /* Header */\n --grid-header-bg: var(--mj-bg-surface-card);\n --grid-header-text: var(--mj-text-primary);\n --grid-header-font-weight: 600;\n --grid-header-height: 40px;\n --grid-header-border-color: var(--mj-border-default);\n\n /* Rows */\n --grid-row-height: 40px;\n --grid-row-bg: var(--mj-bg-surface);\n --grid-row-bg-alt: var(--mj-bg-surface-card);\n --grid-row-hover-bg: var(--mj-bg-surface-hover);\n --grid-row-selected-bg: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --grid-row-selected-hover-bg: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n\n /* Cells */\n --grid-cell-padding: 8px 12px;\n --grid-cell-text: var(--mj-text-primary);\n --grid-cell-border-color: var(--mj-border-subtle);\n\n /* Selection - mellow yellow to avoid conflict with blue hyperlinks */\n --grid-checkbox-color: var(--mj-brand-primary);\n --grid-selection-indicator-color: var(--mj-status-warning);\n\n /* Editing */\n --grid-edit-cell-bg: var(--mj-bg-surface);\n --grid-edit-cell-border: var(--mj-brand-primary);\n --grid-edit-cell-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n\n /* Sorting */\n --grid-sort-indicator-color: var(--mj-brand-primary);\n\n /* Toolbar */\n --grid-toolbar-bg: var(--mj-bg-surface);\n --grid-toolbar-height: 48px;\n --grid-toolbar-border-color: var(--mj-border-default);\n\n /* Loading */\n --grid-loading-overlay-bg: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n\n /* Empty state */\n --grid-empty-text-color: var(--mj-text-disabled);\n --grid-empty-icon-color: var(--mj-border-strong);\n\n display: block;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* ========================================\n Grid Container\n ======================================== */\n\n.mj-grid-container {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--grid-border-color);\n border-radius: var(--grid-border-radius);\n background: var(--grid-background);\n overflow: hidden;\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.mj-grid-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: var(--grid-toolbar-height);\n padding: 0 12px;\n background: var(--grid-toolbar-bg);\n border-bottom: 1px solid var(--grid-toolbar-border-color);\n gap: 12px;\n}\n\n.toolbar-left,\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toolbar-center {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.toolbar-search {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.search-icon {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.search-input {\n padding: 6px 30px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-size: 13px;\n width: 200px;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--grid-selection-indicator-color);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.search-clear:hover {\n color: var(--mj-text-secondary);\n}\n\n.toolbar-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-button i {\n font-size: 14px;\n}\n\n.toolbar-button-danger {\n color: var(--mj-status-error);\n}\n\n.toolbar-button-danger:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.row-count,\n.selection-count {\n font-weight: 500;\n}\n\n/* ========================================\n Grid Content\n ======================================== */\n\n.mj-grid-content {\n flex: 1;\n position: relative;\n overflow: hidden;\n}\n\n.mj-grid-scroll-container {\n height: 100%;\n overflow: auto;\n}\n\n/* ========================================\n Loading Overlay\n ======================================== */\n\n.mj-grid-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--grid-loading-overlay-bg);\n z-index: 10;\n}\n\n/* ========================================\n Error State\n ======================================== */\n\n/* ========================================\n Empty / Error State\n ======================================== */\n\n/* Flex-fill so <mj-empty-state> placeholders occupy the grid content area\n (the host centers its content but does not grow to fill the parent). */\n.mj-grid-state-fill {\n flex: 1 1 auto;\n}\n\n/* ========================================\n Header Row\n ======================================== */\n\n.mj-grid-header {\n display: flex;\n min-height: var(--grid-header-height);\n background: var(--grid-header-bg);\n border-bottom: 2px solid var(--grid-header-border-color);\n position: sticky;\n top: 0;\n z-index: 5;\n}\n\n.mj-grid-header-cell {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n font-weight: var(--grid-header-font-weight);\n color: var(--grid-header-text);\n font-size: 13px;\n user-select: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right: 1px solid var(--grid-cell-border-color);\n flex-shrink: 0;\n}\n\n.mj-grid-header-cell:last-child {\n border-right: none;\n}\n\n.mj-grid-header-cell.sortable {\n cursor: pointer;\n}\n\n.mj-grid-header-cell.sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.header-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sort-indicator {\n display: flex;\n align-items: center;\n margin-left: 6px;\n color: var(--grid-sort-indicator-color);\n}\n\n.sort-indicator i {\n font-size: 12px;\n}\n\n.sort-index {\n font-size: 10px;\n margin-left: 2px;\n font-weight: normal;\n}\n\n/* ========================================\n Data Rows\n ======================================== */\n\n.mj-grid-row {\n display: flex;\n align-items: stretch;\n background: var(--grid-row-bg);\n transition: background-color 0.15s;\n cursor: default;\n}\n\n.mj-grid-row:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-alt {\n background: var(--grid-row-bg-alt);\n}\n\n.mj-grid-row.grid-row-alt:hover {\n background: var(--grid-row-hover-bg);\n}\n\n.mj-grid-row.grid-row-selected {\n background: var(--grid-row-selected-bg);\n}\n\n.mj-grid-row.grid-row-selected:hover {\n background: var(--grid-row-selected-hover-bg);\n}\n\n.mj-grid-row.grid-row-editing {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.mj-grid-row.grid-row-dirty {\n border-left: 3px solid var(--mj-status-warning);\n}\n\n/* ========================================\n Data Cells\n ======================================== */\n\n.mj-grid-cell {\n display: flex;\n align-items: center;\n padding: var(--grid-cell-padding);\n color: var(--grid-cell-text);\n font-size: 13px;\n overflow: hidden;\n border-right: 1px solid transparent;\n flex-shrink: 0;\n}\n\n.mj-grid-cell:last-child {\n border-right: none;\n}\n\n/* Grid lines modes */\n.grid-lines-horizontal .mj-grid-row {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-vertical .mj-grid-cell {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both .mj-grid-row {\n border-bottom: 1px solid var(--grid-cell-border-color);\n}\n\n.grid-lines-both .mj-grid-cell {\n border-right: 1px solid var(--grid-cell-border-color);\n}\n\n/* Cell alignment */\n.mj-grid-cell.align-left {\n justify-content: flex-start;\n}\n\n.mj-grid-cell.align-center {\n justify-content: center;\n}\n\n.mj-grid-cell.align-right {\n justify-content: flex-end;\n}\n\n.cell-content {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Special cells */\n.row-number-cell {\n width: 50px;\n min-width: 50px;\n max-width: 50px;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n background: var(--grid-header-bg);\n}\n\n.checkbox-cell {\n width: 40px;\n min-width: 40px;\n max-width: 40px;\n justify-content: center;\n}\n\n.checkbox-cell input[type=\"checkbox\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--grid-checkbox-color);\n}\n\n/* ========================================\n Virtual Scrolling\n ======================================== */\n\n.mj-grid-virtual-spacer {\n flex-shrink: 0;\n}\n\n/* ========================================\n Responsive Adjustments\n ======================================== */\n\n@media (max-width: 768px) {\n .mj-grid-toolbar {\n flex-wrap: wrap;\n padding: 8px;\n }\n\n .toolbar-search {\n order: 3;\n width: 100%;\n margin-top: 8px;\n }\n\n .search-input {\n width: 100%;\n }\n\n .toolbar-center {\n order: 2;\n }\n\n /* Hide button text on mobile */\n .toolbar-button .button-text {\n display: none;\n }\n}\n\n/* ========================================\n Toolbar Button Text\n ======================================== */\n\n.toolbar-button .button-text {\n font-size: 13px;\n}\n\n/* ========================================\n Overflow Menu\n ======================================== */\n\n.toolbar-overflow {\n position: relative;\n}\n\n.overflow-trigger {\n padding: 6px 8px !important;\n}\n\n.overflow-trigger i {\n font-size: 16px;\n}\n\n.overflow-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 220px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);\n z-index: 1000;\n overflow: hidden;\n}\n\n.overflow-item {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n text-align: left;\n gap: 12px;\n transition: background-color 0.15s;\n}\n\n.overflow-item:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n}\n\n.overflow-item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.overflow-item i {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.overflow-item span {\n flex: 1;\n}\n\n.overflow-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n.overflow-section-label {\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n letter-spacing: 0.5px;\n}\n\n/* Entity Actions submenu styling */\n.overflow-item.action-item i {\n color: var(--mj-brand-primary);\n}\n\n/* ========================================\n Highlight Matches\n ======================================== */\n\n::ng-deep .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n padding: 0 1px;\n}\n\n/* ========================================\n AG Grid Customizations\n ======================================== */\n\n.mj-ag-grid {\n width: 100%;\n height: 100%;\n}\n\n/* AG Grid v35 uses JS-based theming (colorSchemeVariable) \u2014 no CSS variable overrides needed */\n\n/* Selected row styling - left indicator bar only, background handled by AG Grid theme */\n::ng-deep .ag-row-selected {\n box-shadow: inset 4px 0 0 0 var(--mj-status-warning);\n}\n\n/* Selection checkbox styling */\n::ng-deep .ag-checkbox-input-wrapper {\n width: 18px;\n height: 18px;\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n/* ========================================\n Visual Config: Header Styles\n ======================================== */\n\n/* Flat header (minimal) */\n.header-style-flat ::ng-deep .ag-header {\n background: var(--grid-header-bg, var(--mj-bg-surface-card));\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n/* Elevated header (default - subtle shadow) */\n.header-style-elevated ::ng-deep .ag-header {\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--grid-header-border-color, var(--mj-border-default));\n}\n\n.header-style-elevated.header-shadow ::ng-deep .ag-header {\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n/* Gradient header (more prominent) */\n.header-style-gradient ::ng-deep .ag-header {\n background: var(--mj-bg-surface-sunken);\n border-bottom: none;\n}\n\n.header-style-gradient.header-shadow ::ng-deep .ag-header {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n/* Bold header (high contrast) */\n.header-style-bold ::ng-deep .ag-header {\n background: var(--mj-text-secondary);\n border-bottom: none;\n}\n\n.header-style-bold ::ng-deep .ag-header-cell-text {\n color: var(--mj-text-inverse);\n font-weight: 600;\n}\n\n.header-style-bold ::ng-deep .ag-header-icon {\n color: color-mix(in srgb, var(--mj-text-inverse) 70%, transparent);\n}\n\n.header-style-bold ::ng-deep .ag-header-cell:hover {\n background: color-mix(in srgb, var(--mj-text-inverse) 10%, transparent);\n}\n\n/* Header sort icons enhancement */\n::ng-deep .ag-header-cell-sorted-asc .ag-icon-asc,\n::ng-deep .ag-header-cell-sorted-desc .ag-icon-desc {\n color: var(--grid-accent-color, var(--grid-sort-indicator-color, var(--mj-brand-primary)));\n}\n\n/* ========================================\n Visual Config: Zebra Striping\n ======================================== */\n\n/* Subtle contrast */\n.alternate-rows-subtle ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.015);\n}\n\n.alternate-rows-subtle ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* Medium contrast (default) */\n.alternate-rows-medium ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.025);\n}\n\n.alternate-rows-medium ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* Strong contrast */\n.alternate-rows-strong ::ng-deep .ag-row-odd {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.alternate-rows-strong ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--grid-row-hover-bg, var(--mj-bg-surface-hover));\n}\n\n/* ========================================\n Visual Config: Hover Transitions\n ======================================== */\n\n.hover-transitions ::ng-deep .ag-row {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n.hover-transitions ::ng-deep .ag-cell {\n transition: background-color var(--grid-hover-transition, 150ms) ease;\n}\n\n/* ========================================\n Visual Config: Cell Padding\n ======================================== */\n\n.cell-padding-compact ::ng-deep .ag-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-compact ::ng-deep .ag-header-cell {\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.cell-padding-normal ::ng-deep .ag-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-normal ::ng-deep .ag-header-cell {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n.cell-padding-comfortable ::ng-deep .ag-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n.cell-padding-comfortable ::ng-deep .ag-header-cell {\n padding-left: 16px;\n padding-right: 16px;\n}\n\n/* ========================================\n Visual Config: Checkbox Styles\n ======================================== */\n\n/* Rounded checkbox */\n.checkbox-style-rounded ::ng-deep .ag-checkbox-input-wrapper {\n border-radius: 4px;\n}\n\n.checkbox-style-rounded ::ng-deep .ag-checkbox-input-wrapper::after {\n border-radius: 3px;\n}\n\n/* Filled checkbox */\n.checkbox-style-filled ::ng-deep .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n border-color: var(--grid-checkbox-color, var(--mj-brand-primary));\n}\n\n.checkbox-style-filled ::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n/* ========================================\n Cell Content Formatting\n ======================================== */\n\n/* Right-aligned cells (numbers) */\n::ng-deep .cell-align-right {\n text-align: right;\n justify-content: flex-end;\n}\n\n::ng-deep .header-align-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n/* Empty cell placeholder */\n::ng-deep .cell-empty {\n color: var(--mj-text-disabled);\n font-style: normal;\n}\n\n/* Boolean icons */\n::ng-deep .cell-boolean-true {\n color: var(--mj-status-success);\n font-size: 14px;\n}\n\n::ng-deep .cell-boolean-false {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n/* Clickable links */\n::ng-deep .cell-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n transition: color 0.15s;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\n\n::ng-deep .cell-link:hover {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n}\n\n/* Email cells */\n::ng-deep .cell-email {\n font-family: inherit;\n font-size: 13px;\n}\n\n/* Foreign key link cells */\n::ng-deep .cell-fk-link {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s, text-decoration 0.15s;\n}\n\n::ng-deep .cell-fk-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n::ng-deep .cell-fk-link:active {\n color: var(--mj-brand-primary-active);\n}\n\n/* URL cells */\n::ng-deep .cell-url {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n font-size: 13px;\n}\n\n/* Phone cells */\n::ng-deep .cell-phone {\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.3px;\n}\n\n/* ========================================\n Skeleton Loading Animation\n ======================================== */\n\n@keyframes skeleton-shimmer {\n 0% {\n background-position: -200px 0;\n }\n 100% {\n background-position: calc(200px + 100%) 0;\n }\n}\n\n.skeleton-row {\n display: flex;\n height: 40px;\n align-items: center;\n padding: 0 12px;\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n.skeleton-cell {\n height: 16px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n var(--mj-bg-surface-sunken) 0px,\n var(--mj-bg-surface-hover) 40px,\n var(--mj-bg-surface-sunken) 80px\n );\n background-size: 200px 100%;\n animation: skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-cell-short {\n width: 60px;\n}\n\n.skeleton-cell-medium {\n width: 120px;\n}\n\n.skeleton-cell-long {\n width: 180px;\n}\n\n/* Selection checkbox column header */\n::ng-deep .ag-header-select-all {\n margin-right: 0;\n}\n\n/* ========================================\n Row Border Enhancement\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-row {\n border-bottom: 1px solid var(--grid-cell-border-color, var(--mj-border-subtle));\n}\n\n::ng-deep .ag-theme-alpine .ag-row:last-child {\n border-bottom: none;\n}\n\n/* ========================================\n Focus States\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-cell-focus {\n border: none !important;\n outline: none !important;\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:focus {\n outline: 2px solid var(--grid-accent-color, var(--mj-brand-primary));\n outline-offset: -2px;\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* ========================================\n Pinned Column Styling\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-pinned-left-cols-container {\n border-right: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n::ng-deep .ag-theme-alpine .ag-pinned-right-cols-container {\n border-left: 2px solid var(--grid-border-color, var(--mj-border-default));\n}\n\n/* ========================================\n Header Cell Enhancements\n ======================================== */\n\n::ng-deep .ag-theme-alpine .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell-sortable:hover .ag-header-cell-label {\n color: var(--grid-accent-color, var(--mj-brand-primary));\n}\n\n/* Sort icon animation */\n::ng-deep .ag-theme-alpine .ag-sort-indicator-icon {\n transition: transform 0.2s ease;\n}\n\n::ng-deep .ag-theme-alpine .ag-header-cell:hover .ag-sort-indicator-icon {\n transform: scale(1.1);\n}\n\n/* ========================================\n Enhanced Multi-Sort Indicators\n These styles use :host to ensure they're scoped to this component\n and !important to override AG Grid's built-in styles\n ======================================== */\n\n/* Highlight sorted column headers with eye-catching background */\n/* Ascending = blue tint */\n:host ::ng-deep .ag-header-cell-sorted-asc {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n/* Descending = pink tint */\n:host ::ng-deep .ag-header-cell-sorted-desc {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface)) !important;\n position: relative;\n}\n\n/* Bottom border accent for sorted columns - ascending = blue */\n:host ::ng-deep .ag-header-cell-sorted-asc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-brand-primary);\n}\n\n/* Bottom border accent for sorted columns - descending = pink */\n:host ::ng-deep .ag-header-cell-sorted-desc::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--mj-status-error);\n}\n\n/* Sorted column header text - ascending = blue, bold */\n:host ::ng-deep .ag-header-cell-sorted-asc .ag-header-cell-text {\n color: var(--mj-brand-primary) !important;\n font-weight: 700 !important;\n}\n\n/* Sorted column header text - descending = pink, bold */\n:host ::ng-deep .ag-header-cell-sorted-desc .ag-header-cell-text {\n color: var(--mj-status-error) !important;\n font-weight: 700 !important;\n}\n\n/* Sort icons - larger and more prominent */\n/* Ascending = blue */\n:host ::ng-deep .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n/* Descending = pink/magenta */\n:host ::ng-deep .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n:host ::ng-deep .ag-sort-ascending-icon .ag-icon,\n:host ::ng-deep .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n/* Sort order number (1, 2, 3) - show as plain number, no bubble */\n/* This avoids AG Grid bug where .ag-sort-order is always present but empty when unsorted */\n/* The number is only visible when AG Grid populates it (i.e., when column is sorted) */\n/* Default blue for ascending */\n:host ::ng-deep .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-brand-primary) !important;\n}\n\n/* Sort order number - pink for descending */\n:host ::ng-deep .ag-header-cell-sorted-desc .ag-sort-order {\n color: var(--mj-status-error) !important;\n}\n\n/* Hover state for sortable headers */\n:host ::ng-deep .ag-header-cell-sortable:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n:host ::ng-deep .ag-header-cell-sortable:hover .ag-header-cell-text {\n color: var(--mj-brand-primary);\n}\n\n/* ========================================\n Aggregate Summary Row\n ======================================== */\n\n.mj-aggregate-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n min-height: 44px;\n}\n\n.aggregate-summary-content {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n align-items: center;\n}\n\n.aggregate-summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n}\n\n.aggregate-summary-item i {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.agg-summary-label {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.agg-summary-value {\n color: var(--mj-text-primary);\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n\n.aggregate-loading {\n display: flex;\n align-items: center;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-loading i {\n font-size: 14px;\n}\n\n/* ========================================\n AGGREGATE CARDS (displayed above grid)\n ======================================== */\n\n.mj-aggregate-cards {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.aggregate-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n min-width: 140px;\n transition: all 0.15s ease;\n}\n\n.aggregate-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);\n}\n\n.aggregate-card-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.aggregate-card-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.aggregate-card-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.aggregate-card-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n.aggregate-card-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 12px;\n color: var(--mj-text-disabled);\n}\n\n.aggregate-card-loading i {\n font-size: 16px;\n}\n\n/* ========================================\n Text Wrapping Styles\n ======================================== */\n\n/* Cell class for wrapped text */\n::ng-deep .cell-wrap-text {\n white-space: normal !important;\n word-wrap: break-word;\n line-height: 1.4;\n padding-top: 8px !important;\n padding-bottom: 8px !important;\n}\n\n/* Ensure AG Grid cells allow wrapping */\n::ng-deep .ag-cell.cell-wrap-text {\n overflow: visible;\n text-overflow: clip;\n}\n\n/* Maintain minimum row height when wrapping */\n::ng-deep .ag-row[style*=\"auto-height\"] {\n min-height: 40px;\n}\n\n/* ========================================\n Width filler column ([FillWidth])\n ========================================\n The trailing filler exists so row banding and horizontal rules reach the container's right edge\n instead of stopping wherever the last real column ends. For that to read as \"the table extends\"\n rather than \"there is an empty column here\", it must lose every affordance that makes a column\n look like a column: its own vertical rule, the header hover/menu, and the resize handle. What is\n left is bare row background \u2014 which is exactly the point. */\n::ng-deep .ag-header-cell.mj-grid-filler-header,\n::ng-deep .ag-cell.mj-grid-filler-cell {\n border-left: none !important;\n border-right: none !important;\n cursor: default;\n}\n\n/* The hover tint is OURS (see \".ag-theme-alpine .ag-header-cell:hover\" above), not AG Grid's, so it\n has to be switched off here or the filler lights up as though it were interactive. Everything else\n the filler needs suppressed \u2014 resize grip, header menu, moving, tool-panel entry \u2014 is handled by\n native colDef flags on the column itself, not by CSS. */\n::ng-deep .ag-header-cell.mj-grid-filler-header:hover {\n background-color: transparent !important;\n}\n\n/* AG Grid injects cellRenderer HTML without Angular attributes, so these\n must pierce encapsulation or the image renders at intrinsic SVG size. */\n::ng-deep .ag-cell.mj-grid-image-cell {\n display: flex !important;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 4px !important;\n}\n::ng-deep .ag-header-cell.mj-grid-image-header .ag-header-cell-label {\n justify-content: center;\n}\n::ng-deep .cell-image-link {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n overflow: hidden;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n::ng-deep .cell-image {\n width: 100%;\n height: 100%;\n max-width: 28px;\n max-height: 28px;\n object-fit: cover;\n object-position: center;\n display: block;\n}\n"] }]
4851
5025
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.ExportService }, { type: i0.NgZone }], { Params: [{
4852
5026
  type: Input
4853
5027
  }], AllowLoad: [{