@memberjunction/ng-entity-viewer 5.41.0 → 5.43.0

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.
@@ -5,6 +5,7 @@ import { Subject } from 'rxjs';
5
5
  import { debounceTime, takeUntil } from 'rxjs/operators';
6
6
  import { RunView, RunViewParams } from '@memberjunction/core';
7
7
  import { UUIDsEqual } from '@memberjunction/global';
8
+ import { EntityActionEngineBase } from '@memberjunction/actions-base';
8
9
  import { buildPkString, computeFieldsList } from '../utils/record.util';
9
10
  import { ViewInfo, UserViewEngine, UserInfoEngine } from '@memberjunction/core-entities';
10
11
  import { ModuleRegistry, AllCommunityModule, themeAlpine } from 'ag-grid-community';
@@ -17,23 +18,24 @@ import * as i1 from "@memberjunction/ng-export-service";
17
18
  import * as i2 from "ag-grid-angular";
18
19
  import * as i3 from "@memberjunction/ng-shared-generic";
19
20
  import * as i4 from "@memberjunction/ng-pagination";
20
- import * as i5 from "../recycle-bin/recycle-bin-chip.component";
21
+ import * as i5 from "@memberjunction/ng-entity-action-ux";
22
+ import * as i6 from "../recycle-bin/recycle-bin-chip.component";
21
23
  const _c0 = ["gridContainer"];
22
24
  function EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
23
25
  const _r4 = i0.ɵɵgetCurrentView();
24
- i0.ɵɵelementStart(0, "button", 37);
26
+ i0.ɵɵelementStart(0, "button", 38);
25
27
  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 = ""); });
26
- i0.ɵɵelement(1, "i", 38);
28
+ i0.ɵɵelement(1, "i", 39);
27
29
  i0.ɵɵelementEnd();
28
30
  } }
29
31
  function EntityDataGridComponent_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
30
32
  const _r2 = i0.ɵɵgetCurrentView();
31
- i0.ɵɵelementStart(0, "div", 13);
32
- i0.ɵɵelement(1, "i", 34);
33
- i0.ɵɵelementStart(2, "input", 35);
33
+ i0.ɵɵelementStart(0, "div", 14);
34
+ i0.ɵɵelement(1, "i", 35);
35
+ i0.ɵɵelementStart(2, "input", 36);
34
36
  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); });
35
37
  i0.ɵɵelementEnd();
36
- i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template, 2, 0, "button", 36);
38
+ i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_2_Conditional_3_Template, 2, 0, "button", 37);
37
39
  i0.ɵɵelementEnd();
38
40
  } if (rf & 2) {
39
41
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -59,9 +61,9 @@ function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_2
59
61
  } }
60
62
  function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
61
63
  const _r5 = i0.ɵɵgetCurrentView();
62
- i0.ɵɵelementStart(0, "button", 40);
64
+ i0.ɵɵelementStart(0, "button", 41);
63
65
  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)); });
64
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_1_Template, 1, 2, "i", 41);
66
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_1_Template, 1, 2, "i", 42);
65
67
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Conditional_2_Template, 2, 1, "span");
66
68
  i0.ɵɵelementEnd();
67
69
  } if (rf & 2) {
@@ -75,14 +77,14 @@ function EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template(rf,
75
77
  i0.ɵɵconditional(button_r6.text ? 2 : -1);
76
78
  } }
77
79
  function EntityDataGridComponent_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
78
- i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template, 3, 6, "button", 39);
80
+ i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_4_Conditional_0_Template, 3, 6, "button", 40);
79
81
  } if (rf & 2) {
80
82
  const button_r6 = ctx.$implicit;
81
83
  const ctx_r2 = i0.ɵɵnextContext(2);
82
84
  i0.ɵɵconditional(button_r6.position !== "right" && ctx_r2.isButtonVisible(button_r6) ? 0 : -1);
83
85
  } }
84
86
  function EntityDataGridComponent_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
85
- i0.ɵɵelementStart(0, "span", 15);
87
+ i0.ɵɵelementStart(0, "span", 16);
86
88
  i0.ɵɵtext(1);
87
89
  i0.ɵɵelementEnd();
88
90
  } if (rf & 2) {
@@ -91,7 +93,7 @@ function EntityDataGridComponent_Conditional_2_Conditional_6_Template(rf, ctx) {
91
93
  i0.ɵɵtextInterpolate2(" ", ctx_r2.totalRowCount, " ", ctx_r2.totalRowCount === 1 ? "row" : "rows", " ");
92
94
  } }
93
95
  function EntityDataGridComponent_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
94
- i0.ɵɵelementStart(0, "span", 16);
96
+ i0.ɵɵelementStart(0, "span", 17);
95
97
  i0.ɵɵtext(1);
96
98
  i0.ɵɵelementEnd();
97
99
  } if (rf & 2) {
@@ -100,26 +102,26 @@ function EntityDataGridComponent_Conditional_2_Conditional_7_Template(rf, ctx) {
100
102
  i0.ɵɵtextInterpolate1(" (", ctx_r2.SelectedKeys.length, " selected) ");
101
103
  } }
102
104
  function EntityDataGridComponent_Conditional_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
103
- i0.ɵɵelement(0, "mj-recycle-bin-chip", 18);
105
+ i0.ɵɵelement(0, "mj-recycle-bin-chip", 19);
104
106
  } if (rf & 2) {
105
107
  const ctx_r2 = i0.ɵɵnextContext(2);
106
108
  i0.ɵɵproperty("EntityName", ctx_r2.entityInfoName);
107
109
  } }
108
110
  function EntityDataGridComponent_Conditional_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
109
111
  const _r7 = i0.ɵɵgetCurrentView();
110
- i0.ɵɵelementStart(0, "button", 42);
112
+ i0.ɵɵelementStart(0, "button", 43);
111
113
  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()); });
112
- i0.ɵɵelement(1, "i", 43);
113
- i0.ɵɵelementStart(2, "span", 44);
114
+ i0.ɵɵelement(1, "i", 44);
115
+ i0.ɵɵelementStart(2, "span", 45);
114
116
  i0.ɵɵtext(3, "New");
115
117
  i0.ɵɵelementEnd()();
116
118
  } }
117
119
  function EntityDataGridComponent_Conditional_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
118
120
  const _r8 = i0.ɵɵgetCurrentView();
119
- i0.ɵɵelementStart(0, "button", 45);
121
+ i0.ɵɵelementStart(0, "button", 46);
120
122
  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()); });
121
- i0.ɵɵelement(1, "i", 46);
122
- i0.ɵɵelementStart(2, "span", 44);
123
+ i0.ɵɵelement(1, "i", 47);
124
+ i0.ɵɵelementStart(2, "span", 45);
123
125
  i0.ɵɵtext(3, "Refresh");
124
126
  i0.ɵɵelementEnd()();
