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