125
127
  } if (rf & 2) {
@@ -130,28 +132,28 @@ function EntityDataGridComponent_Conditional_2_Conditional_11_Template(rf, ctx)
130
132
  } }
131
133
  function EntityDataGridComponent_Conditional_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
132
134
  const _r9 = i0.ɵɵgetCurrentView();
133
- i0.ɵɵelementStart(0, "button", 47);
135
+ i0.ɵɵelementStart(0, "button", 48);
134
136
  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()); });
135
- i0.ɵɵelement(1, "i", 48);
136
- i0.ɵɵelementStart(2, "span", 44);
137
+ i0.ɵɵelement(1, "i", 49);
138
+ i0.ɵɵelementStart(2, "span", 45);
137
139
  i0.ɵɵtext(3, "Export");
138
140
  i0.ɵɵelementEnd()();
139
141
  } }
140
142
  function EntityDataGridComponent_Conditional_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
141
143
  const _r10 = i0.ɵɵgetCurrentView();
142
- i0.ɵɵelementStart(0, "button", 49);
144
+ i0.ɵɵelementStart(0, "button", 50);
143
145
  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()); });
144
- i0.ɵɵelement(1, "i", 50);
145
- i0.ɵɵelementStart(2, "span", 44);
146
+ i0.ɵɵelement(1, "i", 51);
147
+ i0.ɵɵelementStart(2, "span", 45);
146
148
  i0.ɵɵtext(3, "Delete");
147
149
  i0.ɵɵelementEnd()();
148
150
  } }
149
151
  function EntityDataGridComponent_Conditional_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
150
152
  const _r11 = i0.ɵɵgetCurrentView();
151
- i0.ɵɵelementStart(0, "button", 51);
153
+ i0.ɵɵelementStart(0, "button", 52);
152
154
  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()); });
153
- i0.ɵɵelement(1, "i", 52);
154
- i0.ɵɵelementStart(2, "span", 44);
155
+ i0.ɵɵelement(1, "i", 53);
156
+ i0.ɵɵelementStart(2, "span", 45);
155
157
  i0.ɵɵtext(3, "Compare");
156
158
  i0.ɵɵelementEnd()();
157
159
  } if (rf & 2) {
@@ -160,10 +162,10 @@ function EntityDataGridComponent_Conditional_2_Conditional_14_Template(rf, ctx)
160
162
  } }
161
163
  function EntityDataGridComponent_Conditional_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
162
164
  const _r12 = i0.ɵɵgetCurrentView();
163
- i0.ɵɵelementStart(0, "button", 53);
165
+ i0.ɵɵelementStart(0, "button", 54);
164
166
  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()); });
165
- i0.ɵɵelement(1, "i", 54);
166
- i0.ɵɵelementStart(2, "span", 44);
167
+ i0.ɵɵelement(1, "i", 55);
168
+ i0.ɵɵelementStart(2, "span", 45);
167
169
  i0.ɵɵtext(3, "Merge");
168
170
  i0.ɵɵelementEnd()();
169
171
  } if (rf & 2) {
@@ -172,10 +174,10 @@ function EntityDataGridComponent_Conditional_2_Conditional_15_Template(rf, ctx)
172
174
  } }
173
175
  function EntityDataGridComponent_Conditional_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
174
176
  const _r13 = i0.ɵɵgetCurrentView();
175
- i0.ɵɵelementStart(0, "button", 55);
177
+ i0.ɵɵelementStart(0, "button", 56);
176
178
  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()); });
177
- i0.ɵɵelement(1, "i", 56);
178
- i0.ɵɵelementStart(2, "span", 44);
179
+ i0.ɵɵelement(1, "i", 57);
180
+ i0.ɵɵelementStart(2, "span", 45);
179
181
  i0.ɵɵtext(3, "Add to List");
180
182
  i0.ɵɵelementEnd()();
181
183
  } if (rf & 2) {
@@ -184,10 +186,10 @@ function EntityDataGridComponent_Conditional_2_Conditional_16_Template(rf, ctx)
184
186
  } }
185
187
  function EntityDataGridComponent_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
186
188
  const _r14 = i0.ɵɵgetCurrentView();
187
- i0.ɵɵelementStart(0, "button", 57);
189
+ i0.ɵɵelementStart(0, "button", 58);
188
190
  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()); });
189
- i0.ɵɵelement(1, "i", 58);
190
- i0.ɵɵelementStart(2, "span", 44);
191
+ i0.ɵɵelement(1, "i", 59);
192
+ i0.ɵɵelementStart(2, "span", 45);
191
193
  i0.ɵɵtext(3, "Find Duplicates");
192
194
  i0.ɵɵelementEnd()();
193
195
  } if (rf & 2) {
@@ -196,10 +198,10 @@ function EntityDataGridComponent_Conditional_2_Conditional_17_Template(rf, ctx)
196
198
  } }
197
199
  function EntityDataGridComponent_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
198
200
  const _r15 = i0.ɵɵgetCurrentView();
199
- i0.ɵɵelementStart(0, "button", 59);
201
+ i0.ɵɵelementStart(0, "button", 60);
200
202
  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()); });
201
- i0.ɵɵelement(1, "i", 60);
202
- i0.ɵɵelementStart(2, "span", 44);
203
+ i0.ɵɵelement(1, "i", 61);
204
+ i0.ɵɵelementStart(2, "span", 45);
203
205
  i0.ɵɵtext(3, "Send Message");
204
206
  i0.ɵɵelementEnd()();
205
207
  } if (rf & 2) {
@@ -208,16 +210,16 @@ function EntityDataGridComponent_Conditional_2_Conditional_18_Template(rf, ctx)
208
210
  } }
209
211
  function EntityDataGridComponent_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
210
212
  const _r16 = i0.ɵɵgetCurrentView();
211
- i0.ɵɵelementStart(0, "button", 61);
213
+ i0.ɵɵelementStart(0, "button", 62);
212
214
  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()); });
213
- i0.ɵɵelement(1, "i", 43);
215
+ i0.ɵɵelement(1, "i", 44);
214
216
  i0.ɵɵelementEnd();
215
217
  } }
216
218
  function EntityDataGridComponent_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
217
219
  const _r17 = i0.ɵɵgetCurrentView();
218
- i0.ɵɵelementStart(0, "button", 62);
220
+ i0.ɵɵelementStart(0, "button", 63);
219
221
  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()); });
220
- i0.ɵɵelement(1, "i", 63);
222
+ i0.ɵɵelement(1, "i", 64);
221
223
  i0.ɵɵelementEnd();
222
224
  } if (rf & 2) {
223
225
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -227,23 +229,23 @@ function EntityDataGridComponent_Conditional_2_Conditional_20_Template(rf, ctx)
227
229
  } }
228
230
  function EntityDataGridComponent_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
229
231
  const _r18 = i0.ɵɵgetCurrentView();
230
- i0.ɵɵelementStart(0, "button", 64);
232
+ i0.ɵɵelementStart(0, "button", 65);
231
233
  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()); });
232
- i0.ɵɵelement(1, "i", 50);
234
+ i0.ɵɵelement(1, "i", 51);
233
235
  i0.ɵɵelementEnd();
234
236
  } }
235
237
  function EntityDataGridComponent_Conditional_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
236
238
  const _r19 = i0.ɵɵgetCurrentView();
237
- i0.ɵɵelementStart(0, "button", 65);
239
+ i0.ɵɵelementStart(0, "button", 66);
238
240
  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()); });
239
- i0.ɵɵelement(1, "i", 66);
241
+ i0.ɵɵelement(1, "i", 67);
240
242
  i0.ɵɵelementEnd();
241
243
  } }
242
244
  function EntityDataGridComponent_Conditional_2_Conditional_23_Template(rf, ctx) { if (rf & 1) {
243
245
  const _r20 = i0.ɵɵgetCurrentView();
244
- i0.ɵɵelementStart(0, "button", 67);
246
+ i0.ɵɵelementStart(0, "button", 68);
245
247
  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()); });
246
- i0.ɵɵelement(1, "i", 68);
248
+ i0.ɵɵelement(1, "i", 69);
247
249
  i0.ɵɵelementEnd();
248
250
  } }
249
251
  function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -263,9 +265,9 @@ function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_
263
265
  } }
264
266
  function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template(rf, ctx) { if (rf & 1) {
265
267
  const _r21 = i0.ɵɵgetCurrentView();
266
- i0.ɵɵelementStart(0, "button", 40);
268
+ i0.ɵɵelementStart(0, "button", 41);
267
269
  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)); });
268
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_1_Template, 1, 2, "i", 41);
270
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_1_Template, 1, 2, "i", 42);
269
271
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Conditional_2_Template, 2, 1, "span");
270
272
  i0.ɵɵelementEnd();
271
273
  } if (rf & 2) {
@@ -279,7 +281,7 @@ function EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template(rf,
279
281
  i0.ɵɵconditional(button_r22.text ? 2 : -1);
280
282
  } }
281
283
  function EntityDataGridComponent_Conditional_2_For_25_Template(rf, ctx) { if (rf & 1) {
282
- i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template, 3, 6, "button", 39);
284
+ i0.ɵɵconditionalCreate(0, EntityDataGridComponent_Conditional_2_For_25_Conditional_0_Template, 3, 6, "button", 40);
283
285
  } if (rf & 2) {
284
286
  const button_r22 = ctx.$implicit;
285
287
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -287,16 +289,16 @@ function EntityDataGridComponent_Conditional_2_For_25_Template(rf, ctx) { if (rf
287
289
  } }
288
290
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
289
291
  const _r24 = i0.ɵɵgetCurrentView();
290
- i0.ɵɵelementStart(0, "button", 75);
292
+ i0.ɵɵelementStart(0, "button", 76);
291
293
  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()); });
292
- i0.ɵɵelement(1, "i", 48);
294
+ i0.ɵɵelement(1, "i", 49);
293
295
  i0.ɵɵelementStart(2, "span");
294
296
  i0.ɵɵtext(3, "Export to Excel");
295
297
  i0.ɵɵelementEnd()();
296
298
  } }
297
299
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
298
300
  const _r25 = i0.ɵɵgetCurrentView();
299
- i0.ɵɵelementStart(0, "button", 78);
301
+ i0.ɵɵelementStart(0, "button", 79);
300
302
  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()); });
301
303
  i0.ɵɵelement(1, "i");
302
304
  i0.ɵɵelementStart(2, "span");
@@ -312,51 +314,51 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Cond
312
314
  i0.ɵɵtextInterpolate(action_r26.name);
313
315
  } }
314
316
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
315
- i0.ɵɵelement(0, "div", 74);
316
- i0.ɵɵelementStart(1, "div", 76);
317
+ i0.ɵɵelement(0, "div", 75);
318
+ i0.ɵɵelementStart(1, "div", 77);
317
319
  i0.ɵɵtext(2, "Actions");
318
320
  i0.ɵɵelementEnd();
319
- i0.ɵɵrepeaterCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template, 4, 4, "button", 77, i0.ɵɵrepeaterTrackByIdentity);
321
+ i0.ɵɵrepeaterCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_For_4_Template, 4, 4, "button", 78, i0.ɵɵrepeaterTrackByIdentity);
320
322
  } if (rf & 2) {
321
323
  const ctx_r2 = i0.ɵɵnextContext(4);
322
324
  i0.ɵɵadvance(3);
323
325
  i0.ɵɵrepeater(ctx_r2.EntityActions);
324
326
  } }
325
327
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
326
- i0.ɵɵelement(0, "div", 74);
328
+ i0.ɵɵelement(0, "div", 75);
327
329
  } }
328
330
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
329
331
  const _r27 = i0.ɵɵgetCurrentView();
330
- i0.ɵɵelementStart(0, "button", 75);
332
+ i0.ɵɵelementStart(0, "button", 76);
331
333
  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()); });
332
- i0.ɵɵelement(1, "i", 68);
334
+ i0.ɵɵelement(1, "i", 69);
333
335
  i0.ɵɵelementStart(2, "span");
334
336
  i0.ɵɵtext(3, "Manage Columns");
335
337
  i0.ɵɵelementEnd()();
336
338
  } }
337
339
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
338
340
  const _r28 = i0.ɵɵgetCurrentView();
339
- i0.ɵɵelementStart(0, "button", 75);
341
+ i0.ɵɵelementStart(0, "button", 76);
340
342
  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()); });
341
- i0.ɵɵelement(1, "i", 60);
343
+ i0.ɵɵelement(1, "i", 61);
342
344
  i0.ɵɵelementStart(2, "span");
343
345
  i0.ɵɵtext(3, "Send Message");
344
346
  i0.ɵɵelementEnd()();
345
347
  } }
346
348
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
347
- i0.ɵɵelement(0, "div", 74);
348
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template, 4, 0, "button", 73);
349
+ i0.ɵɵelement(0, "div", 75);
350
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Conditional_1_Template, 4, 0, "button", 74);
349
351
  } if (rf & 2) {
350
352
  const ctx_r2 = i0.ɵɵnextContext(4);
351
353
  i0.ɵɵadvance();
352
354
  i0.ɵɵconditional(ctx_r2.showCommunicationInOverflow ? 1 : -1);
353
355
  } }
354
356
  function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
355
- i0.ɵɵelementStart(0, "div", 72);
356
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template, 4, 0, "button", 73);
357
+ i0.ɵɵelementStart(0, "div", 73);
358
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_1_Template, 4, 0, "button", 74);
357
359
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_2_Template, 5, 0);
358
- i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_3_Template, 1, 0, "div", 74);
359
- i0.ɵɵconditionalCreate(4, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template, 4, 0, "button", 73);
360
+ i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_3_Template, 1, 0, "div", 75);
361
+ i0.ɵɵconditionalCreate(4, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_4_Template, 4, 0, "button", 74);
360
362
  i0.ɵɵconditionalCreate(5, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Conditional_5_Template, 2, 1);
361
363
  i0.ɵɵelementEnd();
362
364
  } if (rf & 2) {
@@ -375,13 +377,13 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Temp
375
377
  } }
376
378
  function EntityDataGridComponent_Conditional_2_Conditional_26_Template(rf, ctx) { if (rf & 1) {
377
379
  const _r23 = i0.ɵɵgetCurrentView();
378
- i0.ɵɵelementStart(0, "div", 69);
380
+ i0.ɵɵelementStart(0, "div", 70);
379
381
  i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_2_Conditional_26_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r23); return i0.ɵɵresetView($event.stopPropagation()); });
380
- i0.ɵɵelementStart(1, "button", 70);
382
+ i0.ɵɵelementStart(1, "button", 71);
381
383
  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()); });
382
- i0.ɵɵelement(2, "i", 71);
384
+ i0.ɵɵelement(2, "i", 72);
383
385
  i0.ɵɵelementEnd();
384
- i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Template, 6, 6, "div", 72);
386
+ i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_2_Conditional_26_Conditional_3_Template, 6, 6, "div", 73);
385
387
  i0.ɵɵelementEnd();
386
388
  } if (rf & 2) {
387
389
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -389,32 +391,32 @@ function EntityDataGridComponent_Conditional_2_Conditional_26_Template(rf, ctx)
389
391
  i0.ɵɵconditional(ctx_r2.showOverflowMenu ? 3 : -1);
390
392
  } }
391
393
  function EntityDataGridComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
392
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 12);
393
- i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_Conditional_2_Template, 4, 3, "div", 13);
394
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 13);
395
+ i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_Conditional_2_Template, 4, 3, "div", 14);
394
396
  i0.ɵɵrepeaterCreate(3, EntityDataGridComponent_Conditional_2_For_4_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
395
397
  i0.ɵɵelementEnd();
396
- i0.ɵɵelementStart(5, "div", 14);
397
- i0.ɵɵconditionalCreate(6, EntityDataGridComponent_Conditional_2_Conditional_6_Template, 2, 2, "span", 15);
398
- i0.ɵɵconditionalCreate(7, EntityDataGridComponent_Conditional_2_Conditional_7_Template, 2, 1, "span", 16);
398
+ i0.ɵɵelementStart(5, "div", 15);
399
+ i0.ɵɵconditionalCreate(6, EntityDataGridComponent_Conditional_2_Conditional_6_Template, 2, 2, "span", 16);
400
+ i0.ɵɵconditionalCreate(7, EntityDataGridComponent_Conditional_2_Conditional_7_Template, 2, 1, "span", 17);
399
401
  i0.ɵɵelementEnd();
400
- i0.ɵɵelementStart(8, "div", 17);
401
- i0.ɵɵconditionalCreate(9, EntityDataGridComponent_Conditional_2_Conditional_9_Template, 1, 1, "mj-recycle-bin-chip", 18);
402
- i0.ɵɵconditionalCreate(10, EntityDataGridComponent_Conditional_2_Conditional_10_Template, 4, 0, "button", 19);
403
- i0.ɵɵconditionalCreate(11, EntityDataGridComponent_Conditional_2_Conditional_11_Template, 4, 3, "button", 20);
404
- i0.ɵɵconditionalCreate(12, EntityDataGridComponent_Conditional_2_Conditional_12_Template, 4, 0, "button", 21);
405
- i0.ɵɵconditionalCreate(13, EntityDataGridComponent_Conditional_2_Conditional_13_Template, 4, 0, "button", 22);
406
- i0.ɵɵconditionalCreate(14, EntityDataGridComponent_Conditional_2_Conditional_14_Template, 4, 1, "button", 23);
407
- i0.ɵɵconditionalCreate(15, EntityDataGridComponent_Conditional_2_Conditional_15_Template, 4, 1, "button", 24);
408
- i0.ɵɵconditionalCreate(16, EntityDataGridComponent_Conditional_2_Conditional_16_Template, 4, 1, "button", 25);
409
- i0.ɵɵconditionalCreate(17, EntityDataGridComponent_Conditional_2_Conditional_17_Template, 4, 1, "button", 26);
410
- i0.ɵɵconditionalCreate(18, EntityDataGridComponent_Conditional_2_Conditional_18_Template, 4, 1, "button", 27);
411
- i0.ɵɵconditionalCreate(19, EntityDataGridComponent_Conditional_2_Conditional_19_Template, 2, 0, "button", 28);
412
- i0.ɵɵconditionalCreate(20, EntityDataGridComponent_Conditional_2_Conditional_20_Template, 2, 3, "button", 29);
413
- i0.ɵɵconditionalCreate(21, EntityDataGridComponent_Conditional_2_Conditional_21_Template, 2, 0, "button", 30);
414
- i0.ɵɵconditionalCreate(22, EntityDataGridComponent_Conditional_2_Conditional_22_Template, 2, 0, "button", 31);
415
- i0.ɵɵconditionalCreate(23, EntityDataGridComponent_Conditional_2_Conditional_23_Template, 2, 0, "button", 32);
402
+ i0.ɵɵelementStart(8, "div", 18);
403
+ i0.ɵɵconditionalCreate(9, EntityDataGridComponent_Conditional_2_Conditional_9_Template, 1, 1, "mj-recycle-bin-chip", 19);
404
+ i0.ɵɵconditionalCreate(10, EntityDataGridComponent_Conditional_2_Conditional_10_Template, 4, 0, "button", 20);
405
+ i0.ɵɵconditionalCreate(11, EntityDataGridComponent_Conditional_2_Conditional_11_Template, 4, 3, "button", 21);
406
+ i0.ɵɵconditionalCreate(12, EntityDataGridComponent_Conditional_2_Conditional_12_Template, 4, 0, "button", 22);
407
+ i0.ɵɵconditionalCreate(13, EntityDataGridComponent_Conditional_2_Conditional_13_Template, 4, 0, "button", 23);
408
+ i0.ɵɵconditionalCreate(14, EntityDataGridComponent_Conditional_2_Conditional_14_Template, 4, 1, "button", 24);
409
+ i0.ɵɵconditionalCreate(15, EntityDataGridComponent_Conditional_2_Conditional_15_Template, 4, 1, "button", 25);
410
+ i0.ɵɵconditionalCreate(16, EntityDataGridComponent_Conditional_2_Conditional_16_Template, 4, 1, "button", 26);
411
+ i0.ɵɵconditionalCreate(17, EntityDataGridComponent_Conditional_2_Conditional_17_Template, 4, 1, "button", 27);
412
+ i0.ɵɵconditionalCreate(18, EntityDataGridComponent_Conditional_2_Conditional_18_Template, 4, 1, "button", 28);
413
+ i0.ɵɵconditionalCreate(19, EntityDataGridComponent_Conditional_2_Conditional_19_Template, 2, 0, "button", 29);
414
+ i0.ɵɵconditionalCreate(20, EntityDataGridComponent_Conditional_2_Conditional_20_Template, 2, 3, "button", 30);
415
+ i0.ɵɵconditionalCreate(21, EntityDataGridComponent_Conditional_2_Conditional_21_Template, 2, 0, "button", 31);
416
+ i0.ɵɵconditionalCreate(22, EntityDataGridComponent_Conditional_2_Conditional_22_Template, 2, 0, "button", 32);
417
+ i0.ɵɵconditionalCreate(23, EntityDataGridComponent_Conditional_2_Conditional_23_Template, 2, 0, "button", 33);
416
418
  i0.ɵɵrepeaterCreate(24, EntityDataGridComponent_Conditional_2_For_25_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
417
- i0.ɵɵconditionalCreate(26, EntityDataGridComponent_Conditional_2_Conditional_26_Template, 4, 1, "div", 33);
419
+ i0.ɵɵconditionalCreate(26, EntityDataGridComponent_Conditional_2_Conditional_26_Template, 4, 1, "div", 34);
418
420
  i0.ɵɵelementEnd()();
419
421
  } if (rf & 2) {
420
422
  const ctx_r2 = i0.ɵɵnextContext();
@@ -462,7 +464,7 @@ function EntityDataGridComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
462
464
  i0.ɵɵconditional(ctx_r2.hasOverflowMenuItems ? 26 : -1);
463
465
  } }
464
466
  function EntityDataGridComponent_Conditional_3_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
465
- i0.ɵɵelementStart(0, "div", 81);
467
+ i0.ɵɵelementStart(0, "div", 82);
466
468
  i0.ɵɵelement(1, "i");
467
469
  i0.ɵɵelementEnd();
468
470
  } if (rf & 2) {
@@ -471,12 +473,12 @@ function EntityDataGridComponent_Conditional_3_For_2_Conditional_1_Template(rf,
471
473
  i0.ɵɵclassMap(agg_r29.icon);
472
474
  } }
473
475
  function EntityDataGridComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
474
- i0.ɵɵelementStart(0, "div", 79);
475
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_3_For_2_Conditional_1_Template, 2, 2, "div", 81);
476
- i0.ɵɵelementStart(2, "div", 82)(3, "span", 83);
476
+ i0.ɵɵelementStart(0, "div", 80);
477
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_3_For_2_Conditional_1_Template, 2, 2, "div", 82);
478
+ i0.ɵɵelementStart(2, "div", 83)(3, "span", 84);
477
479
  i0.ɵɵtext(4);
478
480
  i0.ɵɵelementEnd();
479
- i0.ɵɵelementStart(5, "span", 84);
481
+ i0.ɵɵelementStart(5, "span", 85);
480
482
  i0.ɵɵtext(6);
481
483
  i0.ɵɵelementEnd()()();
482
484
  } if (rf & 2) {
@@ -490,14 +492,14 @@ function EntityDataGridComponent_Conditional_3_For_2_Template(rf, ctx) { if (rf
490
492
  i0.ɵɵtextInterpolate(ctx_r2.getAggregateValue(agg_r29));
491
493
  } }
492
494
  function EntityDataGridComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
493
- i0.ɵɵelementStart(0, "div", 80);
494
- i0.ɵɵelement(1, "i", 85);
495
+ i0.ɵɵelementStart(0, "div", 81);
496
+ i0.ɵɵelement(1, "i", 86);
495
497
  i0.ɵɵelementEnd();
496
498
  } }
497
499
  function EntityDataGridComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
498
500
  i0.ɵɵelementStart(0, "div", 2);
499
- i0.ɵɵrepeaterCreate(1, EntityDataGridComponent_Conditional_3_For_2_Template, 7, 3, "div", 79, i0.ɵɵrepeaterTrackByIdentity);
500
- i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_3_Conditional_3_Template, 2, 0, "div", 80);
501
+ i0.ɵɵrepeaterCreate(1, EntityDataGridComponent_Conditional_3_For_2_Template, 7, 3, "div", 80, i0.ɵɵrepeaterTrackByIdentity);
502
+ i0.ɵɵconditionalCreate(3, EntityDataGridComponent_Conditional_3_Conditional_3_Template, 2, 0, "div", 81);
501
503
  i0.ɵɵelementEnd();
502
504
  } if (rf & 2) {
503
505
  const ctx_r2 = i0.ɵɵnextContext();
@@ -508,17 +510,17 @@ function EntityDataGridComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
508
510
  } }
509
511
  function EntityDataGridComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
510
512
  i0.ɵɵelementStart(0, "div", 4);
511
- i0.ɵɵelement(1, "mj-loading", 86);
513
+ i0.ɵɵelement(1, "mj-loading", 87);
512
514
  i0.ɵɵelementEnd();
513
515
  } }
514
516
  function EntityDataGridComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
515
517
  const _r30 = i0.ɵɵgetCurrentView();
516
518
  i0.ɵɵelementStart(0, "div", 5);
517
- i0.ɵɵelement(1, "i", 87);
519
+ i0.ɵɵelement(1, "i", 88);
518
520
  i0.ɵɵelementStart(2, "span");
519
521
  i0.ɵɵtext(3);
520
522
  i0.ɵɵelementEnd();
521
- i0.ɵɵelementStart(4, "button", 88);
523
+ i0.ɵɵelementStart(4, "button", 89);
522
524
  i0.ɵɵlistener("click", function EntityDataGridComponent_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r30); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Refresh()); });
523
525
  i0.ɵɵtext(5, "Retry");
524
526
  i0.ɵɵelementEnd()();
@@ -529,14 +531,14 @@ function EntityDataGridComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
529
531
  } }
530
532
  function EntityDataGridComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
531
533
  i0.ɵɵelementStart(0, "div", 6);
532
- i0.ɵɵelement(1, "i", 89);
534
+ i0.ɵɵelement(1, "i", 90);
533
535
  i0.ɵɵelementStart(2, "span");
534
536
  i0.ɵɵtext(3, "No data to display");
535
537
  i0.ɵɵelementEnd()();
536
538
  } }
537
539
  function EntityDataGridComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
538
540
  const _r31 = i0.ɵɵgetCurrentView();
539
- i0.ɵɵelementStart(0, "ag-grid-angular", 90);
541
+ i0.ɵɵelementStart(0, "ag-grid-angular", 91);
540
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)); });
541
543
  i0.ɵɵelementEnd();
542
544
  } if (rf & 2) {
@@ -545,7 +547,7 @@ function EntityDataGridComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
545
547
  } }
546
548
  function EntityDataGridComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
547
549
  const _r32 = i0.ɵɵgetCurrentView();
548
- i0.ɵɵelementStart(0, "ag-grid-angular", 91);
550
+ i0.ɵɵelementStart(0, "ag-grid-angular", 92);
549
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)); });
550
552
  i0.ɵɵelementEnd();
551
553
  } if (rf & 2) {
@@ -554,7 +556,7 @@ function EntityDataGridComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
554
556
  } }
555
557
  function EntityDataGridComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
556
558
  const _r33 = i0.ɵɵgetCurrentView();
557
- i0.ɵɵelementStart(0, "mj-pagination", 92);
559
+ i0.ɵɵelementStart(0, "mj-pagination", 93);
558
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)); });
559
561
  i0.ɵɵelementEnd();
560
562
  } if (rf & 2) {
@@ -568,12 +570,12 @@ function EntityDataGridComponent_Conditional_11_For_3_Conditional_1_Template(rf,
568
570
  i0.ɵɵclassMap(agg_r34.icon);
569
571
  } }
570
572
  function EntityDataGridComponent_Conditional_11_For_3_Template(rf, ctx) { if (rf & 1) {
571
- i0.ɵɵelementStart(0, "div", 94);
572
- i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_11_For_3_Conditional_1_Template, 1, 2, "i", 41);
573
- i0.ɵɵelementStart(2, "span", 96);
573
+ i0.ɵɵelementStart(0, "div", 95);
574
+ i0.ɵɵconditionalCreate(1, EntityDataGridComponent_Conditional_11_For_3_Conditional_1_Template, 1, 2, "i", 42);
575
+ i0.ɵɵelementStart(2, "span", 97);
574
576
  i0.ɵɵtext(3);
575
577
  i0.ɵɵelementEnd();
576
- i0.ɵɵelementStart(4, "span", 97);
578
+ i0.ɵɵelementStart(4, "span", 98);
577
579
  i0.ɵɵtext(5);
578
580
  i0.ɵɵelementEnd()();
579
581
  } if (rf & 2) {
@@ -587,15 +589,15 @@ function EntityDataGridComponent_Conditional_11_For_3_Template(rf, ctx) { if (rf
587
589
  i0.ɵɵtextInterpolate(ctx_r2.getAggregateValue(agg_r34));
588
590
  } }
589
591
  function EntityDataGridComponent_Conditional_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
590
- i0.ɵɵelementStart(0, "div", 95);
591
- i0.ɵɵelement(1, "i", 85);
592
+ i0.ɵɵelementStart(0, "div", 96);
593
+ i0.ɵɵelement(1, "i", 86);
592
594
  i0.ɵɵelementEnd();
593
595
  } }
594
596
  function EntityDataGridComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
595
- i0.ɵɵelementStart(0, "div", 10)(1, "div", 93);
596
- i0.ɵɵrepeaterCreate(2, EntityDataGridComponent_Conditional_11_For_3_Template, 6, 3, "div", 94, i0.ɵɵrepeaterTrackByIdentity);
597
+ i0.ɵɵelementStart(0, "div", 10)(1, "div", 94);
598
+ i0.ɵɵrepeaterCreate(2, EntityDataGridComponent_Conditional_11_For_3_Template, 6, 3, "div", 95, i0.ɵɵrepeaterTrackByIdentity);
597
599
  i0.ɵɵelementEnd();
598
- i0.ɵɵconditionalCreate(4, EntityDataGridComponent_Conditional_11_Conditional_4_Template, 2, 0, "div", 95);
600
+ i0.ɵɵconditionalCreate(4, EntityDataGridComponent_Conditional_11_Conditional_4_Template, 2, 0, "div", 96);
599
601
  i0.ɵɵelementEnd();
600
602
  } if (rf & 2) {
601
603
  const ctx_r2 = i0.ɵɵnextContext();
@@ -604,6 +606,15 @@ function EntityDataGridComponent_Conditional_11_Template(rf, ctx) { if (rf & 1)
604
606
  i0.ɵɵadvance(2);
605
607
  i0.ɵɵconditional(ctx_r2.AggregatesLoading ? 4 : -1);
606
608
  } }
609
+ function EntityDataGridComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
610
+ const _r35 = i0.ɵɵgetCurrentView();
611
+ i0.ɵɵelementStart(0, "mj-entity-action-ux-host", 99);
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()); });
613
+ i0.ɵɵelementEnd();
614
+ } if (rf & 2) {
615
+ const ctx_r2 = i0.ɵɵnextContext();
616
+ i0.ɵɵproperty("DriverClass", ctx_r2.ActiveRuntimeDriver.DriverClass)("Context", ctx_r2.ActiveRuntimeDriver.Context);
617
+ } }
607
618
  // Register AG Grid modules (required for v34+)
608
619
  ModuleRegistry.registerModules([AllCommunityModule]);
609
620
  /**
@@ -1309,6 +1320,60 @@ export class EntityDataGridComponent extends BaseAngularComponent {
1309
1320
  get EntityActions() {
1310
1321
  return this._entityActions;
1311
1322
  }
1323
+ _autoLoadEntityActions = false;
1324
+ _entityActionsAutoLoaded = false;
1325
+ /**
1326
+ * When true, the grid resolves the current entity's active EntityActions itself (via the metadata-only
1327
+ * `EntityActionEngineBase`) and shows them — no parent wiring or `LoadEntityActionsRequested` handler
1328
+ * needed. Buttons appear only when the entity actually has active actions (data-driven). Actions whose
1329
+ * invocation names a `RuntimeUXDriverClass` mount that interactive driver in-place when clicked.
1330
+ */
1331
+ set AutoLoadEntityActions(value) {
1332
+ this._autoLoadEntityActions = value;
1333
+ void this.maybeAutoLoadEntityActions();
1334
+ }
1335
+ get AutoLoadEntityActions() {
1336
+ return this._autoLoadEntityActions;
1337
+ }
1338
+ /** Loads + maps the entity's active actions once, when auto-load is on and the entity is known. */
1339
+ async maybeAutoLoadEntityActions() {
1340
+ if (!this._autoLoadEntityActions || !this._entityInfo || this._entityActionsAutoLoaded) {
1341
+ return;
1342
+ }
1343
+ this._entityActionsAutoLoaded = true;
1344
+ try {
1345
+ const provider = this.ProviderToUse;
1346
+ await EntityActionEngineBase.Instance.Config(false, provider?.CurrentUser, provider);
1347
+ const configs = this.mapEntityActionsToConfigs(this._entityInfo.Name);
1348
+ if (configs.length > 0) {
1349
+ this._entityActions = configs;
1350
+ this._showEntityActionButtons = true;
1351
+ this.cdr.detectChanges();
1352
+ }
1353
+ }
1354
+ catch {
1355
+ // Non-fatal: leave the action bar empty if the engine can't load.
1356
+ this._entityActionsAutoLoaded = false;
1357
+ }
1358
+ }
1359
+ /** Maps the entity's active EntityActions to grid configs, carrying the driver key + RecordProcessID. */
1360
+ mapEntityActionsToConfigs(entityName) {
1361
+ const engine = EntityActionEngineBase.Instance;
1362
+ return engine.GetActionsByEntityName(entityName, 'Active').map((ea) => {
1363
+ const driverInvocation = engine.Invocations.find(i => UUIDsEqual(i.EntityActionID, ea.ID) && !!i.RuntimeUXDriverClass);
1364
+ const recordProcessParam = engine.Params.find(p => UUIDsEqual(p.EntityActionID, ea.ID) && p.ActionParam?.trim().toLowerCase() === 'recordprocessid');
1365
+ const config = {
1366
+ id: ea.ID,
1367
+ name: ea.Action ?? 'Action',
1368
+ icon: 'fa-solid fa-bolt',
1369
+ runtimeUXDriverClass: driverInvocation?.RuntimeUXDriverClass ?? undefined,
1370
+ };
1371
+ if (recordProcessParam?.Value) {
1372
+ config.metadata = { RecordProcessID: recordProcessParam.Value };
1373
+ }
1374
+ return config;
1375
+ });
1376
+ }
1312
1377
  // ========================================
1313
1378
  // Aggregate Inputs
1314
1379
  // ========================================
@@ -1866,6 +1931,8 @@ export class EntityDataGridComponent extends BaseAngularComponent {
1866
1931
  finally {
1867
1932
  // Re-enable persistence now that the new view is fully loaded
1868
1933
  this._suppressPersist = false;
1934
+ // Entity is resolved by now — self-load its actions if auto-load is enabled.
1935
+ void this.maybeAutoLoadEntityActions();
1869
1936
  }
1870
1937
  }
1871
1938
  /**
@@ -4149,17 +4216,59 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4149
4216
  // TODO: Implement column chooser dialog
4150
4217
  }
4151
4218
  /**
4152
- * Handles entity action click from the overflow menu
4219
+ * The runtime-UX driver currently mounted over the grid (e.g. the Record Process bulk-update runner),
4220
+ * or null when none. Set when an action whose invocation names a `RuntimeUXDriverClass` is clicked.
4221
+ */
4222
+ ActiveRuntimeDriver = null;
4223
+ /**
4224
+ * Handles entity action click from the overflow menu. When the action names a runtime-UX driver, the
4225
+ * grid mounts that interactive driver in-place (no parent wiring required); otherwise it emits
4226
+ * `EntityActionRequested` for the host to invoke the action the classic way.
4153
4227
  */
4154
4228
  onEntityActionClick(action) {
4155
4229
  if (!this._entityInfo)
4156
4230
  return;
4231
+ if (action.runtimeUXDriverClass) {
4232
+ this.mountRuntimeDriver(action);
4233
+ return;
4234
+ }
4157
4235
  this.EntityActionRequested.emit({
4158
4236
  entityInfo: this._entityInfo,
4159
4237
  action,
4160
4238
  selectedRecords: this.GetSelectedRows()
4161
4239
  });
4162
4240
  }
4241
+ /** Builds the driver context from the current entity + selection and mounts the named driver. */
4242
+ mountRuntimeDriver(action) {
4243
+ const entity = this._entityInfo;
4244
+ const pkName = entity.FirstPrimaryKey?.Name;
4245
+ const selectedRecordIDs = pkName
4246
+ ? this.GetSelectedRows().map(r => String(r[pkName])).filter(id => id.length > 0)
4247
+ : [];
4248
+ this.ActiveRuntimeDriver = {
4249
+ DriverClass: action.runtimeUXDriverClass,
4250
+ Context: {
4251
+ EntityInfo: entity,
4252
+ ScopeKind: 'records',
4253
+ SelectedRecordIDs: selectedRecordIDs,
4254
+ Config: action.metadata ?? {},
4255
+ Provider: this.ProviderToUse,
4256
+ ContextUser: this.ProviderToUse?.CurrentUser,
4257
+ ActionLabel: action.name
4258
+ }
4259
+ };
4260
+ }
4261
+ /** The mounted driver finished — refresh the grid when it changed data, then unmount. */
4262
+ async OnRuntimeDriverCompleted(result) {
4263
+ this.ActiveRuntimeDriver = null;
4264
+ if (result?.RefreshData) {
4265
+ await this.Refresh();
4266
+ }
4267
+ }
4268
+ /** The user dismissed the mounted driver without applying — just unmount. */
4269
+ OnRuntimeDriverCancelled() {
4270
+ this.ActiveRuntimeDriver = null;
4271
+ }
4163
4272
  /**
4164
4273
  * Checks if an entity action is currently enabled based on selection requirements
4165
4274
  */
@@ -4340,7 +4449,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4340
4449
  } if (rf & 2) {
4341
4450
  let _t;
4342
4451
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.gridContainer = _t.first);
4343
- } }, inputs: { Params: "Params", AllowLoad: "AllowLoad", AutoRefreshOnParamsChange: "AutoRefreshOnParamsChange", PaginationMode: "PaginationMode", PageSize: "PageSize", CacheBlockSize: "CacheBlockSize", MaxBlocksInCache: "MaxBlocksInCache", ShowPager: "ShowPager", 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", 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", 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", 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: 13, vars: 15, consts: [["gridContainer", ""], [1, "mj-grid-toolbar"], [1, "mj-aggregate-cards"], [1, "mj-grid-content"], [1, "mj-grid-loading-overlay"], [1, "mj-grid-error"], [1, "mj-grid-empty"], [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"], [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 to Excel", 1, "toolbar-button"], ["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"], ["title", "Add selected records to a list", 1, "toolbar-button", 3, "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 to Excel", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-file-excel"], ["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"], ["title", "Add selected records to a list", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-list-check"], ["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, "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..."], [1, "fa-solid", "fa-exclamation-triangle"], [1, "error-retry", 3, "click"], [1, "fa-solid", "fa-inbox"], [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"]], template: function EntityDataGridComponent_Template(rf, ctx) { if (rf & 1) {
4452
+ } }, inputs: { Params: "Params", AllowLoad: "AllowLoad", AutoRefreshOnParamsChange: "AutoRefreshOnParamsChange", PaginationMode: "PaginationMode", PageSize: "PageSize", CacheBlockSize: "CacheBlockSize", MaxBlocksInCache: "MaxBlocksInCache", ShowPager: "ShowPager", 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", 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", 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"], [1, "mj-grid-error"], [1, "mj-grid-empty"], [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 to Excel", 1, "toolbar-button"], ["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"], ["title", "Add selected records to a list", 1, "toolbar-button", 3, "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 to Excel", 1, "toolbar-button", 3, "click"], [1, "fa-solid", "fa-file-excel"], ["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"], ["title", "Add selected records to a list", 1, "toolbar-button", 3, "click", "disabled"], [1, "fa-solid", "fa-list-check"], ["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, "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..."], [1, "fa-solid", "fa-exclamation-triangle"], [1, "error-retry", 3, "click"], [1, "fa-solid", "fa-inbox"], [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) {
4344
4453
  const _r1 = i0.ɵɵgetCurrentView();
4345
4454
  i0.ɵɵelementStart(0, "div", null, 0);
4346
4455
  i0.ɵɵconditionalCreate(2, EntityDataGridComponent_Conditional_2_Template, 27, 19, "div", 1);
@@ -4358,6 +4467,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4358
4467
  i0.ɵɵelementStart(12, "mj-export-dialog", 11);
4359
4468
  i0.ɵɵlistener("closed", function EntityDataGridComponent_Template_mj_export_dialog_closed_12_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportDialogClosed($event)); });
4360
4469
  i0.ɵɵelementEnd();
4470
+ i0.ɵɵconditionalCreate(13, EntityDataGridComponent_Conditional_13_Template, 1, 2, "mj-entity-action-ux-host", 12);
4361
4471
  } if (rf & 2) {
4362
4472
  i0.ɵɵclassMap(ctx.gridContainerClasses.join(" "));
4363
4473
  i0.ɵɵstyleProp("height", ctx.gridHeightStyle);
@@ -4381,7 +4491,9 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4381
4491
  i0.ɵɵconditional(ctx.ShowAggregateSummary ? 11 : -1);
4382
4492
  i0.ɵɵadvance();
4383
4493
  i0.ɵɵproperty("visible", ctx.showExportDialog)("config", ctx.exportDialogConfig);
4384
- } }, dependencies: [i2.AgGridAngular, i3.LoadingComponent, i4.PaginationComponent, i1.ExportDialogComponent, i5.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.mj-grid-error[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-status-error);\n gap: 12px;\n}\n\n.mj-grid-error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n}\n\n.error-retry[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n}\n\n.error-retry[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-text);\n}\n\n\n\n\n\n\n.mj-grid-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--grid-empty-text-color);\n gap: 12px;\n}\n\n.mj-grid-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--grid-empty-icon-color);\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}"], data: { animation: [
4494
+ i0.ɵɵadvance();
4495
+ i0.ɵɵconditional(ctx.ActiveRuntimeDriver ? 13 : -1);
4496
+ } }, dependencies: [i2.AgGridAngular, i3.LoadingComponent, i4.PaginationComponent, i1.ExportDialogComponent, i5.EntityActionUXHostComponent, i6.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.mj-grid-error[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-status-error);\n gap: 12px;\n}\n\n.mj-grid-error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n}\n\n.error-retry[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n}\n\n.error-retry[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-text);\n}\n\n\n\n\n\n\n.mj-grid-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--grid-empty-text-color);\n gap: 12px;\n}\n\n.mj-grid-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--grid-empty-icon-color);\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}"], data: { animation: [
4385
4497
  trigger('fadeIn', [
4386
4498
  transition(':enter', [
4387
4499
  style({ opacity: 0, transform: 'translateY(-8px)' }),
@@ -4405,7 +4517,7 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4405
4517
  animate('100ms ease-in', style({ opacity: 0, transform: 'translateY(-8px)' }))
4406
4518
  ])
4407
4519
  ])
4408
- ], 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 to Excel\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid fa-file-excel\"></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=\"Add selected records to a list\"\n [disabled]=\"!HasSelection\"\n (click)=\"onAddToListClick()\">\n <i class=\"fa-solid fa-list-check\"></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 to Excel</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 <div class=\"mj-grid-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"error-retry\" (click)=\"Refresh()\">Retry</button>\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading && !errorMessage && rowData.length === 0) {\n <div class=\"mj-grid-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No data to display</span>\n </div>\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", 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.mj-grid-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-status-error);\n gap: 12px;\n}\n\n.mj-grid-error i {\n font-size: 32px;\n}\n\n.error-retry {\n padding: 8px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n}\n\n.error-retry:hover {\n background: var(--mj-status-error-text);\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.mj-grid-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--grid-empty-text-color);\n gap: 12px;\n}\n\n.mj-grid-empty i {\n font-size: 48px;\n color: var(--grid-empty-icon-color);\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"] }]
4520
+ ], 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 to Excel\"\n (click)=\"onExportClick()\">\n <i class=\"fa-solid fa-file-excel\"></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=\"Add selected records to a list\"\n [disabled]=\"!HasSelection\"\n (click)=\"onAddToListClick()\">\n <i class=\"fa-solid fa-list-check\"></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 to Excel</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 <div class=\"mj-grid-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"error-retry\" (click)=\"Refresh()\">Retry</button>\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading && !errorMessage && rowData.length === 0) {\n <div class=\"mj-grid-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No data to display</span>\n </div>\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.mj-grid-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-status-error);\n gap: 12px;\n}\n\n.mj-grid-error i {\n font-size: 32px;\n}\n\n.error-retry {\n padding: 8px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n}\n\n.error-retry:hover {\n background: var(--mj-status-error-text);\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.mj-grid-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--grid-empty-text-color);\n gap: 12px;\n}\n\n.mj-grid-empty i {\n font-size: 48px;\n color: var(--grid-empty-icon-color);\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"] }]
4409
4521
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.ExportService }, { type: i0.NgZone }], { Params: [{
4410
4522
  type: Input
4411
4523
  }], AllowLoad: [{
@@ -4526,6 +4638,8 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4526
4638
  type: Input
4527
4639
  }], EntityActions: [{
4528
4640
  type: Input
4641
+ }], AutoLoadEntityActions: [{
4642
+ type: Input
4529
4643
  }], AggregatesConfig: [{
4530
4644
  type: Input
4531
4645
  }], AggregatesLoaded: [{
@@ -4644,5 +4758,5 @@ export class EntityDataGridComponent extends BaseAngularComponent {
4644
4758
  type: ViewChild,
4645
4759
  args: ['gridContainer']
4646
4760
  }] }); })();
4647
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityDataGridComponent, { className: "EntityDataGridComponent", filePath: "src/lib/entity-data-grid/entity-data-grid.component.ts", lineNumber: 168 }); })();
4761
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityDataGridComponent, { className: "EntityDataGridComponent", filePath: "src/lib/entity-data-grid/entity-data-grid.component.ts", lineNumber: 170 }); })();
4648
4762
  //# sourceMappingURL=entity-data-grid.component.js.map