@memberjunction/ng-entity-viewer 5.39.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/view-types.test.d.ts +2 -0
- package/dist/__tests__/view-types.test.d.ts.map +1 -0
- package/dist/__tests__/view-types.test.js +102 -0
- package/dist/__tests__/view-types.test.js.map +1 -0
- 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 +8 -0
- package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts +356 -341
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.js +993 -1097
- package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
- package/dist/lib/view-config-panel/view-config-panel.component.d.ts +126 -126
- package/dist/lib/view-config-panel/view-config-panel.component.js +635 -635
- package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
- package/dist/lib/view-selector/view-selector.component.d.ts +226 -0
- package/dist/lib/view-selector/view-selector.component.d.ts.map +1 -0
- package/dist/lib/view-selector/view-selector.component.js +861 -0
- package/dist/lib/view-selector/view-selector.component.js.map +1 -0
- package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts +114 -0
- package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts.map +1 -0
- package/dist/lib/view-type-switcher/view-type-switcher.component.js +209 -0
- package/dist/lib/view-type-switcher/view-type-switcher.component.js.map +1 -0
- package/dist/lib/view-types/descriptors/cards-view-type.d.ts +18 -0
- package/dist/lib/view-types/descriptors/cards-view-type.d.ts.map +1 -0
- package/dist/lib/view-types/descriptors/cards-view-type.js +31 -0
- package/dist/lib/view-types/descriptors/cards-view-type.js.map +1 -0
- package/dist/lib/view-types/descriptors/grid-view-type.d.ts +17 -0
- package/dist/lib/view-types/descriptors/grid-view-type.d.ts.map +1 -0
- package/dist/lib/view-types/descriptors/grid-view-type.js +30 -0
- package/dist/lib/view-types/descriptors/grid-view-type.js.map +1 -0
- package/dist/lib/view-types/descriptors/map-view-type.d.ts +21 -0
- package/dist/lib/view-types/descriptors/map-view-type.d.ts.map +1 -0
- package/dist/lib/view-types/descriptors/map-view-type.js +35 -0
- package/dist/lib/view-types/descriptors/map-view-type.js.map +1 -0
- package/dist/lib/view-types/descriptors/timeline-view-type.d.ts +22 -0
- package/dist/lib/view-types/descriptors/timeline-view-type.d.ts.map +1 -0
- package/dist/lib/view-types/descriptors/timeline-view-type.js +40 -0
- package/dist/lib/view-types/descriptors/timeline-view-type.js.map +1 -0
- package/dist/lib/view-types/index.d.ts +20 -0
- package/dist/lib/view-types/index.d.ts.map +1 -0
- package/dist/lib/view-types/index.js +29 -0
- package/dist/lib/view-types/index.js.map +1 -0
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +93 -0
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -0
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js +144 -0
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -0
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +273 -0
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -0
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js +558 -0
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -0
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +135 -0
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -0
- package/dist/lib/view-types/renderers/map-view-renderer.component.js +216 -0
- package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -0
- package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts +176 -0
- package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts.map +1 -0
- package/dist/lib/view-types/renderers/timeline-view-renderer.component.js +535 -0
- package/dist/lib/view-types/renderers/timeline-view-renderer.component.js.map +1 -0
- package/dist/lib/view-types/view-type.contracts.d.ts +235 -0
- package/dist/lib/view-types/view-type.contracts.d.ts.map +1 -0
- package/dist/lib/view-types/view-type.contracts.js +51 -0
- package/dist/lib/view-types/view-type.contracts.js.map +1 -0
- package/dist/lib/view-types/view-type.engine.d.ts +76 -0
- package/dist/lib/view-types/view-type.engine.d.ts.map +1 -0
- package/dist/lib/view-types/view-type.engine.js +138 -0
- package/dist/lib/view-types/view-type.engine.js.map +1 -0
- package/dist/lib/view-workspace/view-workspace.component.d.ts +451 -0
- package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -0
- package/dist/lib/view-workspace/view-workspace.component.js +1212 -0
- package/dist/lib/view-workspace/view-workspace.component.js.map +1 -0
- package/dist/module.d.ts +20 -11
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +50 -8
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +8 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +14 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +16 -15
|
@@ -12,7 +12,7 @@ const _forTrack2 = ($index, $item) => $item.id;
|
|
|
12
12
|
function ViewConfigPanelComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
13
13
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
14
14
|
i0.ɵɵelementStart(0, "div", 28);
|
|
15
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
15
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnClose()); });
|
|
16
16
|
i0.ɵɵelementEnd();
|
|
17
17
|
} }
|
|
18
18
|
function ViewConfigPanelComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -32,7 +32,7 @@ function ViewConfigPanelComponent_Conditional_18_Template(rf, ctx) { if (rf & 1)
|
|
|
32
32
|
} if (rf & 2) {
|
|
33
33
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
34
34
|
i0.ɵɵadvance();
|
|
35
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
35
|
+
i0.ɵɵtextInterpolate(ctx_r1.SortItems.length);
|
|
36
36
|
} }
|
|
37
37
|
function ViewConfigPanelComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
38
38
|
i0.ɵɵelementStart(0, "span");
|
|
@@ -51,7 +51,7 @@ function ViewConfigPanelComponent_Conditional_25_Template(rf, ctx) { if (rf & 1)
|
|
|
51
51
|
} if (rf & 2) {
|
|
52
52
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
53
53
|
i0.ɵɵadvance();
|
|
54
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
54
|
+
i0.ɵɵtextInterpolate(ctx_r1.EnabledAggregatesCount);
|
|
55
55
|
} }
|
|
56
56
|
function ViewConfigPanelComponent_Conditional_26_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
57
57
|
i0.ɵɵelementStart(0, "span");
|
|
@@ -61,16 +61,16 @@ function ViewConfigPanelComponent_Conditional_26_Conditional_2_Template(rf, ctx)
|
|
|
61
61
|
function ViewConfigPanelComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
62
62
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
63
63
|
i0.ɵɵelementStart(0, "button", 10);
|
|
64
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_26_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
64
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_26_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetActiveTab("settings")); });
|
|
65
65
|
i0.ɵɵelement(1, "i", 29);
|
|
66
66
|
i0.ɵɵconditionalCreate(2, ViewConfigPanelComponent_Conditional_26_Conditional_2_Template, 2, 0, "span");
|
|
67
67
|
i0.ɵɵelementEnd();
|
|
68
68
|
} if (rf & 2) {
|
|
69
69
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
70
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
71
|
-
i0.ɵɵproperty("title", ctx_r1.
|
|
70
|
+
i0.ɵɵclassProp("active", ctx_r1.ActiveTab === "settings");
|
|
71
|
+
i0.ɵɵproperty("title", ctx_r1.IsIconOnlyMode ? "Settings" : "");
|
|
72
72
|
i0.ɵɵadvance(2);
|
|
73
|
-
i0.ɵɵconditional(!ctx_r1.
|
|
73
|
+
i0.ɵɵconditional(!ctx_r1.IsIconOnlyMode ? 2 : -1);
|
|
74
74
|
} }
|
|
75
75
|
function ViewConfigPanelComponent_Conditional_28_For_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
76
76
|
i0.ɵɵelement(0, "div", 40);
|
|
@@ -91,7 +91,7 @@ function ViewConfigPanelComponent_Conditional_28_For_10_Template(rf, ctx) { if (
|
|
|
91
91
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
92
92
|
i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_28_For_10_Conditional_0_Template, 1, 0, "div", 40);
|
|
93
93
|
i0.ɵɵelementStart(1, "div", 41);
|
|
94
|
-
i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_dragstart_1_listener($event) { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
94
|
+
i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_dragstart_1_listener($event) { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, column_r5)); })("dragover", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_dragover_1_listener($event) { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, column_r5)); })("dragleave", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_dragleave_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event)); })("drop", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_drop_1_listener($event) { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDrop($event, column_r5)); })("dragend", function ViewConfigPanelComponent_Conditional_28_For_10_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd($event)); });
|
|
95
95
|
i0.ɵɵelementStart(2, "div", 42);
|
|
96
96
|
i0.ɵɵelement(3, "i", 43);
|
|
97
97
|
i0.ɵɵelementEnd();
|
|
@@ -101,19 +101,19 @@ function ViewConfigPanelComponent_Conditional_28_For_10_Template(rf, ctx) { if (
|
|
|
101
101
|
i0.ɵɵconditionalCreate(7, ViewConfigPanelComponent_Conditional_28_For_10_Conditional_7_Template, 1, 0, "i", 46);
|
|
102
102
|
i0.ɵɵelementEnd();
|
|
103
103
|
i0.ɵɵelementStart(8, "div", 47)(9, "button", 48);
|
|
104
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_9_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
104
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_9_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenFormatEditor(column_r5)); });
|
|
105
105
|
i0.ɵɵelement(10, "i", 49);
|
|
106
106
|
i0.ɵɵelementEnd();
|
|
107
107
|
i0.ɵɵelementStart(11, "button", 50);
|
|
108
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_11_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
108
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_11_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MoveColumnUp(column_r5)); });
|
|
109
109
|
i0.ɵɵelement(12, "i", 51);
|
|
110
110
|
i0.ɵɵelementEnd();
|
|
111
111
|
i0.ɵɵelementStart(13, "button", 52);
|
|
112
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_13_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
112
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_13_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MoveColumnDown(column_r5)); });
|
|
113
113
|
i0.ɵɵelement(14, "i", 53);
|
|
114
114
|
i0.ɵɵelementEnd();
|
|
115
115
|
i0.ɵɵelementStart(15, "button", 54);
|
|
116
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_15_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
116
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_10_Template_button_click_15_listener() { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleColumnVisibility(column_r5)); });
|
|
117
117
|
i0.ɵɵelement(16, "i", 36);
|
|
118
118
|
i0.ɵɵelementEnd()()();
|
|
119
119
|
i0.ɵɵconditionalCreate(17, ViewConfigPanelComponent_Conditional_28_For_10_Conditional_17_Template, 1, 0, "div", 40);
|
|
@@ -121,21 +121,21 @@ function ViewConfigPanelComponent_Conditional_28_For_10_Template(rf, ctx) { if (
|
|
|
121
121
|
const column_r5 = ctx.$implicit;
|
|
122
122
|
const ɵ$index_93_r6 = ctx.$index;
|
|
123
123
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
124
|
-
i0.ɵɵconditional(ctx_r1.
|
|
124
|
+
i0.ɵɵconditional(ctx_r1.IsDropBefore(column_r5) ? 0 : -1);
|
|
125
125
|
i0.ɵɵadvance();
|
|
126
|
-
i0.ɵɵclassProp("dragging", ctx_r1.
|
|
126
|
+
i0.ɵɵclassProp("dragging", ctx_r1.DraggedColumn === column_r5)("drop-target", ctx_r1.DropTargetColumn === column_r5);
|
|
127
127
|
i0.ɵɵadvance(4);
|
|
128
128
|
i0.ɵɵtextInterpolate1(" ", column_r5.userDisplayName || column_r5.displayName, " ");
|
|
129
129
|
i0.ɵɵadvance();
|
|
130
130
|
i0.ɵɵconditional(column_r5.userDisplayName ? 6 : -1);
|
|
131
131
|
i0.ɵɵadvance();
|
|
132
|
-
i0.ɵɵconditional(ctx_r1.
|
|
132
|
+
i0.ɵɵconditional(ctx_r1.HasCustomFormat(column_r5) ? 7 : -1);
|
|
133
133
|
i0.ɵɵadvance(4);
|
|
134
134
|
i0.ɵɵproperty("disabled", ɵ$index_93_r6 === 0);
|
|
135
135
|
i0.ɵɵadvance(2);
|
|
136
|
-
i0.ɵɵproperty("disabled", ɵ$index_93_r6 === ctx_r1.
|
|
136
|
+
i0.ɵɵproperty("disabled", ɵ$index_93_r6 === ctx_r1.VisibleColumns.length - 1);
|
|
137
137
|
i0.ɵɵadvance(4);
|
|
138
|
-
i0.ɵɵconditional(ctx_r1.
|
|
138
|
+
i0.ɵɵconditional(ctx_r1.IsDropAfter(column_r5) && ɵ$index_93_r6 === ctx_r1.VisibleColumns.length - 1 ? 17 : -1);
|
|
139
139
|
} }
|
|
140
140
|
function ViewConfigPanelComponent_Conditional_28_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
141
141
|
i0.ɵɵelementStart(0, "div", 35);
|
|
@@ -149,12 +149,12 @@ function ViewConfigPanelComponent_Conditional_28_Conditional_19_Template(rf, ctx
|
|
|
149
149
|
i0.ɵɵelementStart(0, "div", 37);
|
|
150
150
|
i0.ɵɵelement(1, "i", 56);
|
|
151
151
|
i0.ɵɵelementStart(2, "input", 57);
|
|
152
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_28_Conditional_19_Template_input_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
152
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_28_Conditional_19_Template_input_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.ColumnSearchText, $event) || (ctx_r1.ColumnSearchText = $event); return i0.ɵɵresetView($event); });
|
|
153
153
|
i0.ɵɵelementEnd()();
|
|
154
154
|
} if (rf & 2) {
|
|
155
155
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
156
156
|
i0.ɵɵadvance(2);
|
|
157
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
157
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ColumnSearchText);
|
|
158
158
|
} }
|
|
159
159
|
function ViewConfigPanelComponent_Conditional_28_For_22_Template(rf, ctx) { if (rf & 1) {
|
|
160
160
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
@@ -162,7 +162,7 @@ function ViewConfigPanelComponent_Conditional_28_For_22_Template(rf, ctx) { if (
|
|
|
162
162
|
i0.ɵɵtext(2);
|
|
163
163
|
i0.ɵɵelementEnd();
|
|
164
164
|
i0.ɵɵelementStart(3, "button", 58);
|
|
165
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_22_Template_button_click_3_listener() { const column_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
165
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_28_For_22_Template_button_click_3_listener() { const column_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleColumnVisibility(column_r9)); });
|
|
166
166
|
i0.ɵɵelement(4, "i", 59);
|
|
167
167
|
i0.ɵɵelementEnd()();
|
|
168
168
|
} if (rf & 2) {
|
|
@@ -206,19 +206,19 @@ function ViewConfigPanelComponent_Conditional_28_Template(rf, ctx) { if (rf & 1)
|
|
|
206
206
|
} if (rf & 2) {
|
|
207
207
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
208
208
|
i0.ɵɵadvance(7);
|
|
209
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
209
|
+
i0.ɵɵtextInterpolate(ctx_r1.VisibleColumns.length);
|
|
210
210
|
i0.ɵɵadvance(2);
|
|
211
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
211
|
+
i0.ɵɵrepeater(ctx_r1.VisibleColumns);
|
|
212
212
|
i0.ɵɵadvance(2);
|
|
213
|
-
i0.ɵɵconditional(ctx_r1.
|
|
213
|
+
i0.ɵɵconditional(ctx_r1.VisibleColumns.length === 0 ? 11 : -1);
|
|
214
214
|
i0.ɵɵadvance(7);
|
|
215
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
215
|
+
i0.ɵɵtextInterpolate(ctx_r1.HiddenColumns.length);
|
|
216
216
|
i0.ɵɵadvance();
|
|
217
|
-
i0.ɵɵconditional(ctx_r1.
|
|
217
|
+
i0.ɵɵconditional(ctx_r1.HiddenColumns.length > 5 ? 19 : -1);
|
|
218
218
|
i0.ɵɵadvance(2);
|
|
219
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
219
|
+
i0.ɵɵrepeater(ctx_r1.FilteredHiddenColumns);
|
|
220
220
|
i0.ɵɵadvance(2);
|
|
221
|
-
i0.ɵɵconditional(ctx_r1.
|
|
221
|
+
i0.ɵɵconditional(ctx_r1.HiddenColumns.length === 0 ? 23 : -1);
|
|
222
222
|
} }
|
|
223
223
|
function ViewConfigPanelComponent_Conditional_29_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
224
224
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
@@ -226,13 +226,13 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_16_Template(rf, ctx
|
|
|
226
226
|
i0.ɵɵtext(2);
|
|
227
227
|
i0.ɵɵelementEnd();
|
|
228
228
|
i0.ɵɵelementStart(3, "button", 107);
|
|
229
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Conditional_16_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
229
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Conditional_16_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.FormatEditingColumn.userDisplayName = undefined); });
|
|
230
230
|
i0.ɵɵelement(4, "i", 8);
|
|
231
231
|
i0.ɵɵelementEnd()();
|
|
232
232
|
} if (rf & 2) {
|
|
233
233
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
234
234
|
i0.ɵɵadvance(2);
|
|
235
|
-
i0.ɵɵtextInterpolate1("Original: ", ctx_r1.
|
|
235
|
+
i0.ɵɵtextInterpolate1("Original: ", ctx_r1.FormatEditingColumn.displayName);
|
|
236
236
|
} }
|
|
237
237
|
function ViewConfigPanelComponent_Conditional_29_For_26_Template(rf, ctx) { if (rf & 1) {
|
|
238
238
|
i0.ɵɵelementStart(0, "div", 108);
|
|
@@ -241,9 +241,9 @@ function ViewConfigPanelComponent_Conditional_29_For_26_Template(rf, ctx) { if (
|
|
|
241
241
|
} if (rf & 2) {
|
|
242
242
|
const value_r12 = ctx.$implicit;
|
|
243
243
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
244
|
-
i0.ɵɵstyleProp("text-align", (ctx_r1.
|
|
244
|
+
i0.ɵɵstyleProp("text-align", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.align) || "left")("font-weight", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.bold) ? "bold" : "normal")("font-style", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.italic) ? "italic" : "normal")("text-decoration", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.underline) ? "underline" : "none")("color", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.color)("background-color", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.backgroundColor);
|
|
245
245
|
i0.ɵɵadvance();
|
|
246
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
246
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatPreviewValue(value_r12, ctx_r1.FormatEditingColumn.format), " ");
|
|
247
247
|
} }
|
|
248
248
|
function ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
249
249
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
@@ -251,7 +251,7 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Te
|
|
|
251
251
|
i0.ɵɵtext(2, "Currency");
|
|
252
252
|
i0.ɵɵelementEnd();
|
|
253
253
|
i0.ɵɵelementStart(3, "select", 77);
|
|
254
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
254
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.currencyCode, $event) || (ctx_r1.FormatEditingColumn.format.currencyCode = $event); return i0.ɵɵresetView($event); });
|
|
255
255
|
i0.ɵɵelementStart(4, "option", 112);
|
|
256
256
|
i0.ɵɵtext(5, "USD ($)");
|
|
257
257
|
i0.ɵɵelementEnd();
|
|
@@ -273,7 +273,7 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Te
|
|
|
273
273
|
} if (rf & 2) {
|
|
274
274
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
275
275
|
i0.ɵɵadvance(3);
|
|
276
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
276
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.currencyCode);
|
|
277
277
|
} }
|
|
278
278
|
function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
279
279
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
@@ -286,23 +286,23 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template(rf, ctx
|
|
|
286
286
|
i0.ɵɵtext(7, "Decimal Places");
|
|
287
287
|
i0.ɵɵelementEnd();
|
|
288
288
|
i0.ɵɵelementStart(8, "input", 110);
|
|
289
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
289
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.decimals, $event) || (ctx_r1.FormatEditingColumn.format.decimals = $event); return i0.ɵɵresetView($event); });
|
|
290
290
|
i0.ɵɵelementEnd()();
|
|
291
291
|
i0.ɵɵconditionalCreate(9, ViewConfigPanelComponent_Conditional_29_Conditional_49_Conditional_9_Template, 16, 1, "div", 68);
|
|
292
292
|
i0.ɵɵelementStart(10, "div", 68)(11, "label");
|
|
293
293
|
i0.ɵɵtext(12, "Thousands Separator");
|
|
294
294
|
i0.ɵɵelementEnd();
|
|
295
295
|
i0.ɵɵelementStart(13, "input", 111);
|
|
296
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template_input_ngModelChange_13_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
296
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_49_Template_input_ngModelChange_13_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.thousandsSeparator, $event) || (ctx_r1.FormatEditingColumn.format.thousandsSeparator = $event); return i0.ɵɵresetView($event); });
|
|
297
297
|
i0.ɵɵelementEnd()()();
|
|
298
298
|
} if (rf & 2) {
|
|
299
299
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
300
300
|
i0.ɵɵadvance(8);
|
|
301
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
301
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.decimals);
|
|
302
302
|
i0.ɵɵadvance();
|
|
303
|
-
i0.ɵɵconditional((ctx_r1.
|
|
303
|
+
i0.ɵɵconditional((ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "currency" ? 9 : -1);
|
|
304
304
|
i0.ɵɵadvance(4);
|
|
305
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
305
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.thousandsSeparator);
|
|
306
306
|
} }
|
|
307
307
|
function ViewConfigPanelComponent_Conditional_29_Conditional_50_Template(rf, ctx) { if (rf & 1) {
|
|
308
308
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
@@ -315,7 +315,7 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_50_Template(rf, ctx
|
|
|
315
315
|
i0.ɵɵtext(7, "Format");
|
|
316
316
|
i0.ɵɵelementEnd();
|
|
317
317
|
i0.ɵɵelementStart(8, "select", 77);
|
|
318
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_50_Template_select_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
318
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_50_Template_select_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.dateFormat, $event) || (ctx_r1.FormatEditingColumn.format.dateFormat = $event); return i0.ɵɵresetView($event); });
|
|
319
319
|
i0.ɵɵelementStart(9, "option", 119);
|
|
320
320
|
i0.ɵɵtext(10, "Short (1/15/25)");
|
|
321
321
|
i0.ɵɵelementEnd();
|
|
@@ -337,7 +337,7 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_50_Template(rf, ctx
|
|
|
337
337
|
} if (rf & 2) {
|
|
338
338
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
339
339
|
i0.ɵɵadvance(8);
|
|
340
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
340
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.dateFormat);
|
|
341
341
|
} }
|
|
342
342
|
function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template(rf, ctx) { if (rf & 1) {
|
|
343
343
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
@@ -350,19 +350,19 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template(rf, ctx
|
|
|
350
350
|
i0.ɵɵtext(7, "True Label");
|
|
351
351
|
i0.ɵɵelementEnd();
|
|
352
352
|
i0.ɵɵelementStart(8, "input", 126);
|
|
353
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
353
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.trueLabel, $event) || (ctx_r1.FormatEditingColumn.format.trueLabel = $event); return i0.ɵɵresetView($event); });
|
|
354
354
|
i0.ɵɵelementEnd()();
|
|
355
355
|
i0.ɵɵelementStart(9, "div", 68)(10, "label");
|
|
356
356
|
i0.ɵɵtext(11, "False Label");
|
|
357
357
|
i0.ɵɵelementEnd();
|
|
358
358
|
i0.ɵɵelementStart(12, "input", 127);
|
|
359
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
359
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.falseLabel, $event) || (ctx_r1.FormatEditingColumn.format.falseLabel = $event); return i0.ɵɵresetView($event); });
|
|
360
360
|
i0.ɵɵelementEnd()();
|
|
361
361
|
i0.ɵɵelementStart(13, "div", 68)(14, "label");
|
|
362
362
|
i0.ɵɵtext(15, "Display As");
|
|
363
363
|
i0.ɵɵelementEnd();
|
|
364
364
|
i0.ɵɵelementStart(16, "select", 77);
|
|
365
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_select_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
365
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template_select_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.booleanDisplay, $event) || (ctx_r1.FormatEditingColumn.format.booleanDisplay = $event); return i0.ɵɵresetView($event); });
|
|
366
366
|
i0.ɵɵelementStart(17, "option", 79);
|
|
367
367
|
i0.ɵɵtext(18, "Text");
|
|
368
368
|
i0.ɵɵelementEnd();
|
|
@@ -375,16 +375,16 @@ function ViewConfigPanelComponent_Conditional_29_Conditional_51_Template(rf, ctx
|
|
|
375
375
|
} if (rf & 2) {
|
|
376
376
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
377
377
|
i0.ɵɵadvance(8);
|
|
378
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
378
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.trueLabel);
|
|
379
379
|
i0.ɵɵadvance(4);
|
|
380
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
380
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.falseLabel);
|
|
381
381
|
i0.ɵɵadvance(4);
|
|
382
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
382
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.booleanDisplay);
|
|
383
383
|
} }
|
|
384
384
|
function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
385
385
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
386
386
|
i0.ɵɵelementStart(0, "div", 19)(1, "div", 61)(2, "button", 62);
|
|
387
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
387
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseFormatEditor()); });
|
|
388
388
|
i0.ɵɵelement(3, "i", 63);
|
|
389
389
|
i0.ɵɵelementEnd();
|
|
390
390
|
i0.ɵɵelementStart(4, "div", 64)(5, "span");
|
|
@@ -399,7 +399,7 @@ function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1)
|
|
|
399
399
|
i0.ɵɵtext(14, "Display As");
|
|
400
400
|
i0.ɵɵelementEnd();
|
|
401
401
|
i0.ɵɵelementStart(15, "input", 69);
|
|
402
|
-
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
402
|
+
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateUserDisplayName($event.target.value)); });
|
|
403
403
|
i0.ɵɵelementEnd()();
|
|
404
404
|
i0.ɵɵconditionalCreate(16, ViewConfigPanelComponent_Conditional_29_Conditional_16_Template, 5, 1, "div", 70);
|
|
405
405
|
i0.ɵɵelementEnd();
|
|
@@ -419,7 +419,7 @@ function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1)
|
|
|
419
419
|
i0.ɵɵtext(31, "Format Type");
|
|
420
420
|
i0.ɵɵelementEnd()();
|
|
421
421
|
i0.ɵɵelementStart(32, "select", 77);
|
|
422
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Template_select_ngModelChange_32_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
422
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_29_Template_select_ngModelChange_32_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.FormatEditingColumn.format.type, $event) || (ctx_r1.FormatEditingColumn.format.type = $event); return i0.ɵɵresetView($event); });
|
|
423
423
|
i0.ɵɵelementStart(33, "option", 78);
|
|
424
424
|
i0.ɵɵtext(34, "Auto (Smart Default)");
|
|
425
425
|
i0.ɵɵelementEnd();
|
|
@@ -453,15 +453,15 @@ function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1)
|
|
|
453
453
|
i0.ɵɵtext(56, "Alignment");
|
|
454
454
|
i0.ɵɵelementEnd()();
|
|
455
455
|
i0.ɵɵelementStart(57, "div", 87)(58, "button", 88);
|
|
456
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_58_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
456
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_58_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormatEditingColumn.format.align = "left"); });
|
|
457
457
|
i0.ɵɵelement(59, "i", 86);
|
|
458
458
|
i0.ɵɵelementEnd();
|
|
459
459
|
i0.ɵɵelementStart(60, "button", 89);
|
|
460
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_60_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
460
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_60_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormatEditingColumn.format.align = "center"); });
|
|
461
461
|
i0.ɵɵelement(61, "i", 90);
|
|
462
462
|
i0.ɵɵelementEnd();
|
|
463
463
|
i0.ɵɵelementStart(62, "button", 91);
|
|
464
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_62_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
464
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_62_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormatEditingColumn.format.align = "right"); });
|
|
465
465
|
i0.ɵɵelement(63, "i", 92);
|
|
466
466
|
i0.ɵɵelementEnd()()();
|
|
467
467
|
i0.ɵɵelementStart(64, "div", 65)(65, "div", 66);
|
|
@@ -470,28 +470,28 @@ function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1)
|
|
|
470
470
|
i0.ɵɵtext(68, "Header Style");
|
|
471
471
|
i0.ɵɵelementEnd()();
|
|
472
472
|
i0.ɵɵelementStart(69, "div", 94)(70, "button", 95);
|
|
473
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
473
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleHeaderStyle("bold")); });
|
|
474
474
|
i0.ɵɵelement(71, "i", 96);
|
|
475
475
|
i0.ɵɵelementEnd();
|
|
476
476
|
i0.ɵɵelementStart(72, "button", 97);
|
|
477
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_72_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
477
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_72_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleHeaderStyle("italic")); });
|
|
478
478
|
i0.ɵɵelement(73, "i", 98);
|
|
479
479
|
i0.ɵɵelementEnd();
|
|
480
480
|
i0.ɵɵelementStart(74, "button", 99);
|
|
481
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_74_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
481
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_74_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleHeaderStyle("underline")); });
|
|
482
482
|
i0.ɵɵelement(75, "i", 100);
|
|
483
483
|
i0.ɵɵelementEnd()();
|
|
484
484
|
i0.ɵɵelementStart(76, "div", 68)(77, "label");
|
|
485
485
|
i0.ɵɵtext(78, "Text Color");
|
|
486
486
|
i0.ɵɵelementEnd();
|
|
487
487
|
i0.ɵɵelementStart(79, "input", 101);
|
|
488
|
-
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_79_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
488
|
+
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_79_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateHeaderColor("color", $event.target.value)); });
|
|
489
489
|
i0.ɵɵelementEnd()();
|
|
490
490
|
i0.ɵɵelementStart(80, "div", 68)(81, "label");
|
|
491
491
|
i0.ɵɵtext(82, "Background");
|
|
492
492
|
i0.ɵɵelementEnd();
|
|
493
493
|
i0.ɵɵelementStart(83, "input", 101);
|
|
494
|
-
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_83_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
494
|
+
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_83_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateHeaderColor("backgroundColor", $event.target.value)); });
|
|
495
495
|
i0.ɵɵelementEnd()()();
|
|
496
496
|
i0.ɵɵelementStart(84, "div", 65)(85, "div", 66);
|
|
497
497
|
i0.ɵɵelement(86, "i", 102);
|
|
@@ -499,82 +499,82 @@ function ViewConfigPanelComponent_Conditional_29_Template(rf, ctx) { if (rf & 1)
|
|
|
499
499
|
i0.ɵɵtext(88, "Cell Style");
|
|
500
500
|
i0.ɵɵelementEnd()();
|
|
501
501
|
i0.ɵɵelementStart(89, "div", 94)(90, "button", 95);
|
|
502
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_90_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
502
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_90_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCellStyle("bold")); });
|
|
503
503
|
i0.ɵɵelement(91, "i", 96);
|
|
504
504
|
i0.ɵɵelementEnd();
|
|
505
505
|
i0.ɵɵelementStart(92, "button", 97);
|
|
506
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_92_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
506
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_92_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCellStyle("italic")); });
|
|
507
507
|
i0.ɵɵelement(93, "i", 98);
|
|
508
508
|
i0.ɵɵelementEnd();
|
|
509
509
|
i0.ɵɵelementStart(94, "button", 99);
|
|
510
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_94_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
510
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_94_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCellStyle("underline")); });
|
|
511
511
|
i0.ɵɵelement(95, "i", 100);
|
|
512
512
|
i0.ɵɵelementEnd()();
|
|
513
513
|
i0.ɵɵelementStart(96, "div", 68)(97, "label");
|
|
514
514
|
i0.ɵɵtext(98, "Text Color");
|
|
515
515
|
i0.ɵɵelementEnd();
|
|
516
516
|
i0.ɵɵelementStart(99, "input", 101);
|
|
517
|
-
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_99_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
517
|
+
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_99_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateCellColor("color", $event.target.value)); });
|
|
518
518
|
i0.ɵɵelementEnd()();
|
|
519
519
|
i0.ɵɵelementStart(100, "div", 68)(101, "label");
|
|
520
520
|
i0.ɵɵtext(102, "Background");
|
|
521
521
|
i0.ɵɵelementEnd();
|
|
522
522
|
i0.ɵɵelementStart(103, "input", 101);
|
|
523
|
-
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_103_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
523
|
+
i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_29_Template_input_input_103_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateCellColor("backgroundColor", $event.target.value)); });
|
|
524
524
|
i0.ɵɵelementEnd()()();
|
|
525
525
|
i0.ɵɵelementStart(104, "div", 103)(105, "button", 104);
|
|
526
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_105_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.
|
|
526
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_29_Template_button_click_105_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.ClearColumnFormat(ctx_r1.FormatEditingColumn); return i0.ɵɵresetView(ctx_r1.CloseFormatEditor()); });
|
|
527
527
|
i0.ɵɵelement(106, "i", 105);
|
|
528
528
|
i0.ɵɵtext(107, " Clear Formatting ");
|
|
529
529
|
i0.ɵɵelementEnd()()();
|
|
530
530
|
} if (rf & 2) {
|
|
531
531
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
532
532
|
i0.ɵɵadvance(6);
|
|
533
|
-
i0.ɵɵtextInterpolate1("Format: ", ctx_r1.
|
|
533
|
+
i0.ɵɵtextInterpolate1("Format: ", ctx_r1.FormatEditingColumn.userDisplayName || ctx_r1.FormatEditingColumn.displayName);
|
|
534
534
|
i0.ɵɵadvance(9);
|
|
535
|
-
i0.ɵɵproperty("value", ctx_r1.
|
|
535
|
+
i0.ɵɵproperty("value", ctx_r1.FormatEditingColumn.userDisplayName || "")("placeholder", ctx_r1.FormatEditingColumn.displayName);
|
|
536
536
|
i0.ɵɵadvance();
|
|
537
|
-
i0.ɵɵconditional(ctx_r1.
|
|
537
|
+
i0.ɵɵconditional(ctx_r1.FormatEditingColumn.userDisplayName ? 16 : -1);
|
|
538
538
|
i0.ɵɵadvance(7);
|
|
539
|
-
i0.ɵɵstyleProp("font-weight", (ctx_r1.
|
|
539
|
+
i0.ɵɵstyleProp("font-weight", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.bold) ? "bold" : "normal")("font-style", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.italic) ? "italic" : "normal")("text-decoration", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.underline) ? "underline" : "none")("color", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.color)("background-color", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.backgroundColor);
|
|
540
540
|
i0.ɵɵadvance();
|
|
541
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
541
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatEditingColumn.userDisplayName || ctx_r1.FormatEditingColumn.displayName, " ");
|
|
542
542
|
i0.ɵɵadvance();
|
|
543
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
543
|
+
i0.ɵɵrepeater(ctx_r1.GetSampleValues(ctx_r1.FormatEditingColumn));
|
|
544
544
|
i0.ɵɵadvance(7);
|
|
545
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
545
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.FormatEditingColumn.format.type);
|
|
546
546
|
i0.ɵɵadvance(17);
|
|
547
|
-
i0.ɵɵconditional((ctx_r1.
|
|
547
|
+
i0.ɵɵconditional((ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "number" || (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "currency" || (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "percent" ? 49 : -1);
|
|
548
548
|
i0.ɵɵadvance();
|
|
549
|
-
i0.ɵɵconditional((ctx_r1.
|
|
549
|
+
i0.ɵɵconditional((ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "date" || (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "datetime" ? 50 : -1);
|
|
550
550
|
i0.ɵɵadvance();
|
|
551
|
-
i0.ɵɵconditional((ctx_r1.
|
|
551
|
+
i0.ɵɵconditional((ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.type) === "boolean" ? 51 : -1);
|
|
552
552
|
i0.ɵɵadvance(7);
|
|
553
|
-
i0.ɵɵclassProp("active", (ctx_r1.
|
|
553
|
+
i0.ɵɵclassProp("active", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.align) === "left" || !(ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.align));
|
|
554
554
|
i0.ɵɵadvance(2);
|
|
555
|
-
i0.ɵɵclassProp("active", (ctx_r1.
|
|
555
|
+
i0.ɵɵclassProp("active", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.align) === "center");
|
|
556
556
|
i0.ɵɵadvance(2);
|
|
557
|
-
i0.ɵɵclassProp("active", (ctx_r1.
|
|
557
|
+
i0.ɵɵclassProp("active", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.align) === "right");
|
|
558
558
|
i0.ɵɵadvance(8);
|
|
559
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
559
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.bold);
|
|
560
560
|
i0.ɵɵadvance(2);
|
|
561
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
561
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.italic);
|
|
562
562
|
i0.ɵɵadvance(2);
|
|
563
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
563
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.underline);
|
|
564
564
|
i0.ɵɵadvance(5);
|
|
565
|
-
i0.ɵɵproperty("value", (ctx_r1.
|
|
565
|
+
i0.ɵɵproperty("value", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.color) || "#000000");
|
|
566
566
|
i0.ɵɵadvance(4);
|
|
567
|
-
i0.ɵɵproperty("value", (ctx_r1.
|
|
567
|
+
i0.ɵɵproperty("value", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle == null ? null : ctx_r1.FormatEditingColumn.format.headerStyle.backgroundColor) || "#ffffff");
|
|
568
568
|
i0.ɵɵadvance(7);
|
|
569
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
569
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.bold);
|
|
570
570
|
i0.ɵɵadvance(2);
|
|
571
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
571
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.italic);
|
|
572
572
|
i0.ɵɵadvance(2);
|
|
573
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
573
|
+
i0.ɵɵclassProp("active", ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.underline);
|
|
574
574
|
i0.ɵɵadvance(5);
|
|
575
|
-
i0.ɵɵproperty("value", (ctx_r1.
|
|
575
|
+
i0.ɵɵproperty("value", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.color) || "#000000");
|
|
576
576
|
i0.ɵɵadvance(4);
|
|
577
|
-
i0.ɵɵproperty("value", (ctx_r1.
|
|
577
|
+
i0.ɵɵproperty("value", (ctx_r1.FormatEditingColumn.format == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle == null ? null : ctx_r1.FormatEditingColumn.format.cellStyle.backgroundColor) || "#ffffff");
|
|
578
578
|
} }
|
|
579
579
|
function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
580
580
|
i0.ɵɵelement(0, "div", 137);
|
|
@@ -596,7 +596,7 @@ function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template(rf
|
|
|
596
596
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
597
597
|
i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Conditional_0_Template, 1, 0, "div", 137);
|
|
598
598
|
i0.ɵɵelementStart(1, "div", 138);
|
|
599
|
-
i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_dragstart_1_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
599
|
+
i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_dragstart_1_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDragStart($event, sortItem_r19)); })("dragover", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_dragover_1_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDragOver($event, sortItem_r19)); })("dragleave", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_dragleave_1_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDragLeave($event)); })("drop", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_drop_1_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDrop($event, sortItem_r19)); })("dragend", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDragEnd($event)); });
|
|
600
600
|
i0.ɵɵelementStart(2, "div", 139);
|
|
601
601
|
i0.ɵɵtext(3);
|
|
602
602
|
i0.ɵɵelementEnd();
|
|
@@ -605,19 +605,19 @@ function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template(rf
|
|
|
605
605
|
i0.ɵɵelementEnd();
|
|
606
606
|
i0.ɵɵelementStart(6, "select", 141);
|
|
607
607
|
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_select_ngModelChange_6_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; i0.ɵɵtwoWayBindingSet(sortItem_r19.field, $event) || (sortItem_r19.field = $event); return i0.ɵɵresetView($event); });
|
|
608
|
-
i0.ɵɵlistener("ngModelChange", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_select_ngModelChange_6_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
608
|
+
i0.ɵɵlistener("ngModelChange", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_select_ngModelChange_6_listener($event) { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortFieldChange(sortItem_r19, $event)); });
|
|
609
609
|
i0.ɵɵrepeaterCreate(7, ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_For_8_Template, 2, 2, "option", 142, _forTrack1);
|
|
610
610
|
i0.ɵɵelementEnd();
|
|
611
611
|
i0.ɵɵelementStart(9, "div", 143)(10, "button", 144);
|
|
612
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_10_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
612
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_10_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDirectionChange(sortItem_r19, "asc")); });
|
|
613
613
|
i0.ɵɵelement(11, "i", 145);
|
|
614
614
|
i0.ɵɵelementEnd();
|
|
615
615
|
i0.ɵɵelementStart(12, "button", 146);
|
|
616
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_12_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
616
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_12_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSortDirectionChange(sortItem_r19, "desc")); });
|
|
617
617
|
i0.ɵɵelement(13, "i", 147);
|
|
618
618
|
i0.ɵɵelementEnd()();
|
|
619
619
|
i0.ɵɵelementStart(14, "button", 148);
|
|
620
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_14_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
620
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template_button_click_14_listener() { const sortItem_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.RemoveSortLevel(sortItem_r19)); });
|
|
621
621
|
i0.ɵɵelement(15, "i", 8);
|
|
622
622
|
i0.ɵɵelementEnd()();
|
|
623
623
|
i0.ɵɵconditionalCreate(16, ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Conditional_16_Template, 1, 0, "div", 137);
|
|
@@ -625,26 +625,26 @@ function ViewConfigPanelComponent_Conditional_30_Conditional_9_For_2_Template(rf
|
|
|
625
625
|
const sortItem_r19 = ctx.$implicit;
|
|
626
626
|
const ɵ$index_522_r21 = ctx.$index;
|
|
627
627
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
628
|
-
i0.ɵɵconditional(ctx_r1.
|
|
628
|
+
i0.ɵɵconditional(ctx_r1.IsSortDropBefore(sortItem_r19) ? 0 : -1);
|
|
629
629
|
i0.ɵɵadvance();
|
|
630
|
-
i0.ɵɵclassProp("dragging", ctx_r1.
|
|
630
|
+
i0.ɵɵclassProp("dragging", ctx_r1.DraggedSortItem === sortItem_r19)("drop-target", ctx_r1.DropTargetSortItem === sortItem_r19);
|
|
631
631
|
i0.ɵɵadvance(2);
|
|
632
632
|
i0.ɵɵtextInterpolate(ɵ$index_522_r21 + 1);
|
|
633
633
|
i0.ɵɵadvance(3);
|
|
634
634
|
i0.ɵɵtwoWayProperty("ngModel", sortItem_r19.field);
|
|
635
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
635
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
636
636
|
i0.ɵɵadvance();
|
|
637
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
637
|
+
i0.ɵɵrepeater(ctx_r1.SortableFields);
|
|
638
638
|
i0.ɵɵadvance(3);
|
|
639
639
|
i0.ɵɵclassProp("active", sortItem_r19.direction === "asc");
|
|
640
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
640
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
641
641
|
i0.ɵɵadvance(2);
|
|
642
642
|
i0.ɵɵclassProp("active", sortItem_r19.direction === "desc");
|
|
643
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
643
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
644
644
|
i0.ɵɵadvance(2);
|
|
645
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
645
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
646
646
|
i0.ɵɵadvance(2);
|
|
647
|
-
i0.ɵɵconditional(ctx_r1.
|
|
647
|
+
i0.ɵɵconditional(ctx_r1.IsSortDropAfter(sortItem_r19) && ɵ$index_522_r21 === ctx_r1.SortItems.length - 1 ? 16 : -1);
|
|
648
648
|
} }
|
|
649
649
|
function ViewConfigPanelComponent_Conditional_30_Conditional_9_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
650
650
|
i0.ɵɵelementStart(0, "div", 136);
|
|
@@ -661,9 +661,9 @@ function ViewConfigPanelComponent_Conditional_30_Conditional_9_Template(rf, ctx)
|
|
|
661
661
|
} if (rf & 2) {
|
|
662
662
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
663
663
|
i0.ɵɵadvance();
|
|
664
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
664
|
+
i0.ɵɵrepeater(ctx_r1.SortItems);
|
|
665
665
|
i0.ɵɵadvance(2);
|
|
666
|
-
i0.ɵɵconditional(ctx_r1.
|
|
666
|
+
i0.ɵɵconditional(ctx_r1.SortItems.length > 1 ? 3 : -1);
|
|
667
667
|
} }
|
|
668
668
|
function ViewConfigPanelComponent_Conditional_30_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
669
669
|
i0.ɵɵelementStart(0, "div", 134);
|
|
@@ -681,7 +681,7 @@ function ViewConfigPanelComponent_Conditional_30_Template(rf, ctx) { if (rf & 1)
|
|
|
681
681
|
i0.ɵɵtext(4, " Define how records should be ordered. Add multiple levels to sort by secondary fields when values are equal. ");
|
|
682
682
|
i0.ɵɵelementEnd()();
|
|
683
683
|
i0.ɵɵelementStart(5, "button", 133);
|
|
684
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
684
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.AddSortLevel()); });
|
|
685
685
|
i0.ɵɵelement(6, "i", 59);
|
|
686
686
|
i0.ɵɵelementStart(7, "span");
|
|
687
687
|
i0.ɵɵtext(8, "Add Sort Level");
|
|
@@ -691,9 +691,9 @@ function ViewConfigPanelComponent_Conditional_30_Template(rf, ctx) { if (rf & 1)
|
|
|
691
691
|
} if (rf & 2) {
|
|
692
692
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
693
693
|
i0.ɵɵadvance(5);
|
|
694
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
694
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit || ctx_r1.SortItems.length >= ctx_r1.SortableFields.length);
|
|
695
695
|
i0.ɵɵadvance(4);
|
|
696
|
-
i0.ɵɵconditional(ctx_r1.
|
|
696
|
+
i0.ɵɵconditional(ctx_r1.SortItems.length > 0 ? 9 : 10);
|
|
697
697
|
} }
|
|
698
698
|
function ViewConfigPanelComponent_Conditional_31_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
699
699
|
i0.ɵɵelement(0, "i", 157);
|
|
@@ -710,7 +710,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_20_Conditional_5_Te
|
|
|
710
710
|
} if (rf & 2) {
|
|
711
711
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
712
712
|
i0.ɵɵadvance(3);
|
|
713
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
713
|
+
i0.ɵɵtextInterpolate(ctx_r1.SmartFilterExplanation);
|
|
714
714
|
} }
|
|
715
715
|
function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
716
716
|
const _r23 = i0.ɵɵgetCurrentView();
|
|
@@ -718,7 +718,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template(rf, ctx
|
|
|
718
718
|
i0.ɵɵelement(3, "i", 153);
|
|
719
719
|
i0.ɵɵelementEnd();
|
|
720
720
|
i0.ɵɵelementStart(4, "textarea", 162);
|
|
721
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_textarea_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
721
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_textarea_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.SmartFilterPrompt, $event) || (ctx_r1.SmartFilterPrompt = $event); return i0.ɵɵresetView($event); });
|
|
722
722
|
i0.ɵɵelementEnd()();
|
|
723
723
|
i0.ɵɵconditionalCreate(5, ViewConfigPanelComponent_Conditional_31_Conditional_20_Conditional_5_Template, 4, 1, "div", 163);
|
|
724
724
|
i0.ɵɵelementStart(6, "div", 164)(7, "div", 165);
|
|
@@ -727,22 +727,22 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template(rf, ctx
|
|
|
727
727
|
i0.ɵɵtext(10, "Try these examples:");
|
|
728
728
|
i0.ɵɵelementEnd()();
|
|
729
729
|
i0.ɵɵelementStart(11, "div", 167)(12, "button", 168);
|
|
730
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
730
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApplySmartFilterExample("Show records created in the last 30 days")); });
|
|
731
731
|
i0.ɵɵelement(13, "i", 169);
|
|
732
732
|
i0.ɵɵtext(14, " Last 30 days ");
|
|
733
733
|
i0.ɵɵelementEnd();
|
|
734
734
|
i0.ɵɵelementStart(15, "button", 168);
|
|
735
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
735
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApplySmartFilterExample("Active records only")); });
|
|
736
736
|
i0.ɵɵelement(16, "i", 170);
|
|
737
737
|
i0.ɵɵtext(17, " Active only ");
|
|
738
738
|
i0.ɵɵelementEnd();
|
|
739
739
|
i0.ɵɵelementStart(18, "button", 168);
|
|
740
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
740
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApplySmartFilterExample("Records with high priority")); });
|
|
741
741
|
i0.ɵɵelement(19, "i", 171);
|
|
742
742
|
i0.ɵɵtext(20, " High priority ");
|
|
743
743
|
i0.ɵɵelementEnd();
|
|
744
744
|
i0.ɵɵelementStart(21, "button", 168);
|
|
745
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
745
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApplySmartFilterExample("Records modified this week")); });
|
|
746
746
|
i0.ɵɵelement(22, "i", 172);
|
|
747
747
|
i0.ɵɵtext(23, " Modified this week ");
|
|
748
748
|
i0.ɵɵelementEnd()()();
|
|
@@ -754,18 +754,18 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_20_Template(rf, ctx
|
|
|
754
754
|
} if (rf & 2) {
|
|
755
755
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
756
756
|
i0.ɵɵadvance(4);
|
|
757
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
758
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
757
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SmartFilterPrompt);
|
|
758
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
759
759
|
i0.ɵɵadvance();
|
|
760
|
-
i0.ɵɵconditional(ctx_r1.
|
|
760
|
+
i0.ɵɵconditional(ctx_r1.SmartFilterExplanation ? 5 : -1);
|
|
761
761
|
i0.ɵɵadvance(7);
|
|
762
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
762
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
763
763
|
i0.ɵɵadvance(3);
|
|
764
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
764
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
765
765
|
i0.ɵɵadvance(3);
|
|
766
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
766
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
767
767
|
i0.ɵɵadvance(3);
|
|
768
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
768
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
769
769
|
} }
|
|
770
770
|
function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
771
771
|
i0.ɵɵelementStart(0, "span", 184);
|
|
@@ -777,9 +777,9 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_4_Te
|
|
|
777
777
|
} if (rf & 2) {
|
|
778
778
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
779
779
|
i0.ɵɵadvance();
|
|
780
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
780
|
+
i0.ɵɵtextInterpolate(ctx_r1.GetFilterCount());
|
|
781
781
|
i0.ɵɵadvance(2);
|
|
782
|
-
i0.ɵɵtextInterpolate(ctx_r1.
|
|
782
|
+
i0.ɵɵtextInterpolate(ctx_r1.GetFilterSummary());
|
|
783
783
|
} }
|
|
784
784
|
function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
785
785
|
i0.ɵɵelementStart(0, "span", 178);
|
|
@@ -789,7 +789,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_5_Te
|
|
|
789
789
|
function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
790
790
|
const _r25 = i0.ɵɵgetCurrentView();
|
|
791
791
|
i0.ɵɵelementStart(0, "button", 186);
|
|
792
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
792
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
|
|
793
793
|
i0.ɵɵelement(1, "i", 8);
|
|
794
794
|
i0.ɵɵtext(2, " Clear ");
|
|
795
795
|
i0.ɵɵelementEnd();
|
|
@@ -802,7 +802,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_21_Template(rf, ctx
|
|
|
802
802
|
i0.ɵɵelementStart(6, "div", 179);
|
|
803
803
|
i0.ɵɵconditionalCreate(7, ViewConfigPanelComponent_Conditional_31_Conditional_21_Conditional_7_Template, 3, 0, "button", 180);
|
|
804
804
|
i0.ɵɵelementStart(8, "button", 181);
|
|
805
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_21_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
805
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Conditional_21_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenFilterDialog()); });
|
|
806
806
|
i0.ɵɵelement(9, "i", 182);
|
|
807
807
|
i0.ɵɵtext(10);
|
|
808
808
|
i0.ɵɵelementEnd()()()();
|
|
@@ -814,18 +814,18 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_21_Template(rf, ctx
|
|
|
814
814
|
} if (rf & 2) {
|
|
815
815
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
816
816
|
i0.ɵɵadvance(4);
|
|
817
|
-
i0.ɵɵconditional(ctx_r1.
|
|
817
|
+
i0.ɵɵconditional(ctx_r1.GetFilterCount() > 0 ? 4 : 5);
|
|
818
818
|
i0.ɵɵadvance(3);
|
|
819
|
-
i0.ɵɵconditional(ctx_r1.
|
|
819
|
+
i0.ɵɵconditional(ctx_r1.GetFilterCount() > 0 && ctx_r1.CanEdit ? 7 : -1);
|
|
820
820
|
i0.ɵɵadvance();
|
|
821
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
821
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit && ctx_r1.GetFilterCount() === 0);
|
|
822
822
|
i0.ɵɵadvance(2);
|
|
823
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
823
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.GetFilterCount() > 0 ? "Edit Filters" : "Add Filters", " ");
|
|
824
824
|
} }
|
|
825
825
|
function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
826
826
|
const _r22 = i0.ɵɵgetCurrentView();
|
|
827
827
|
i0.ɵɵelementStart(0, "div", 18)(1, "div", 150)(2, "button", 151);
|
|
828
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
828
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetFilterMode("smart")); });
|
|
829
829
|
i0.ɵɵelementStart(3, "div", 152);
|
|
830
830
|
i0.ɵɵelement(4, "i", 153);
|
|
831
831
|
i0.ɵɵelementEnd();
|
|
@@ -838,7 +838,7 @@ function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1)
|
|
|
838
838
|
i0.ɵɵconditionalCreate(10, ViewConfigPanelComponent_Conditional_31_Conditional_10_Template, 1, 0, "i", 157);
|
|
839
839
|
i0.ɵɵelementEnd();
|
|
840
840
|
i0.ɵɵelementStart(11, "button", 151);
|
|
841
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
841
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_31_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetFilterMode("traditional")); });
|
|
842
842
|
i0.ɵɵelementStart(12, "div", 152);
|
|
843
843
|
i0.ɵɵelement(13, "i", 109);
|
|
844
844
|
i0.ɵɵelementEnd();
|
|
@@ -856,19 +856,19 @@ function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1)
|
|
|
856
856
|
} if (rf & 2) {
|
|
857
857
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
858
858
|
i0.ɵɵadvance(2);
|
|
859
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
860
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
859
|
+
i0.ɵɵclassProp("active", ctx_r1.FilterMode === "smart");
|
|
860
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
861
861
|
i0.ɵɵadvance(8);
|
|
862
|
-
i0.ɵɵconditional(ctx_r1.
|
|
862
|
+
i0.ɵɵconditional(ctx_r1.FilterMode === "smart" ? 10 : -1);
|
|
863
863
|
i0.ɵɵadvance();
|
|
864
|
-
i0.ɵɵclassProp("active", ctx_r1.
|
|
865
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
864
|
+
i0.ɵɵclassProp("active", ctx_r1.FilterMode === "traditional");
|
|
865
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
866
866
|
i0.ɵɵadvance(8);
|
|
867
|
-
i0.ɵɵconditional(ctx_r1.
|
|
867
|
+
i0.ɵɵconditional(ctx_r1.FilterMode === "traditional" ? 19 : -1);
|
|
868
868
|
i0.ɵɵadvance();
|
|
869
|
-
i0.ɵɵconditional(ctx_r1.
|
|
869
|
+
i0.ɵɵconditional(ctx_r1.FilterMode === "smart" ? 20 : -1);
|
|
870
870
|
i0.ɵɵadvance();
|
|
871
|
-
i0.ɵɵconditional(ctx_r1.
|
|
871
|
+
i0.ɵɵconditional(ctx_r1.FilterMode === "traditional" ? 21 : -1);
|
|
872
872
|
} }
|
|
873
873
|
function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
874
874
|
i0.ɵɵelementStart(0, "span", 205);
|
|
@@ -890,23 +890,23 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template(rf
|
|
|
890
890
|
i0.ɵɵconditionalCreate(10, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_10_Template, 2, 0, "span", 205);
|
|
891
891
|
i0.ɵɵelementEnd()();
|
|
892
892
|
i0.ɵɵelementStart(11, "div", 206)(12, "button", 207);
|
|
893
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_12_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
893
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_12_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.MoveAggregateUp(agg_r28)); });
|
|
894
894
|
i0.ɵɵelement(13, "i", 51);
|
|
895
895
|
i0.ɵɵelementEnd();
|
|
896
896
|
i0.ɵɵelementStart(14, "button", 208);
|
|
897
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_14_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
897
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_14_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.MoveAggregateDown(agg_r28)); });
|
|
898
898
|
i0.ɵɵelement(15, "i", 53);
|
|
899
899
|
i0.ɵɵelementEnd();
|
|
900
900
|
i0.ɵɵelementStart(16, "button", 209);
|
|
901
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_16_listener($event) { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
901
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_16_listener($event) { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleAggregateEnabled(agg_r28, $event)); });
|
|
902
902
|
i0.ɵɵelement(17, "i");
|
|
903
903
|
i0.ɵɵelementEnd();
|
|
904
904
|
i0.ɵɵelementStart(18, "button", 210);
|
|
905
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_18_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
905
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_18_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.EditAggregate(agg_r28)); });
|
|
906
906
|
i0.ɵɵelement(19, "i", 182);
|
|
907
907
|
i0.ɵɵelementEnd();
|
|
908
908
|
i0.ɵɵelementStart(20, "button", 211);
|
|
909
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_20_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.
|
|
909
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_20_listener() { const agg_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.RemoveAggregate(agg_r28)); });
|
|
910
910
|
i0.ɵɵelement(21, "i", 212);
|
|
911
911
|
i0.ɵɵelementEnd()()();
|
|
912
912
|
} if (rf & 2) {
|
|
@@ -925,18 +925,18 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template(rf
|
|
|
925
925
|
i0.ɵɵadvance();
|
|
926
926
|
i0.ɵɵconditional(agg_r28.smartPrompt ? 10 : -1);
|
|
927
927
|
i0.ɵɵadvance(2);
|
|
928
|
-
i0.ɵɵproperty("disabled", ɵ$index_733_r29 === 0 || !ctx_r1.
|
|
928
|
+
i0.ɵɵproperty("disabled", ɵ$index_733_r29 === 0 || !ctx_r1.CanEdit);
|
|
929
929
|
i0.ɵɵadvance(2);
|
|
930
|
-
i0.ɵɵproperty("disabled", ɵ$index_733_r29 === ctx_r1.
|
|
930
|
+
i0.ɵɵproperty("disabled", ɵ$index_733_r29 === ctx_r1.Aggregates.length - 1 || !ctx_r1.CanEdit);
|
|
931
931
|
i0.ɵɵadvance(2);
|
|
932
932
|
i0.ɵɵclassProp("enabled", agg_r28.enabled !== false);
|
|
933
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
933
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit)("title", agg_r28.enabled !== false ? "Disable" : "Enable");
|
|
934
934
|
i0.ɵɵadvance();
|
|
935
935
|
i0.ɵɵclassMap(agg_r28.enabled !== false ? "fa-solid fa-eye" : "fa-solid fa-eye-slash");
|
|
936
936
|
i0.ɵɵadvance();
|
|
937
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
937
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
938
938
|
i0.ɵɵadvance(2);
|
|
939
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
939
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
940
940
|
} }
|
|
941
941
|
function ViewConfigPanelComponent_Conditional_32_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
942
942
|
i0.ɵɵelementStart(0, "div", 193);
|
|
@@ -955,11 +955,11 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_Template(rf, ctx)
|
|
|
955
955
|
} if (rf & 2) {
|
|
956
956
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
957
957
|
i0.ɵɵadvance();
|
|
958
|
-
i0.ɵɵrepeater(ctx_r1.
|
|
958
|
+
i0.ɵɵrepeater(ctx_r1.Aggregates);
|
|
959
959
|
i0.ɵɵadvance(6);
|
|
960
|
-
i0.ɵɵtextInterpolate2("", ctx_r1.
|
|
960
|
+
i0.ɵɵtextInterpolate2("", ctx_r1.CardAggregates.length, " card", ctx_r1.CardAggregates.length !== 1 ? "s" : "");
|
|
961
961
|
i0.ɵɵadvance(4);
|
|
962
|
-
i0.ɵɵtextInterpolate2("", ctx_r1.
|
|
962
|
+
i0.ɵɵtextInterpolate2("", ctx_r1.ColumnAggregates.length, " column footer", ctx_r1.ColumnAggregates.length !== 1 ? "s" : "");
|
|
963
963
|
} }
|
|
964
964
|
function ViewConfigPanelComponent_Conditional_32_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
965
965
|
i0.ɵɵelementStart(0, "div", 191);
|
|
@@ -977,7 +977,7 @@ function ViewConfigPanelComponent_Conditional_32_Template(rf, ctx) { if (rf & 1)
|
|
|
977
977
|
i0.ɵɵtext(4, " Add summary calculations like totals, averages, and counts. Display them in cards or as column footers. ");
|
|
978
978
|
i0.ɵɵelementEnd()();
|
|
979
979
|
i0.ɵɵelementStart(5, "button", 190);
|
|
980
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
980
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenAddAggregateDialog()); });
|
|
981
981
|
i0.ɵɵelement(6, "i", 59);
|
|
982
982
|
i0.ɵɵelementStart(7, "span");
|
|
983
983
|
i0.ɵɵtext(8, "Add Aggregate");
|
|
@@ -991,9 +991,9 @@ function ViewConfigPanelComponent_Conditional_32_Template(rf, ctx) { if (rf & 1)
|
|
|
991
991
|
} if (rf & 2) {
|
|
992
992
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
993
993
|
i0.ɵɵadvance(5);
|
|
994
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
994
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
995
995
|
i0.ɵɵadvance(4);
|
|
996
|
-
i0.ɵɵconditional(ctx_r1.
|
|
996
|
+
i0.ɵɵconditional(ctx_r1.Aggregates.length > 0 ? 9 : 10);
|
|
997
997
|
} }
|
|
998
998
|
function ViewConfigPanelComponent_Conditional_33_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
999
999
|
i0.ɵɵelementStart(0, "span", 217);
|
|
@@ -1008,7 +1008,7 @@ function ViewConfigPanelComponent_Conditional_33_Conditional_27_Template(rf, ctx
|
|
|
1008
1008
|
i0.ɵɵtext(4, "Danger Zone");
|
|
1009
1009
|
i0.ɵɵelementEnd()();
|
|
1010
1010
|
i0.ɵɵelementStart(5, "button", 226);
|
|
1011
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_33_Conditional_27_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.
|
|
1011
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_33_Conditional_27_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDelete()); });
|
|
1012
1012
|
i0.ɵɵelement(6, "i", 212);
|
|
1013
1013
|
i0.ɵɵelementStart(7, "span");
|
|
1014
1014
|
i0.ɵɵtext(8, "Delete View");
|
|
@@ -1025,7 +1025,7 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
|
|
|
1025
1025
|
i0.ɵɵtext(8, "Name");
|
|
1026
1026
|
i0.ɵɵelementEnd();
|
|
1027
1027
|
i0.ɵɵelementStart(9, "input", 216);
|
|
1028
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_input_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
1028
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_input_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.ViewName, $event) || (ctx_r1.ViewName = $event); return i0.ɵɵresetView($event); });
|
|
1029
1029
|
i0.ɵɵelementEnd();
|
|
1030
1030
|
i0.ɵɵconditionalCreate(10, ViewConfigPanelComponent_Conditional_33_Conditional_10_Template, 2, 0, "span", 217);
|
|
1031
1031
|
i0.ɵɵelementEnd();
|
|
@@ -1033,7 +1033,7 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
|
|
|
1033
1033
|
i0.ɵɵtext(13, "Description");
|
|
1034
1034
|
i0.ɵɵelementEnd();
|
|
1035
1035
|
i0.ɵɵelementStart(14, "textarea", 219);
|
|
1036
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_textarea_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
1036
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_textarea_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.ViewDescription, $event) || (ctx_r1.ViewDescription = $event); return i0.ɵɵresetView($event); });
|
|
1037
1037
|
i0.ɵɵelementEnd()()();
|
|
1038
1038
|
i0.ɵɵelementStart(15, "div", 30)(16, "div", 31);
|
|
1039
1039
|
i0.ɵɵelement(17, "i", 220);
|
|
@@ -1041,7 +1041,7 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
|
|
|
1041
1041
|
i0.ɵɵtext(19, "Sharing");
|
|
1042
1042
|
i0.ɵɵelementEnd()();
|
|
1043
1043
|
i0.ɵɵelementStart(20, "label", 221)(21, "input", 222);
|
|
1044
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.
|
|
1044
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.IsShared, $event) || (ctx_r1.IsShared = $event); return i0.ɵɵresetView($event); });
|
|
1045
1045
|
i0.ɵɵelementEnd();
|
|
1046
1046
|
i0.ɵɵelementStart(22, "span", 223)(23, "strong");
|
|
1047
1047
|
i0.ɵɵtext(24, "Share with others");
|
|
@@ -1054,19 +1054,19 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
|
|
|
1054
1054
|
} if (rf & 2) {
|
|
1055
1055
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
1056
1056
|
i0.ɵɵadvance(9);
|
|
1057
|
-
i0.ɵɵclassProp("invalid", !ctx_r1.
|
|
1058
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
1059
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
1057
|
+
i0.ɵɵclassProp("invalid", !ctx_r1.ViewName || !ctx_r1.ViewName.trim());
|
|
1058
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ViewName);
|
|
1059
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
1060
1060
|
i0.ɵɵadvance();
|
|
1061
|
-
i0.ɵɵconditional(!ctx_r1.
|
|
1061
|
+
i0.ɵɵconditional(!ctx_r1.ViewName || !ctx_r1.ViewName.trim() ? 10 : -1);
|
|
1062
1062
|
i0.ɵɵadvance(4);
|
|
1063
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
1064
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
1063
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ViewDescription);
|
|
1064
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
1065
1065
|
i0.ɵɵadvance(7);
|
|
1066
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.
|
|
1067
|
-
i0.ɵɵproperty("disabled", !ctx_r1.
|
|
1066
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.IsShared);
|
|
1067
|
+
i0.ɵɵproperty("disabled", !ctx_r1.CanEdit);
|
|
1068
1068
|
i0.ɵɵadvance(6);
|
|
1069
|
-
i0.ɵɵconditional(ctx_r1.
|
|
1069
|
+
i0.ɵɵconditional(ctx_r1.ViewEntity && ctx_r1.CanDelete ? 27 : -1);
|
|
1070
1070
|
} }
|
|
1071
1071
|
function ViewConfigPanelComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
1072
1072
|
i0.ɵɵelementStart(0, "div", 20);
|
|
@@ -1084,17 +1084,17 @@ function ViewConfigPanelComponent_Conditional_37_Conditional_2_Template(rf, ctx)
|
|
|
1084
1084
|
function ViewConfigPanelComponent_Conditional_37_Template(rf, ctx) { if (rf & 1) {
|
|
1085
1085
|
const _r32 = i0.ɵɵgetCurrentView();
|
|
1086
1086
|
i0.ɵɵelementStart(0, "button", 227);
|
|
1087
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_37_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
1087
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_37_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSave()); });
|
|
1088
1088
|
i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_37_Conditional_1_Template, 1, 0, "i", 228)(2, ViewConfigPanelComponent_Conditional_37_Conditional_2_Template, 1, 0, "i", 229);
|
|
1089
1089
|
i0.ɵɵtext(3);
|
|
1090
1090
|
i0.ɵɵelementEnd();
|
|
1091
1091
|
} if (rf & 2) {
|
|
1092
1092
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
1093
|
-
i0.ɵɵproperty("disabled", ctx_r1.
|
|
1093
|
+
i0.ɵɵproperty("disabled", ctx_r1.IsSaving || !ctx_r1.IsValid);
|
|
1094
1094
|
i0.ɵɵadvance();
|
|
1095
|
-
i0.ɵɵconditional(ctx_r1.
|
|
1095
|
+
i0.ɵɵconditional(ctx_r1.IsSaving ? 1 : 2);
|
|
1096
1096
|
i0.ɵɵadvance(2);
|
|
1097
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
1097
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.IsSaving ? "Saving..." : "Save", " ");
|
|
1098
1098
|
} }
|
|
1099
1099
|
function ViewConfigPanelComponent_Conditional_38_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1100
1100
|
i0.ɵɵelement(0, "i", 228);
|
|
@@ -1105,17 +1105,17 @@ function ViewConfigPanelComponent_Conditional_38_Conditional_2_Template(rf, ctx)
|
|
|
1105
1105
|
function ViewConfigPanelComponent_Conditional_38_Template(rf, ctx) { if (rf & 1) {
|
|
1106
1106
|
const _r33 = i0.ɵɵgetCurrentView();
|
|
1107
1107
|
i0.ɵɵelementStart(0, "button", 227);
|
|
1108
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_38_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
1108
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_38_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSaveAsNew()); });
|
|
1109
1109
|
i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_38_Conditional_1_Template, 1, 0, "i", 228)(2, ViewConfigPanelComponent_Conditional_38_Conditional_2_Template, 1, 0, "i", 59);
|
|
1110
1110
|
i0.ɵɵtext(3);
|
|
1111
1111
|
i0.ɵɵelementEnd();
|
|
1112
1112
|
} if (rf & 2) {
|
|
1113
1113
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
1114
|
-
i0.ɵɵproperty("disabled", ctx_r1.
|
|
1114
|
+
i0.ɵɵproperty("disabled", ctx_r1.IsSaving || !ctx_r1.IsValidForSaveAsNew);
|
|
1115
1115
|
i0.ɵɵadvance();
|
|
1116
|
-
i0.ɵɵconditional(ctx_r1.
|
|
1116
|
+
i0.ɵɵconditional(ctx_r1.IsSaving ? 1 : 2);
|
|
1117
1117
|
i0.ɵɵadvance(2);
|
|
1118
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
1118
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.IsSaving ? "Saving..." : "Create View", " ");
|
|
1119
1119
|
} }
|
|
1120
1120
|
function ViewConfigPanelComponent_Conditional_39_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1121
1121
|
i0.ɵɵelement(0, "i", 228);
|
|
@@ -1126,17 +1126,17 @@ function ViewConfigPanelComponent_Conditional_39_Conditional_2_Template(rf, ctx)
|
|
|
1126
1126
|
function ViewConfigPanelComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
|
|
1127
1127
|
const _r34 = i0.ɵɵgetCurrentView();
|
|
1128
1128
|
i0.ɵɵelementStart(0, "button", 227);
|
|
1129
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_39_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.
|
|
1129
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_39_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSaveDefaults()); });
|
|
1130
1130
|
i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_39_Conditional_1_Template, 1, 0, "i", 228)(2, ViewConfigPanelComponent_Conditional_39_Conditional_2_Template, 1, 0, "i", 229);
|
|
1131
1131
|
i0.ɵɵtext(3);
|
|
1132
1132
|
i0.ɵɵelementEnd();
|
|
1133
1133
|
} if (rf & 2) {
|
|
1134
1134
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
1135
|
-
i0.ɵɵproperty("disabled", ctx_r1.
|
|
1135
|
+
i0.ɵɵproperty("disabled", ctx_r1.IsSaving);
|
|
1136
1136
|
i0.ɵɵadvance();
|
|
1137
|
-
i0.ɵɵconditional(ctx_r1.
|
|
1137
|
+
i0.ɵɵconditional(ctx_r1.IsSaving ? 1 : 2);
|
|
1138
1138
|
i0.ɵɵadvance(2);
|
|
1139
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.
|
|
1139
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.IsSaving ? "Saving..." : "Save", " ");
|
|
1140
1140
|
} }
|
|
1141
1141
|
/**
|
|
1142
1142
|
* ViewConfigPanelComponent - Sliding panel for configuring view settings
|
|
@@ -1154,49 +1154,49 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1154
1154
|
/**
|
|
1155
1155
|
* The entity being viewed
|
|
1156
1156
|
*/
|
|
1157
|
-
|
|
1157
|
+
Entity = null;
|
|
1158
1158
|
/**
|
|
1159
1159
|
* The current view entity (null for default view)
|
|
1160
1160
|
*/
|
|
1161
|
-
|
|
1161
|
+
ViewEntity = null;
|
|
1162
1162
|
/**
|
|
1163
1163
|
* Whether the panel is open
|
|
1164
1164
|
*/
|
|
1165
|
-
|
|
1165
|
+
IsOpen = false;
|
|
1166
1166
|
/**
|
|
1167
1167
|
* Current grid state from the grid (includes live column widths/order from user interaction)
|
|
1168
1168
|
* This takes precedence over viewEntity.Columns for showing current state
|
|
1169
1169
|
*/
|
|
1170
|
-
|
|
1170
|
+
CurrentGridState = null;
|
|
1171
1171
|
/**
|
|
1172
1172
|
* Sample data for column format preview (first few records)
|
|
1173
1173
|
*/
|
|
1174
|
-
|
|
1174
|
+
SampleData = [];
|
|
1175
1175
|
/**
|
|
1176
1176
|
* Emitted when the panel should close
|
|
1177
1177
|
*/
|
|
1178
|
-
|
|
1178
|
+
Close = new EventEmitter();
|
|
1179
1179
|
/**
|
|
1180
1180
|
* Emitted when the view should be saved
|
|
1181
1181
|
*/
|
|
1182
|
-
|
|
1182
|
+
Save = new EventEmitter();
|
|
1183
1183
|
/**
|
|
1184
1184
|
* Emitted when default view settings should be saved to user settings
|
|
1185
1185
|
* (Used for dynamic/default views that persist to MJ: User Settings)
|
|
1186
1186
|
*/
|
|
1187
|
-
|
|
1187
|
+
SaveDefaults = new EventEmitter();
|
|
1188
1188
|
/**
|
|
1189
1189
|
* Emitted when the view should be deleted
|
|
1190
1190
|
*/
|
|
1191
|
-
|
|
1191
|
+
Delete = new EventEmitter();
|
|
1192
1192
|
/**
|
|
1193
1193
|
* Emitted when filter dialog should be opened (at dashboard level for full width)
|
|
1194
1194
|
*/
|
|
1195
|
-
|
|
1195
|
+
OpenFilterDialogRequest = new EventEmitter();
|
|
1196
1196
|
/**
|
|
1197
1197
|
* Filter state from external dialog (set by parent after dialog closes)
|
|
1198
1198
|
*/
|
|
1199
|
-
|
|
1199
|
+
ExternalFilterState = null;
|
|
1200
1200
|
/**
|
|
1201
1201
|
* When true, the panel is in "create new view" mode — shows the Settings tab
|
|
1202
1202
|
* and a "Create View" button even without a viewEntity.
|
|
@@ -1217,61 +1217,61 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1217
1217
|
/**
|
|
1218
1218
|
* Emitted when user wants to duplicate the current view (F-005)
|
|
1219
1219
|
*/
|
|
1220
|
-
|
|
1220
|
+
Duplicate = new EventEmitter();
|
|
1221
1221
|
// Form state
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1222
|
+
ViewName = '';
|
|
1223
|
+
ViewDescription = '';
|
|
1224
|
+
IsShared = false;
|
|
1225
|
+
Columns = [];
|
|
1226
1226
|
/** @deprecated Use sortItems instead */
|
|
1227
|
-
|
|
1227
|
+
SortField = null;
|
|
1228
1228
|
/** @deprecated Use sortItems instead */
|
|
1229
|
-
|
|
1229
|
+
SortDirection = 'asc';
|
|
1230
1230
|
/** Multi-column sort configuration (ordered by priority) */
|
|
1231
|
-
|
|
1231
|
+
SortItems = [];
|
|
1232
1232
|
// Sort drag state
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1233
|
+
DraggedSortItem = null;
|
|
1234
|
+
DropTargetSortItem = null;
|
|
1235
|
+
SortDropPosition = null;
|
|
1236
1236
|
// Available sort directions for dropdown
|
|
1237
|
-
|
|
1237
|
+
SortDirections = [
|
|
1238
1238
|
{ name: 'Ascending', value: 'asc' },
|
|
1239
1239
|
{ name: 'Descending', value: 'desc' }
|
|
1240
1240
|
];
|
|
1241
1241
|
// Smart Filter state
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1242
|
+
SmartFilterEnabled = false;
|
|
1243
|
+
SmartFilterPrompt = '';
|
|
1244
|
+
SmartFilterExplanation = '';
|
|
1245
1245
|
// Traditional Filter state
|
|
1246
|
-
|
|
1247
|
-
|
|
1246
|
+
FilterState = createEmptyFilter();
|
|
1247
|
+
FilterFields = [];
|
|
1248
1248
|
// Filter mode: 'smart' or 'traditional' (mutually exclusive)
|
|
1249
|
-
|
|
1249
|
+
FilterMode = 'smart';
|
|
1250
1250
|
// Aggregates state
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1251
|
+
Aggregates = [];
|
|
1252
|
+
ShowAggregateDialog = false;
|
|
1253
|
+
EditingAggregate = null;
|
|
1254
1254
|
// Saved filter state for mode switching (BUG-006: preserve both modes' data)
|
|
1255
1255
|
savedSmartFilterPrompt = '';
|
|
1256
1256
|
savedTraditionalFilter = createEmptyFilter();
|
|
1257
1257
|
// Filter mode switch confirmation (BUG-006)
|
|
1258
|
-
|
|
1259
|
-
|
|
1258
|
+
ShowFilterModeSwitchConfirm = false;
|
|
1259
|
+
PendingFilterModeSwitch = null;
|
|
1260
1260
|
// Local saving guard (BUG-003: race condition on double-click)
|
|
1261
1261
|
_localSaving = false;
|
|
1262
1262
|
// UI state
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1263
|
+
ActiveTab = 'columns';
|
|
1264
|
+
IsSaving = false;
|
|
1265
|
+
ColumnSearchText = '';
|
|
1266
1266
|
// Drag state for column reordering
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1267
|
+
DraggedColumn = null;
|
|
1268
|
+
DropTargetColumn = null;
|
|
1269
|
+
DropPosition = null;
|
|
1270
1270
|
// Column format editing state
|
|
1271
|
-
|
|
1271
|
+
FormatEditingColumn = null;
|
|
1272
1272
|
// Panel resize state
|
|
1273
|
-
|
|
1274
|
-
|
|
1273
|
+
IsResizing = false;
|
|
1274
|
+
PanelWidth = 520;
|
|
1275
1275
|
MIN_PANEL_WIDTH = 360;
|
|
1276
1276
|
MAX_PANEL_WIDTH = 800;
|
|
1277
1277
|
DEFAULT_PANEL_WIDTH = 520;
|
|
@@ -1283,8 +1283,8 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1283
1283
|
/**
|
|
1284
1284
|
* Whether tabs should show icons only (narrow panel mode)
|
|
1285
1285
|
*/
|
|
1286
|
-
get
|
|
1287
|
-
return this.
|
|
1286
|
+
get IsIconOnlyMode() {
|
|
1287
|
+
return this.PanelWidth < this.ICON_ONLY_THRESHOLD;
|
|
1288
1288
|
}
|
|
1289
1289
|
metadata = this.ProviderToUse;
|
|
1290
1290
|
constructor(cdr) {
|
|
@@ -1295,12 +1295,12 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1295
1295
|
* Handle keyboard shortcuts
|
|
1296
1296
|
* Escape: Close the panel or format sub-panel
|
|
1297
1297
|
*/
|
|
1298
|
-
|
|
1299
|
-
if (this.
|
|
1300
|
-
this.
|
|
1298
|
+
HandleEscape() {
|
|
1299
|
+
if (this.FormatEditingColumn) {
|
|
1300
|
+
this.CloseFormatEditor();
|
|
1301
1301
|
}
|
|
1302
|
-
else if (this.
|
|
1303
|
-
this.
|
|
1302
|
+
else if (this.IsOpen) {
|
|
1303
|
+
this.OnClose();
|
|
1304
1304
|
}
|
|
1305
1305
|
}
|
|
1306
1306
|
// ========================================
|
|
@@ -1309,11 +1309,11 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1309
1309
|
/**
|
|
1310
1310
|
* Start resizing the panel
|
|
1311
1311
|
*/
|
|
1312
|
-
|
|
1312
|
+
OnResizeStart(event) {
|
|
1313
1313
|
event.preventDefault();
|
|
1314
|
-
this.
|
|
1314
|
+
this.IsResizing = true;
|
|
1315
1315
|
this.resizeStartX = event.clientX;
|
|
1316
|
-
this.resizeStartWidth = this.
|
|
1316
|
+
this.resizeStartWidth = this.PanelWidth;
|
|
1317
1317
|
// Add document-level listeners for mouse move and up
|
|
1318
1318
|
document.addEventListener('mousemove', this.onResizeMove);
|
|
1319
1319
|
document.addEventListener('mouseup', this.onResizeEnd);
|
|
@@ -1324,21 +1324,21 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1324
1324
|
* Handle resize movement (bound to document)
|
|
1325
1325
|
*/
|
|
1326
1326
|
onResizeMove = (event) => {
|
|
1327
|
-
if (!this.
|
|
1327
|
+
if (!this.IsResizing)
|
|
1328
1328
|
return;
|
|
1329
1329
|
// Calculate new width (panel is on the right, so moving left increases width)
|
|
1330
1330
|
const deltaX = this.resizeStartX - event.clientX;
|
|
1331
1331
|
let newWidth = this.resizeStartWidth + deltaX;
|
|
1332
1332
|
// Clamp to min/max bounds
|
|
1333
1333
|
newWidth = Math.max(this.MIN_PANEL_WIDTH, Math.min(this.MAX_PANEL_WIDTH, newWidth));
|
|
1334
|
-
this.
|
|
1334
|
+
this.PanelWidth = newWidth;
|
|
1335
1335
|
this.cdr.detectChanges();
|
|
1336
1336
|
};
|
|
1337
1337
|
/**
|
|
1338
1338
|
* End resizing the panel (bound to document)
|
|
1339
1339
|
*/
|
|
1340
1340
|
onResizeEnd = () => {
|
|
1341
|
-
this.
|
|
1341
|
+
this.IsResizing = false;
|
|
1342
1342
|
document.removeEventListener('mousemove', this.onResizeMove);
|
|
1343
1343
|
document.removeEventListener('mouseup', this.onResizeEnd);
|
|
1344
1344
|
document.body.style.cursor = '';
|
|
@@ -1360,7 +1360,7 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1360
1360
|
if (savedWidth) {
|
|
1361
1361
|
const width = parseInt(savedWidth, 10);
|
|
1362
1362
|
if (!isNaN(width) && width >= this.MIN_PANEL_WIDTH && width <= this.MAX_PANEL_WIDTH) {
|
|
1363
|
-
this.
|
|
1363
|
+
this.PanelWidth = width;
|
|
1364
1364
|
}
|
|
1365
1365
|
}
|
|
1366
1366
|
}
|
|
@@ -1373,7 +1373,7 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1373
1373
|
*/
|
|
1374
1374
|
async savePanelWidth() {
|
|
1375
1375
|
try {
|
|
1376
|
-
await UserInfoEngine.Instance.SetSetting(this.PANEL_WIDTH_SETTING_KEY, String(this.
|
|
1376
|
+
await UserInfoEngine.Instance.SetSetting(this.PANEL_WIDTH_SETTING_KEY, String(this.PanelWidth));
|
|
1377
1377
|
}
|
|
1378
1378
|
catch (error) {
|
|
1379
1379
|
console.warn('[ViewConfigPanel] Failed to save panel width:', error);
|
|
@@ -1381,31 +1381,31 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1381
1381
|
}
|
|
1382
1382
|
ngOnChanges(changes) {
|
|
1383
1383
|
// Reset to first tab and clear search when panel opens
|
|
1384
|
-
if (changes['
|
|
1384
|
+
if (changes['IsOpen'] && this.IsOpen) {
|
|
1385
1385
|
// BUG-011: If DefaultSaveAsNew is set, open on Settings tab with name focused
|
|
1386
|
-
this.
|
|
1387
|
-
this.
|
|
1388
|
-
this.
|
|
1386
|
+
this.ActiveTab = this.DefaultSaveAsNew ? 'settings' : 'columns';
|
|
1387
|
+
this.ColumnSearchText = '';
|
|
1388
|
+
this.FormatEditingColumn = null;
|
|
1389
1389
|
this._localSaving = false;
|
|
1390
1390
|
// Also close any open aggregate dialog
|
|
1391
|
-
this.
|
|
1392
|
-
this.
|
|
1391
|
+
this.ShowAggregateDialog = false;
|
|
1392
|
+
this.EditingAggregate = null;
|
|
1393
1393
|
// Close filter mode switch confirm
|
|
1394
|
-
this.
|
|
1395
|
-
this.
|
|
1394
|
+
this.ShowFilterModeSwitchConfirm = false;
|
|
1395
|
+
this.PendingFilterModeSwitch = null;
|
|
1396
1396
|
// Re-initialize from entity to get fresh state
|
|
1397
1397
|
this.initializeFromEntity();
|
|
1398
1398
|
}
|
|
1399
1399
|
// BUG-003: Reset local saving guard when isSaving transitions from true to false
|
|
1400
|
-
if (changes['
|
|
1400
|
+
if (changes['IsSaving'] && !this.IsSaving && changes['IsSaving'].previousValue === true) {
|
|
1401
1401
|
this._localSaving = false;
|
|
1402
1402
|
}
|
|
1403
|
-
if (changes['
|
|
1403
|
+
if (changes['Entity'] || changes['ViewEntity'] || changes['CurrentGridState']) {
|
|
1404
1404
|
this.initializeFromEntity();
|
|
1405
1405
|
}
|
|
1406
1406
|
// Apply external filter state when it changes (from dashboard-level dialog)
|
|
1407
|
-
if (changes['
|
|
1408
|
-
this.
|
|
1407
|
+
if (changes['ExternalFilterState'] && this.ExternalFilterState) {
|
|
1408
|
+
this.FilterState = this.ExternalFilterState;
|
|
1409
1409
|
this.cdr.detectChanges();
|
|
1410
1410
|
}
|
|
1411
1411
|
}
|
|
@@ -1414,12 +1414,12 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1414
1414
|
* Priority for column state: currentGridState > viewEntity.Columns > entity defaults
|
|
1415
1415
|
*/
|
|
1416
1416
|
initializeFromEntity() {
|
|
1417
|
-
if (!this.
|
|
1418
|
-
this.
|
|
1417
|
+
if (!this.Entity) {
|
|
1418
|
+
this.Columns = [];
|
|
1419
1419
|
return;
|
|
1420
1420
|
}
|
|
1421
1421
|
// Initialize columns from entity fields (including __mj_ fields for audit/timestamp info)
|
|
1422
|
-
this.
|
|
1422
|
+
this.Columns = this.Entity.Fields
|
|
1423
1423
|
.map((field, index) => ({
|
|
1424
1424
|
fieldId: field.ID,
|
|
1425
1425
|
fieldName: field.Name,
|
|
@@ -1432,31 +1432,31 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1432
1432
|
format: undefined
|
|
1433
1433
|
}));
|
|
1434
1434
|
// Priority 1: Use currentGridState if available (reflects live grid state including resizes)
|
|
1435
|
-
if (this.
|
|
1436
|
-
this.applyGridStateToColumns(this.
|
|
1435
|
+
if (this.CurrentGridState?.columnSettings && this.CurrentGridState.columnSettings.length > 0) {
|
|
1436
|
+
this.applyGridStateToColumns(this.CurrentGridState.columnSettings);
|
|
1437
1437
|
// Also apply sort from currentGridState (supports multi-sort)
|
|
1438
|
-
if (this.
|
|
1439
|
-
this.
|
|
1438
|
+
if (this.CurrentGridState.sortSettings && this.CurrentGridState.sortSettings.length > 0) {
|
|
1439
|
+
this.SortItems = this.CurrentGridState.sortSettings.map(s => ({
|
|
1440
1440
|
field: s.field,
|
|
1441
1441
|
direction: s.dir
|
|
1442
1442
|
}));
|
|
1443
1443
|
// Keep legacy fields in sync for backward compatibility
|
|
1444
|
-
this.
|
|
1445
|
-
this.
|
|
1444
|
+
this.SortField = this.CurrentGridState.sortSettings[0].field;
|
|
1445
|
+
this.SortDirection = this.CurrentGridState.sortSettings[0].dir;
|
|
1446
1446
|
}
|
|
1447
1447
|
else {
|
|
1448
|
-
this.
|
|
1448
|
+
this.SortItems = [];
|
|
1449
1449
|
}
|
|
1450
1450
|
}
|
|
1451
1451
|
// Priority 2: If we have a view, apply its column configuration
|
|
1452
|
-
else if (this.
|
|
1453
|
-
const viewColumns = this.
|
|
1452
|
+
else if (this.ViewEntity) {
|
|
1453
|
+
const viewColumns = this.ViewEntity.Columns;
|
|
1454
1454
|
if (viewColumns && viewColumns.length > 0) {
|
|
1455
1455
|
// Mark all columns as hidden initially
|
|
1456
|
-
this.
|
|
1456
|
+
this.Columns.forEach(c => c.visible = false);
|
|
1457
1457
|
// Apply view column settings
|
|
1458
1458
|
viewColumns.forEach((vc, idx) => {
|
|
1459
|
-
const column = this.
|
|
1459
|
+
const column = this.Columns.find(c => c.fieldName.toLowerCase() === vc.Name?.toLowerCase());
|
|
1460
1460
|
if (column) {
|
|
1461
1461
|
column.visible = !vc.hidden;
|
|
1462
1462
|
column.width = vc.width || null;
|
|
@@ -1472,73 +1472,73 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1472
1472
|
}
|
|
1473
1473
|
});
|
|
1474
1474
|
// Sort by orderIndex
|
|
1475
|
-
this.
|
|
1475
|
+
this.Columns.sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1476
1476
|
}
|
|
1477
1477
|
// Apply view's sort configuration (supports multi-sort)
|
|
1478
|
-
const sortInfo = this.
|
|
1478
|
+
const sortInfo = this.ViewEntity.ViewSortInfo;
|
|
1479
1479
|
if (sortInfo && sortInfo.length > 0) {
|
|
1480
|
-
this.
|
|
1480
|
+
this.SortItems = sortInfo.map(s => ({
|
|
1481
1481
|
field: s.field,
|
|
1482
1482
|
direction: s.direction === 'Desc' ? 'desc' : 'asc'
|
|
1483
1483
|
}));
|
|
1484
1484
|
// Keep legacy fields in sync for backward compatibility
|
|
1485
|
-
this.
|
|
1486
|
-
this.
|
|
1485
|
+
this.SortField = sortInfo[0].field;
|
|
1486
|
+
this.SortDirection = sortInfo[0].direction === 'Desc' ? 'desc' : 'asc';
|
|
1487
1487
|
}
|
|
1488
1488
|
else {
|
|
1489
|
-
this.
|
|
1489
|
+
this.SortItems = [];
|
|
1490
1490
|
}
|
|
1491
1491
|
}
|
|
1492
1492
|
// Initialize filter fields from entity
|
|
1493
|
-
this.
|
|
1493
|
+
this.FilterFields = this.buildFilterFields();
|
|
1494
1494
|
// Apply view entity metadata (name, description, etc.) if available
|
|
1495
|
-
if (this.
|
|
1496
|
-
this.
|
|
1497
|
-
this.
|
|
1498
|
-
this.
|
|
1495
|
+
if (this.ViewEntity) {
|
|
1496
|
+
this.ViewName = this.ViewEntity.Name;
|
|
1497
|
+
this.ViewDescription = this.ViewEntity.Description || '';
|
|
1498
|
+
this.IsShared = this.ViewEntity.IsShared;
|
|
1499
1499
|
// Apply view's smart filter configuration
|
|
1500
|
-
this.
|
|
1501
|
-
this.
|
|
1502
|
-
this.
|
|
1500
|
+
this.SmartFilterEnabled = this.ViewEntity.SmartFilterEnabled || false;
|
|
1501
|
+
this.SmartFilterPrompt = this.ViewEntity.SmartFilterPrompt || '';
|
|
1502
|
+
this.SmartFilterExplanation = this.ViewEntity.SmartFilterExplanation || '';
|
|
1503
1503
|
// Apply view's traditional filter state
|
|
1504
|
-
this.
|
|
1504
|
+
this.FilterState = this.parseFilterState(this.ViewEntity.FilterState);
|
|
1505
1505
|
// Set filter mode based on which type of filter is active
|
|
1506
1506
|
// Smart filter takes precedence if enabled
|
|
1507
|
-
if (this.
|
|
1508
|
-
this.
|
|
1507
|
+
if (this.SmartFilterEnabled && this.SmartFilterPrompt) {
|
|
1508
|
+
this.FilterMode = 'smart';
|
|
1509
1509
|
}
|
|
1510
|
-
else if (this.
|
|
1511
|
-
this.
|
|
1510
|
+
else if (this.GetFilterCount() > 0) {
|
|
1511
|
+
this.FilterMode = 'traditional';
|
|
1512
1512
|
}
|
|
1513
1513
|
else {
|
|
1514
1514
|
// Default to smart mode for new/empty filters (promote AI filtering)
|
|
1515
|
-
this.
|
|
1516
|
-
this.
|
|
1515
|
+
this.FilterMode = 'smart';
|
|
1516
|
+
this.SmartFilterEnabled = true;
|
|
1517
1517
|
}
|
|
1518
1518
|
}
|
|
1519
1519
|
else {
|
|
1520
1520
|
// Default view or pending new view — use pending values if creating a new view
|
|
1521
|
-
this.
|
|
1522
|
-
this.
|
|
1523
|
-
this.
|
|
1524
|
-
if (!this.
|
|
1525
|
-
this.
|
|
1526
|
-
this.
|
|
1527
|
-
this.
|
|
1521
|
+
this.ViewName = this.DefaultSaveAsNew ? this.PendingNewViewName : '';
|
|
1522
|
+
this.ViewDescription = this.DefaultSaveAsNew ? this.PendingNewViewDescription : '';
|
|
1523
|
+
this.IsShared = this.DefaultSaveAsNew ? this.PendingNewViewIsShared : false;
|
|
1524
|
+
if (!this.CurrentGridState?.sortSettings?.length) {
|
|
1525
|
+
this.SortField = null;
|
|
1526
|
+
this.SortDirection = 'asc';
|
|
1527
|
+
this.SortItems = [];
|
|
1528
1528
|
}
|
|
1529
|
-
this.
|
|
1530
|
-
this.
|
|
1531
|
-
this.
|
|
1529
|
+
this.SmartFilterPrompt = '';
|
|
1530
|
+
this.SmartFilterExplanation = '';
|
|
1531
|
+
this.FilterState = createEmptyFilter();
|
|
1532
1532
|
// Default to smart mode (promote AI filtering)
|
|
1533
|
-
this.
|
|
1534
|
-
this.
|
|
1533
|
+
this.FilterMode = 'smart';
|
|
1534
|
+
this.SmartFilterEnabled = true;
|
|
1535
1535
|
}
|
|
1536
1536
|
// Load aggregates from currentGridState if available
|
|
1537
|
-
if (this.
|
|
1538
|
-
this.
|
|
1537
|
+
if (this.CurrentGridState?.aggregates?.expressions) {
|
|
1538
|
+
this.Aggregates = [...this.CurrentGridState.aggregates.expressions];
|
|
1539
1539
|
}
|
|
1540
1540
|
else {
|
|
1541
|
-
this.
|
|
1541
|
+
this.Aggregates = [];
|
|
1542
1542
|
}
|
|
1543
1543
|
this.cdr.detectChanges();
|
|
1544
1544
|
}
|
|
@@ -1546,9 +1546,9 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1546
1546
|
* Build filter fields from entity fields (including __mj_ fields for filtering by timestamps)
|
|
1547
1547
|
*/
|
|
1548
1548
|
buildFilterFields() {
|
|
1549
|
-
if (!this.
|
|
1549
|
+
if (!this.Entity)
|
|
1550
1550
|
return [];
|
|
1551
|
-
return this.
|
|
1551
|
+
return this.Entity.Fields
|
|
1552
1552
|
.filter(f => !f.IsBinaryFieldType)
|
|
1553
1553
|
.map(field => ({
|
|
1554
1554
|
name: field.Name,
|
|
@@ -1605,24 +1605,24 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1605
1605
|
/**
|
|
1606
1606
|
* Handle filter state change from filter builder
|
|
1607
1607
|
*/
|
|
1608
|
-
|
|
1609
|
-
this.
|
|
1608
|
+
OnFilterChange(filter) {
|
|
1609
|
+
this.FilterState = filter;
|
|
1610
1610
|
this.cdr.detectChanges();
|
|
1611
1611
|
}
|
|
1612
1612
|
/**
|
|
1613
1613
|
* Open the filter dialog - emits event to parent (dashboard) which renders the dialog at viewport level
|
|
1614
1614
|
*/
|
|
1615
|
-
|
|
1616
|
-
this.
|
|
1617
|
-
filterState: this.
|
|
1618
|
-
filterFields: this.
|
|
1615
|
+
OpenFilterDialog() {
|
|
1616
|
+
this.OpenFilterDialogRequest.emit({
|
|
1617
|
+
filterState: this.FilterState,
|
|
1618
|
+
filterFields: this.FilterFields
|
|
1619
1619
|
});
|
|
1620
1620
|
}
|
|
1621
1621
|
/**
|
|
1622
1622
|
* Get the count of active filter rules
|
|
1623
1623
|
*/
|
|
1624
|
-
|
|
1625
|
-
return this.countFilters(this.
|
|
1624
|
+
GetFilterCount() {
|
|
1625
|
+
return this.countFilters(this.FilterState);
|
|
1626
1626
|
}
|
|
1627
1627
|
/**
|
|
1628
1628
|
* Count filters recursively
|
|
@@ -1642,8 +1642,8 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1642
1642
|
/**
|
|
1643
1643
|
* Get a human-readable summary of the filter state
|
|
1644
1644
|
*/
|
|
1645
|
-
|
|
1646
|
-
const count = this.
|
|
1645
|
+
GetFilterSummary() {
|
|
1646
|
+
const count = this.GetFilterCount();
|
|
1647
1647
|
if (count === 0) {
|
|
1648
1648
|
return 'No filters applied';
|
|
1649
1649
|
}
|
|
@@ -1652,8 +1652,8 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1652
1652
|
/**
|
|
1653
1653
|
* Clear all filters
|
|
1654
1654
|
*/
|
|
1655
|
-
|
|
1656
|
-
this.
|
|
1655
|
+
ClearFilters() {
|
|
1656
|
+
this.FilterState = createEmptyFilter();
|
|
1657
1657
|
this.cdr.detectChanges();
|
|
1658
1658
|
}
|
|
1659
1659
|
/**
|
|
@@ -1661,10 +1661,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1661
1661
|
*/
|
|
1662
1662
|
applyGridStateToColumns(gridColumns) {
|
|
1663
1663
|
// Mark all columns as hidden initially
|
|
1664
|
-
this.
|
|
1664
|
+
this.Columns.forEach(c => c.visible = false);
|
|
1665
1665
|
// Apply grid state column settings
|
|
1666
1666
|
gridColumns.forEach((gc, idx) => {
|
|
1667
|
-
const column = this.
|
|
1667
|
+
const column = this.Columns.find(c => c.fieldName.toLowerCase() === gc.Name.toLowerCase());
|
|
1668
1668
|
if (column) {
|
|
1669
1669
|
column.visible = !gc.hidden;
|
|
1670
1670
|
column.width = gc.width || null;
|
|
@@ -1683,94 +1683,94 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1683
1683
|
}
|
|
1684
1684
|
});
|
|
1685
1685
|
// Sort by orderIndex
|
|
1686
|
-
this.
|
|
1686
|
+
this.Columns.sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1687
1687
|
}
|
|
1688
1688
|
/**
|
|
1689
1689
|
* Get visible columns
|
|
1690
1690
|
*/
|
|
1691
|
-
get
|
|
1692
|
-
return this.
|
|
1691
|
+
get VisibleColumns() {
|
|
1692
|
+
return this.Columns.filter(c => c.visible);
|
|
1693
1693
|
}
|
|
1694
1694
|
/**
|
|
1695
1695
|
* Get hidden columns
|
|
1696
1696
|
*/
|
|
1697
|
-
get
|
|
1698
|
-
return this.
|
|
1697
|
+
get HiddenColumns() {
|
|
1698
|
+
return this.Columns.filter(c => !c.visible);
|
|
1699
1699
|
}
|
|
1700
1700
|
/**
|
|
1701
1701
|
* Get filtered columns for search
|
|
1702
1702
|
*/
|
|
1703
|
-
get
|
|
1704
|
-
if (!this.
|
|
1705
|
-
return this.
|
|
1703
|
+
get FilteredHiddenColumns() {
|
|
1704
|
+
if (!this.ColumnSearchText) {
|
|
1705
|
+
return this.HiddenColumns;
|
|
1706
1706
|
}
|
|
1707
|
-
const search = this.
|
|
1708
|
-
return this.
|
|
1707
|
+
const search = this.ColumnSearchText.toLowerCase();
|
|
1708
|
+
return this.HiddenColumns.filter(c => c.displayName.toLowerCase().includes(search) ||
|
|
1709
1709
|
c.fieldName.toLowerCase().includes(search));
|
|
1710
1710
|
}
|
|
1711
1711
|
/**
|
|
1712
1712
|
* Get sortable fields for dropdown (including __mj_ fields for sorting by timestamps)
|
|
1713
1713
|
*/
|
|
1714
|
-
get
|
|
1715
|
-
if (!this.
|
|
1714
|
+
get SortableFields() {
|
|
1715
|
+
if (!this.Entity)
|
|
1716
1716
|
return [];
|
|
1717
|
-
return this.
|
|
1717
|
+
return this.Entity.Fields.filter(f => !f.IsBinaryFieldType // Exclude binary fields from sorting
|
|
1718
1718
|
);
|
|
1719
1719
|
}
|
|
1720
1720
|
/**
|
|
1721
1721
|
* Check if the current user can edit the view
|
|
1722
1722
|
*/
|
|
1723
|
-
get
|
|
1724
|
-
if (!this.
|
|
1723
|
+
get CanEdit() {
|
|
1724
|
+
if (!this.ViewEntity)
|
|
1725
1725
|
return true; // Can always create new
|
|
1726
|
-
return this.
|
|
1726
|
+
return this.ViewEntity.UserCanEdit;
|
|
1727
1727
|
}
|
|
1728
1728
|
/**
|
|
1729
1729
|
* Check if the current user can delete the view
|
|
1730
1730
|
*/
|
|
1731
|
-
get
|
|
1732
|
-
if (!this.
|
|
1731
|
+
get CanDelete() {
|
|
1732
|
+
if (!this.ViewEntity)
|
|
1733
1733
|
return false; // Can't delete default
|
|
1734
|
-
return this.
|
|
1734
|
+
return this.ViewEntity.UserCanDelete;
|
|
1735
1735
|
}
|
|
1736
1736
|
/**
|
|
1737
1737
|
* Toggle column visibility
|
|
1738
1738
|
*/
|
|
1739
|
-
|
|
1739
|
+
ToggleColumnVisibility(column) {
|
|
1740
1740
|
column.visible = !column.visible;
|
|
1741
1741
|
if (column.visible) {
|
|
1742
1742
|
// Add to end of visible columns
|
|
1743
|
-
column.orderIndex = this.
|
|
1743
|
+
column.orderIndex = this.VisibleColumns.length;
|
|
1744
1744
|
}
|
|
1745
1745
|
this.cdr.detectChanges();
|
|
1746
1746
|
}
|
|
1747
1747
|
/**
|
|
1748
1748
|
* Move column up in order
|
|
1749
1749
|
*/
|
|
1750
|
-
|
|
1751
|
-
const visibleCols = this.
|
|
1750
|
+
MoveColumnUp(column) {
|
|
1751
|
+
const visibleCols = this.VisibleColumns;
|
|
1752
1752
|
const currentIndex = visibleCols.indexOf(column);
|
|
1753
1753
|
if (currentIndex > 0) {
|
|
1754
1754
|
const prevColumn = visibleCols[currentIndex - 1];
|
|
1755
1755
|
const tempOrder = column.orderIndex;
|
|
1756
1756
|
column.orderIndex = prevColumn.orderIndex;
|
|
1757
1757
|
prevColumn.orderIndex = tempOrder;
|
|
1758
|
-
this.
|
|
1758
|
+
this.Columns.sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1759
1759
|
this.cdr.detectChanges();
|
|
1760
1760
|
}
|
|
1761
1761
|
}
|
|
1762
1762
|
/**
|
|
1763
1763
|
* Move column down in order
|
|
1764
1764
|
*/
|
|
1765
|
-
|
|
1766
|
-
const visibleCols = this.
|
|
1765
|
+
MoveColumnDown(column) {
|
|
1766
|
+
const visibleCols = this.VisibleColumns;
|
|
1767
1767
|
const currentIndex = visibleCols.indexOf(column);
|
|
1768
1768
|
if (currentIndex < visibleCols.length - 1) {
|
|
1769
1769
|
const nextColumn = visibleCols[currentIndex + 1];
|
|
1770
1770
|
const tempOrder = column.orderIndex;
|
|
1771
1771
|
column.orderIndex = nextColumn.orderIndex;
|
|
1772
1772
|
nextColumn.orderIndex = tempOrder;
|
|
1773
|
-
this.
|
|
1773
|
+
this.Columns.sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1774
1774
|
this.cdr.detectChanges();
|
|
1775
1775
|
}
|
|
1776
1776
|
}
|
|
@@ -1780,8 +1780,8 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1780
1780
|
/**
|
|
1781
1781
|
* Handle drag start for column reordering
|
|
1782
1782
|
*/
|
|
1783
|
-
|
|
1784
|
-
this.
|
|
1783
|
+
OnDragStart(event, column) {
|
|
1784
|
+
this.DraggedColumn = column;
|
|
1785
1785
|
if (event.dataTransfer) {
|
|
1786
1786
|
event.dataTransfer.effectAllowed = 'move';
|
|
1787
1787
|
event.dataTransfer.setData('text/plain', column.fieldId);
|
|
@@ -1792,46 +1792,46 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1792
1792
|
/**
|
|
1793
1793
|
* Handle drag over for column reordering - determines drop position
|
|
1794
1794
|
*/
|
|
1795
|
-
|
|
1795
|
+
OnDragOver(event, column) {
|
|
1796
1796
|
event.preventDefault();
|
|
1797
1797
|
if (event.dataTransfer) {
|
|
1798
1798
|
event.dataTransfer.dropEffect = 'move';
|
|
1799
1799
|
}
|
|
1800
|
-
if (!this.
|
|
1801
|
-
this.
|
|
1802
|
-
this.
|
|
1800
|
+
if (!this.DraggedColumn || this.DraggedColumn === column) {
|
|
1801
|
+
this.DropTargetColumn = null;
|
|
1802
|
+
this.DropPosition = null;
|
|
1803
1803
|
return;
|
|
1804
1804
|
}
|
|
1805
1805
|
// Calculate if we're in the top or bottom half of the target
|
|
1806
1806
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
1807
1807
|
const y = event.clientY - rect.top;
|
|
1808
1808
|
const threshold = rect.height / 2;
|
|
1809
|
-
this.
|
|
1810
|
-
this.
|
|
1809
|
+
this.DropTargetColumn = column;
|
|
1810
|
+
this.DropPosition = y < threshold ? 'before' : 'after';
|
|
1811
1811
|
}
|
|
1812
1812
|
/**
|
|
1813
1813
|
* Handle drag leave - clear drop indicator
|
|
1814
1814
|
*/
|
|
1815
|
-
|
|
1815
|
+
OnDragLeave(event) {
|
|
1816
1816
|
// Only clear if we're leaving the column item, not entering a child element
|
|
1817
1817
|
const relatedTarget = event.relatedTarget;
|
|
1818
1818
|
const currentTarget = event.currentTarget;
|
|
1819
1819
|
if (!currentTarget.contains(relatedTarget)) {
|
|
1820
|
-
this.
|
|
1821
|
-
this.
|
|
1820
|
+
this.DropTargetColumn = null;
|
|
1821
|
+
this.DropPosition = null;
|
|
1822
1822
|
}
|
|
1823
1823
|
}
|
|
1824
1824
|
/**
|
|
1825
1825
|
* Handle drop for column reordering
|
|
1826
1826
|
*/
|
|
1827
|
-
|
|
1827
|
+
OnDrop(event, targetColumn) {
|
|
1828
1828
|
event.preventDefault();
|
|
1829
|
-
if (this.
|
|
1830
|
-
const visibleCols = this.
|
|
1831
|
-
const draggedIndex = visibleCols.indexOf(this.
|
|
1829
|
+
if (this.DraggedColumn && this.DraggedColumn !== targetColumn && this.DropPosition) {
|
|
1830
|
+
const visibleCols = this.VisibleColumns;
|
|
1831
|
+
const draggedIndex = visibleCols.indexOf(this.DraggedColumn);
|
|
1832
1832
|
let targetIndex = visibleCols.indexOf(targetColumn);
|
|
1833
1833
|
// Adjust target index based on drop position
|
|
1834
|
-
if (this.
|
|
1834
|
+
if (this.DropPosition === 'after') {
|
|
1835
1835
|
targetIndex++;
|
|
1836
1836
|
}
|
|
1837
1837
|
// If dragging from before target, adjust for removal
|
|
@@ -1839,14 +1839,14 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1839
1839
|
targetIndex--;
|
|
1840
1840
|
}
|
|
1841
1841
|
// Reorder the columns
|
|
1842
|
-
this.reorderColumn(this.
|
|
1842
|
+
this.reorderColumn(this.DraggedColumn, targetIndex);
|
|
1843
1843
|
}
|
|
1844
1844
|
this.clearDragState();
|
|
1845
1845
|
}
|
|
1846
1846
|
/**
|
|
1847
1847
|
* Handle drag end
|
|
1848
1848
|
*/
|
|
1849
|
-
|
|
1849
|
+
OnDragEnd(event) {
|
|
1850
1850
|
event.target.classList.remove('dragging');
|
|
1851
1851
|
this.clearDragState();
|
|
1852
1852
|
}
|
|
@@ -1854,16 +1854,16 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1854
1854
|
* Clear all drag state
|
|
1855
1855
|
*/
|
|
1856
1856
|
clearDragState() {
|
|
1857
|
-
this.
|
|
1858
|
-
this.
|
|
1859
|
-
this.
|
|
1857
|
+
this.DraggedColumn = null;
|
|
1858
|
+
this.DropTargetColumn = null;
|
|
1859
|
+
this.DropPosition = null;
|
|
1860
1860
|
this.cdr.detectChanges();
|
|
1861
1861
|
}
|
|
1862
1862
|
/**
|
|
1863
1863
|
* Reorder a column to a new position
|
|
1864
1864
|
*/
|
|
1865
1865
|
reorderColumn(column, newIndex) {
|
|
1866
|
-
const visibleCols = this.
|
|
1866
|
+
const visibleCols = this.VisibleColumns;
|
|
1867
1867
|
// Remove from current position
|
|
1868
1868
|
const currentIndex = visibleCols.indexOf(column);
|
|
1869
1869
|
if (currentIndex === newIndex)
|
|
@@ -1887,20 +1887,20 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1887
1887
|
}
|
|
1888
1888
|
});
|
|
1889
1889
|
// Re-sort all columns by orderIndex
|
|
1890
|
-
this.
|
|
1890
|
+
this.Columns.sort((a, b) => a.orderIndex - b.orderIndex);
|
|
1891
1891
|
this.cdr.detectChanges();
|
|
1892
1892
|
}
|
|
1893
1893
|
/**
|
|
1894
1894
|
* Check if drop indicator should show before a column
|
|
1895
1895
|
*/
|
|
1896
|
-
|
|
1897
|
-
return this.
|
|
1896
|
+
IsDropBefore(column) {
|
|
1897
|
+
return this.DropTargetColumn === column && this.DropPosition === 'before';
|
|
1898
1898
|
}
|
|
1899
1899
|
/**
|
|
1900
1900
|
* Check if drop indicator should show after a column
|
|
1901
1901
|
*/
|
|
1902
|
-
|
|
1903
|
-
return this.
|
|
1902
|
+
IsDropAfter(column) {
|
|
1903
|
+
return this.DropTargetColumn === column && this.DropPosition === 'after';
|
|
1904
1904
|
}
|
|
1905
1905
|
// ========================================
|
|
1906
1906
|
// MULTI-SORT MANAGEMENT
|
|
@@ -1908,12 +1908,12 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1908
1908
|
/**
|
|
1909
1909
|
* Add a new sort level
|
|
1910
1910
|
*/
|
|
1911
|
-
|
|
1911
|
+
AddSortLevel() {
|
|
1912
1912
|
// Find the first sortable field not already in use
|
|
1913
|
-
const usedFields = new Set(this.
|
|
1914
|
-
const availableField = this.
|
|
1913
|
+
const usedFields = new Set(this.SortItems.map(s => s.field));
|
|
1914
|
+
const availableField = this.SortableFields.find(f => !usedFields.has(f.Name));
|
|
1915
1915
|
if (availableField) {
|
|
1916
|
-
this.
|
|
1916
|
+
this.SortItems.push({
|
|
1917
1917
|
field: availableField.Name,
|
|
1918
1918
|
direction: 'asc'
|
|
1919
1919
|
});
|
|
@@ -1924,10 +1924,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1924
1924
|
/**
|
|
1925
1925
|
* Remove a sort level
|
|
1926
1926
|
*/
|
|
1927
|
-
|
|
1928
|
-
const index = this.
|
|
1927
|
+
RemoveSortLevel(sortItem) {
|
|
1928
|
+
const index = this.SortItems.indexOf(sortItem);
|
|
1929
1929
|
if (index > -1) {
|
|
1930
|
-
this.
|
|
1930
|
+
this.SortItems.splice(index, 1);
|
|
1931
1931
|
this.syncLegacySortFields();
|
|
1932
1932
|
this.cdr.detectChanges();
|
|
1933
1933
|
}
|
|
@@ -1935,21 +1935,21 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1935
1935
|
/**
|
|
1936
1936
|
* Get the display name for a field
|
|
1937
1937
|
*/
|
|
1938
|
-
|
|
1939
|
-
const field = this.
|
|
1938
|
+
GetFieldDisplayName(fieldName) {
|
|
1939
|
+
const field = this.SortableFields.find(f => f.Name === fieldName);
|
|
1940
1940
|
return field?.DisplayNameOrName || fieldName;
|
|
1941
1941
|
}
|
|
1942
1942
|
/**
|
|
1943
1943
|
* Get fields available for a sort item (excludes already selected fields except current)
|
|
1944
1944
|
*/
|
|
1945
|
-
|
|
1946
|
-
const usedFields = new Set(this.
|
|
1947
|
-
return this.
|
|
1945
|
+
GetAvailableFieldsForSort(currentSortItem) {
|
|
1946
|
+
const usedFields = new Set(this.SortItems.map(s => s.field));
|
|
1947
|
+
return this.SortableFields.filter(f => f.Name === currentSortItem.field || !usedFields.has(f.Name));
|
|
1948
1948
|
}
|
|
1949
1949
|
/**
|
|
1950
1950
|
* Handle sort field change
|
|
1951
1951
|
*/
|
|
1952
|
-
|
|
1952
|
+
OnSortFieldChange(sortItem, fieldName) {
|
|
1953
1953
|
sortItem.field = fieldName;
|
|
1954
1954
|
this.syncLegacySortFields();
|
|
1955
1955
|
this.cdr.detectChanges();
|
|
@@ -1957,7 +1957,7 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1957
1957
|
/**
|
|
1958
1958
|
* Handle sort direction change
|
|
1959
1959
|
*/
|
|
1960
|
-
|
|
1960
|
+
OnSortDirectionChange(sortItem, direction) {
|
|
1961
1961
|
sortItem.direction = direction;
|
|
1962
1962
|
this.syncLegacySortFields();
|
|
1963
1963
|
this.cdr.detectChanges();
|
|
@@ -1966,13 +1966,13 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1966
1966
|
* Keep legacy sortField/sortDirection in sync with sortItems[0]
|
|
1967
1967
|
*/
|
|
1968
1968
|
syncLegacySortFields() {
|
|
1969
|
-
if (this.
|
|
1970
|
-
this.
|
|
1971
|
-
this.
|
|
1969
|
+
if (this.SortItems.length > 0) {
|
|
1970
|
+
this.SortField = this.SortItems[0].field;
|
|
1971
|
+
this.SortDirection = this.SortItems[0].direction;
|
|
1972
1972
|
}
|
|
1973
1973
|
else {
|
|
1974
|
-
this.
|
|
1975
|
-
this.
|
|
1974
|
+
this.SortField = null;
|
|
1975
|
+
this.SortDirection = 'asc';
|
|
1976
1976
|
}
|
|
1977
1977
|
}
|
|
1978
1978
|
// ----------------------------------------
|
|
@@ -1981,8 +1981,8 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1981
1981
|
/**
|
|
1982
1982
|
* Handle drag start for sort item reordering
|
|
1983
1983
|
*/
|
|
1984
|
-
|
|
1985
|
-
this.
|
|
1984
|
+
OnSortDragStart(event, sortItem) {
|
|
1985
|
+
this.DraggedSortItem = sortItem;
|
|
1986
1986
|
if (event.dataTransfer) {
|
|
1987
1987
|
event.dataTransfer.effectAllowed = 'move';
|
|
1988
1988
|
event.dataTransfer.setData('text/plain', sortItem.field);
|
|
@@ -1992,43 +1992,43 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
1992
1992
|
/**
|
|
1993
1993
|
* Handle drag over for sort item reordering
|
|
1994
1994
|
*/
|
|
1995
|
-
|
|
1995
|
+
OnSortDragOver(event, sortItem) {
|
|
1996
1996
|
event.preventDefault();
|
|
1997
1997
|
if (event.dataTransfer) {
|
|
1998
1998
|
event.dataTransfer.dropEffect = 'move';
|
|
1999
1999
|
}
|
|
2000
|
-
if (!this.
|
|
2001
|
-
this.
|
|
2002
|
-
this.
|
|
2000
|
+
if (!this.DraggedSortItem || this.DraggedSortItem === sortItem) {
|
|
2001
|
+
this.DropTargetSortItem = null;
|
|
2002
|
+
this.SortDropPosition = null;
|
|
2003
2003
|
return;
|
|
2004
2004
|
}
|
|
2005
2005
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
2006
2006
|
const y = event.clientY - rect.top;
|
|
2007
2007
|
const threshold = rect.height / 2;
|
|
2008
|
-
this.
|
|
2009
|
-
this.
|
|
2008
|
+
this.DropTargetSortItem = sortItem;
|
|
2009
|
+
this.SortDropPosition = y < threshold ? 'before' : 'after';
|
|
2010
2010
|
}
|
|
2011
2011
|
/**
|
|
2012
2012
|
* Handle drag leave for sort item
|
|
2013
2013
|
*/
|
|
2014
|
-
|
|
2014
|
+
OnSortDragLeave(event) {
|
|
2015
2015
|
const relatedTarget = event.relatedTarget;
|
|
2016
2016
|
const currentTarget = event.currentTarget;
|
|
2017
2017
|
if (!currentTarget.contains(relatedTarget)) {
|
|
2018
|
-
this.
|
|
2019
|
-
this.
|
|
2018
|
+
this.DropTargetSortItem = null;
|
|
2019
|
+
this.SortDropPosition = null;
|
|
2020
2020
|
}
|
|
2021
2021
|
}
|
|
2022
2022
|
/**
|
|
2023
2023
|
* Handle drop for sort item reordering
|
|
2024
2024
|
*/
|
|
2025
|
-
|
|
2025
|
+
OnSortDrop(event, targetSortItem) {
|
|
2026
2026
|
event.preventDefault();
|
|
2027
|
-
if (this.
|
|
2028
|
-
const draggedIndex = this.
|
|
2029
|
-
let targetIndex = this.
|
|
2027
|
+
if (this.DraggedSortItem && this.DraggedSortItem !== targetSortItem && this.SortDropPosition) {
|
|
2028
|
+
const draggedIndex = this.SortItems.indexOf(this.DraggedSortItem);
|
|
2029
|
+
let targetIndex = this.SortItems.indexOf(targetSortItem);
|
|
2030
2030
|
// Adjust target index based on drop position
|
|
2031
|
-
if (this.
|
|
2031
|
+
if (this.SortDropPosition === 'after') {
|
|
2032
2032
|
targetIndex++;
|
|
2033
2033
|
}
|
|
2034
2034
|
// If dragging from before target, adjust for removal
|
|
@@ -2036,9 +2036,9 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2036
2036
|
targetIndex--;
|
|
2037
2037
|
}
|
|
2038
2038
|
// Remove from old position
|
|
2039
|
-
this.
|
|
2039
|
+
this.SortItems.splice(draggedIndex, 1);
|
|
2040
2040
|
// Insert at new position
|
|
2041
|
-
this.
|
|
2041
|
+
this.SortItems.splice(targetIndex, 0, this.DraggedSortItem);
|
|
2042
2042
|
this.syncLegacySortFields();
|
|
2043
2043
|
}
|
|
2044
2044
|
this.clearSortDragState();
|
|
@@ -2046,7 +2046,7 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2046
2046
|
/**
|
|
2047
2047
|
* Handle drag end for sort item
|
|
2048
2048
|
*/
|
|
2049
|
-
|
|
2049
|
+
OnSortDragEnd(event) {
|
|
2050
2050
|
event.target.classList.remove('dragging');
|
|
2051
2051
|
this.clearSortDragState();
|
|
2052
2052
|
}
|
|
@@ -2054,22 +2054,22 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2054
2054
|
* Clear sort drag state
|
|
2055
2055
|
*/
|
|
2056
2056
|
clearSortDragState() {
|
|
2057
|
-
this.
|
|
2058
|
-
this.
|
|
2059
|
-
this.
|
|
2057
|
+
this.DraggedSortItem = null;
|
|
2058
|
+
this.DropTargetSortItem = null;
|
|
2059
|
+
this.SortDropPosition = null;
|
|
2060
2060
|
this.cdr.detectChanges();
|
|
2061
2061
|
}
|
|
2062
2062
|
/**
|
|
2063
2063
|
* Check if drop indicator should show before a sort item
|
|
2064
2064
|
*/
|
|
2065
|
-
|
|
2066
|
-
return this.
|
|
2065
|
+
IsSortDropBefore(sortItem) {
|
|
2066
|
+
return this.DropTargetSortItem === sortItem && this.SortDropPosition === 'before';
|
|
2067
2067
|
}
|
|
2068
2068
|
/**
|
|
2069
2069
|
* Check if drop indicator should show after a sort item
|
|
2070
2070
|
*/
|
|
2071
|
-
|
|
2072
|
-
return this.
|
|
2071
|
+
IsSortDropAfter(sortItem) {
|
|
2072
|
+
return this.DropTargetSortItem === sortItem && this.SortDropPosition === 'after';
|
|
2073
2073
|
}
|
|
2074
2074
|
// ========================================
|
|
2075
2075
|
// COLUMN FORMAT EDITOR
|
|
@@ -2077,19 +2077,19 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2077
2077
|
/**
|
|
2078
2078
|
* Open the format editor for a column
|
|
2079
2079
|
*/
|
|
2080
|
-
|
|
2080
|
+
OpenFormatEditor(column) {
|
|
2081
2081
|
// Initialize format if not present
|
|
2082
2082
|
if (!column.format) {
|
|
2083
2083
|
column.format = this.getDefaultFormat(column.field);
|
|
2084
2084
|
}
|
|
2085
|
-
this.
|
|
2085
|
+
this.FormatEditingColumn = column;
|
|
2086
2086
|
this.cdr.detectChanges();
|
|
2087
2087
|
}
|
|
2088
2088
|
/**
|
|
2089
2089
|
* Close the format editor
|
|
2090
2090
|
*/
|
|
2091
|
-
|
|
2092
|
-
this.
|
|
2091
|
+
CloseFormatEditor() {
|
|
2092
|
+
this.FormatEditingColumn = null;
|
|
2093
2093
|
this.cdr.detectChanges();
|
|
2094
2094
|
}
|
|
2095
2095
|
/**
|
|
@@ -2123,24 +2123,24 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2123
2123
|
/**
|
|
2124
2124
|
* Check if a column has custom formatting applied
|
|
2125
2125
|
*/
|
|
2126
|
-
|
|
2126
|
+
HasCustomFormat(column) {
|
|
2127
2127
|
return !!column.format && column.format.type !== 'auto';
|
|
2128
2128
|
}
|
|
2129
2129
|
/**
|
|
2130
2130
|
* Clear formatting for a column
|
|
2131
2131
|
*/
|
|
2132
|
-
|
|
2132
|
+
ClearColumnFormat(column) {
|
|
2133
2133
|
column.format = undefined;
|
|
2134
2134
|
this.cdr.detectChanges();
|
|
2135
2135
|
}
|
|
2136
2136
|
/**
|
|
2137
2137
|
* Get sample values for preview
|
|
2138
2138
|
*/
|
|
2139
|
-
|
|
2140
|
-
if (!this.
|
|
2139
|
+
GetSampleValues(column) {
|
|
2140
|
+
if (!this.SampleData || this.SampleData.length === 0) {
|
|
2141
2141
|
return this.getPlaceholderSamples(column.field);
|
|
2142
2142
|
}
|
|
2143
|
-
return this.
|
|
2143
|
+
return this.SampleData
|
|
2144
2144
|
.slice(0, 5)
|
|
2145
2145
|
.map(row => row[column.fieldName])
|
|
2146
2146
|
.filter(v => v != null);
|
|
@@ -2174,7 +2174,7 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2174
2174
|
/**
|
|
2175
2175
|
* Format a value for preview display
|
|
2176
2176
|
*/
|
|
2177
|
-
|
|
2177
|
+
FormatPreviewValue(value, format) {
|
|
2178
2178
|
if (value == null)
|
|
2179
2179
|
return '—';
|
|
2180
2180
|
if (!format || format.type === 'auto')
|
|
@@ -2268,14 +2268,14 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2268
2268
|
/**
|
|
2269
2269
|
* Close the panel
|
|
2270
2270
|
*/
|
|
2271
|
-
|
|
2272
|
-
this.
|
|
2271
|
+
OnClose() {
|
|
2272
|
+
this.Close.emit();
|
|
2273
2273
|
}
|
|
2274
2274
|
/**
|
|
2275
2275
|
* Check if filter state has any active filters
|
|
2276
2276
|
*/
|
|
2277
2277
|
hasActiveFilters() {
|
|
2278
|
-
return this.
|
|
2278
|
+
return this.FilterState?.filters?.length > 0;
|
|
2279
2279
|
}
|
|
2280
2280
|
// ========================================
|
|
2281
2281
|
// VALIDATION (BUG-004)
|
|
@@ -2285,10 +2285,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2285
2285
|
*/
|
|
2286
2286
|
get ValidationErrors() {
|
|
2287
2287
|
const errors = [];
|
|
2288
|
-
if (!this.
|
|
2288
|
+
if (!this.ViewName || !this.ViewName.trim()) {
|
|
2289
2289
|
errors.push('View name is required');
|
|
2290
2290
|
}
|
|
2291
|
-
if (this.
|
|
2291
|
+
if (this.VisibleColumns.length === 0) {
|
|
2292
2292
|
errors.push('At least one column must be visible');
|
|
2293
2293
|
}
|
|
2294
2294
|
return errors;
|
|
@@ -2303,147 +2303,147 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2303
2303
|
* Whether the form is valid for save-as-new (name can default to 'New View')
|
|
2304
2304
|
*/
|
|
2305
2305
|
get IsValidForSaveAsNew() {
|
|
2306
|
-
return this.
|
|
2306
|
+
return this.VisibleColumns.length > 0;
|
|
2307
2307
|
}
|
|
2308
2308
|
/**
|
|
2309
2309
|
* Build a ViewConfigSummary for quick-save preview (F-003)
|
|
2310
2310
|
*/
|
|
2311
2311
|
BuildSummary() {
|
|
2312
2312
|
return {
|
|
2313
|
-
ColumnCount: this.
|
|
2314
|
-
FilterCount: this.
|
|
2315
|
-
SortCount: this.
|
|
2316
|
-
SmartFilterActive: this.
|
|
2317
|
-
SmartFilterPrompt: this.
|
|
2318
|
-
AggregateCount: this.
|
|
2313
|
+
ColumnCount: this.VisibleColumns.length,
|
|
2314
|
+
FilterCount: this.FilterMode === 'traditional' ? this.GetFilterCount() : 0,
|
|
2315
|
+
SortCount: this.SortItems.length,
|
|
2316
|
+
SmartFilterActive: this.SmartFilterEnabled && !!this.SmartFilterPrompt.trim(),
|
|
2317
|
+
SmartFilterPrompt: this.SmartFilterPrompt,
|
|
2318
|
+
AggregateCount: this.Aggregates.filter(a => a.enabled !== false).length
|
|
2319
2319
|
};
|
|
2320
2320
|
}
|
|
2321
2321
|
/**
|
|
2322
2322
|
* Save the view
|
|
2323
2323
|
*/
|
|
2324
|
-
|
|
2324
|
+
OnSave() {
|
|
2325
2325
|
// BUG-003: Guard against double-clicks with local flag
|
|
2326
|
-
if (this.
|
|
2326
|
+
if (this.IsSaving || this._localSaving)
|
|
2327
2327
|
return;
|
|
2328
2328
|
// BUG-004: Validate before saving
|
|
2329
2329
|
if (!this.IsValid)
|
|
2330
2330
|
return;
|
|
2331
2331
|
this._localSaving = true;
|
|
2332
|
-
this.
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2332
|
+
this.Save.emit({
|
|
2333
|
+
Name: this.ViewName,
|
|
2334
|
+
Description: this.ViewDescription,
|
|
2335
|
+
IsShared: this.IsShared,
|
|
2336
|
+
SaveAsNew: false,
|
|
2337
|
+
Columns: this.VisibleColumns,
|
|
2338
|
+
SortField: this.SortField,
|
|
2339
|
+
SortDirection: this.SortDirection,
|
|
2340
|
+
SortItems: [...this.SortItems],
|
|
2341
|
+
SmartFilterEnabled: this.SmartFilterEnabled,
|
|
2342
|
+
SmartFilterPrompt: this.SmartFilterPrompt,
|
|
2343
|
+
FilterState: this.hasActiveFilters() ? this.FilterState : null,
|
|
2344
|
+
AggregatesConfig: this.buildAggregatesConfig()
|
|
2345
2345
|
});
|
|
2346
2346
|
}
|
|
2347
2347
|
/**
|
|
2348
2348
|
* Save as a new view
|
|
2349
2349
|
*/
|
|
2350
|
-
|
|
2350
|
+
OnSaveAsNew() {
|
|
2351
2351
|
// BUG-003: Guard against double-clicks with local flag
|
|
2352
|
-
if (this.
|
|
2352
|
+
if (this.IsSaving || this._localSaving)
|
|
2353
2353
|
return;
|
|
2354
2354
|
// BUG-004: Validate (name defaults to 'New View' if empty)
|
|
2355
2355
|
if (!this.IsValidForSaveAsNew)
|
|
2356
2356
|
return;
|
|
2357
2357
|
this._localSaving = true;
|
|
2358
|
-
this.
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2358
|
+
this.Save.emit({
|
|
2359
|
+
Name: this.ViewName || 'New View',
|
|
2360
|
+
Description: this.ViewDescription,
|
|
2361
|
+
IsShared: this.IsShared,
|
|
2362
|
+
SaveAsNew: true,
|
|
2363
|
+
Columns: this.VisibleColumns,
|
|
2364
|
+
SortField: this.SortField,
|
|
2365
|
+
SortDirection: this.SortDirection,
|
|
2366
|
+
SortItems: [...this.SortItems],
|
|
2367
|
+
SmartFilterEnabled: this.SmartFilterEnabled,
|
|
2368
|
+
SmartFilterPrompt: this.SmartFilterPrompt,
|
|
2369
|
+
FilterState: this.hasActiveFilters() ? this.FilterState : null,
|
|
2370
|
+
AggregatesConfig: this.buildAggregatesConfig()
|
|
2371
2371
|
});
|
|
2372
2372
|
}
|
|
2373
2373
|
/**
|
|
2374
2374
|
* Save default view settings to user settings
|
|
2375
2375
|
* Used for dynamic/default views that don't have a stored view entity
|
|
2376
2376
|
*/
|
|
2377
|
-
|
|
2377
|
+
OnSaveDefaults() {
|
|
2378
2378
|
// BUG-003: Guard against double-clicks with local flag
|
|
2379
|
-
if (this.
|
|
2379
|
+
if (this.IsSaving || this._localSaving)
|
|
2380
2380
|
return;
|
|
2381
2381
|
this._localSaving = true;
|
|
2382
|
-
this.
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2382
|
+
this.SaveDefaults.emit({
|
|
2383
|
+
Name: 'Default',
|
|
2384
|
+
Description: '',
|
|
2385
|
+
IsShared: false,
|
|
2386
|
+
SaveAsNew: false,
|
|
2387
|
+
Columns: this.VisibleColumns,
|
|
2388
|
+
SortField: this.SortField,
|
|
2389
|
+
SortDirection: this.SortDirection,
|
|
2390
|
+
SortItems: [...this.SortItems],
|
|
2391
|
+
SmartFilterEnabled: this.SmartFilterEnabled,
|
|
2392
|
+
SmartFilterPrompt: this.SmartFilterPrompt,
|
|
2393
|
+
FilterState: this.hasActiveFilters() ? this.FilterState : null,
|
|
2394
|
+
AggregatesConfig: this.buildAggregatesConfig()
|
|
2395
2395
|
});
|
|
2396
2396
|
}
|
|
2397
2397
|
// Delete confirmation state
|
|
2398
|
-
|
|
2398
|
+
ShowDeleteConfirm = false;
|
|
2399
2399
|
/**
|
|
2400
2400
|
* Delete the view - shows confirmation dialog
|
|
2401
2401
|
*/
|
|
2402
|
-
|
|
2403
|
-
this.
|
|
2402
|
+
OnDelete() {
|
|
2403
|
+
this.ShowDeleteConfirm = true;
|
|
2404
2404
|
this.cdr.detectChanges();
|
|
2405
2405
|
}
|
|
2406
2406
|
/**
|
|
2407
2407
|
* Confirmed delete from dialog
|
|
2408
2408
|
*/
|
|
2409
2409
|
OnDeleteConfirmed() {
|
|
2410
|
-
this.
|
|
2411
|
-
this.
|
|
2410
|
+
this.ShowDeleteConfirm = false;
|
|
2411
|
+
this.Delete.emit();
|
|
2412
2412
|
}
|
|
2413
2413
|
/**
|
|
2414
2414
|
* Cancelled delete from dialog
|
|
2415
2415
|
*/
|
|
2416
2416
|
OnDeleteCancelled() {
|
|
2417
|
-
this.
|
|
2417
|
+
this.ShowDeleteConfirm = false;
|
|
2418
2418
|
this.cdr.detectChanges();
|
|
2419
2419
|
}
|
|
2420
2420
|
/**
|
|
2421
2421
|
* Duplicate the current view (F-005)
|
|
2422
2422
|
*/
|
|
2423
2423
|
OnDuplicate() {
|
|
2424
|
-
this.
|
|
2424
|
+
this.Duplicate.emit();
|
|
2425
2425
|
}
|
|
2426
2426
|
/**
|
|
2427
2427
|
* Set the active tab
|
|
2428
2428
|
*/
|
|
2429
|
-
|
|
2430
|
-
this.
|
|
2431
|
-
this.
|
|
2429
|
+
SetActiveTab(tab) {
|
|
2430
|
+
this.ActiveTab = tab;
|
|
2431
|
+
this.FormatEditingColumn = null; // Close format editor when switching tabs
|
|
2432
2432
|
this.cdr.detectChanges();
|
|
2433
2433
|
}
|
|
2434
2434
|
/**
|
|
2435
2435
|
* Set the filter mode (smart or traditional)
|
|
2436
2436
|
* BUG-006: Shows confirmation when switching if active mode has data
|
|
2437
2437
|
*/
|
|
2438
|
-
|
|
2439
|
-
if (this.
|
|
2438
|
+
SetFilterMode(mode) {
|
|
2439
|
+
if (this.FilterMode === mode)
|
|
2440
2440
|
return;
|
|
2441
2441
|
// Check if current mode has data that would be lost
|
|
2442
2442
|
const currentModeHasData = this.currentFilterModeHasData();
|
|
2443
2443
|
if (currentModeHasData) {
|
|
2444
2444
|
// Show confirmation dialog before switching
|
|
2445
|
-
this.
|
|
2446
|
-
this.
|
|
2445
|
+
this.PendingFilterModeSwitch = mode;
|
|
2446
|
+
this.ShowFilterModeSwitchConfirm = true;
|
|
2447
2447
|
this.cdr.detectChanges();
|
|
2448
2448
|
return;
|
|
2449
2449
|
}
|
|
@@ -2453,61 +2453,61 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2453
2453
|
* Check if the current filter mode has user-entered data
|
|
2454
2454
|
*/
|
|
2455
2455
|
currentFilterModeHasData() {
|
|
2456
|
-
if (this.
|
|
2457
|
-
return !!this.
|
|
2456
|
+
if (this.FilterMode === 'smart') {
|
|
2457
|
+
return !!this.SmartFilterPrompt.trim();
|
|
2458
2458
|
}
|
|
2459
2459
|
else {
|
|
2460
|
-
return this.
|
|
2460
|
+
return this.GetFilterCount() > 0;
|
|
2461
2461
|
}
|
|
2462
2462
|
}
|
|
2463
2463
|
/**
|
|
2464
2464
|
* Confirm the filter mode switch (called from ConfirmDialog)
|
|
2465
2465
|
*/
|
|
2466
2466
|
OnFilterModeSwitchConfirmed() {
|
|
2467
|
-
if (this.
|
|
2468
|
-
this.applyFilterModeSwitch(this.
|
|
2467
|
+
if (this.PendingFilterModeSwitch) {
|
|
2468
|
+
this.applyFilterModeSwitch(this.PendingFilterModeSwitch);
|
|
2469
2469
|
}
|
|
2470
|
-
this.
|
|
2471
|
-
this.
|
|
2470
|
+
this.ShowFilterModeSwitchConfirm = false;
|
|
2471
|
+
this.PendingFilterModeSwitch = null;
|
|
2472
2472
|
}
|
|
2473
2473
|
/**
|
|
2474
2474
|
* Cancel the filter mode switch (called from ConfirmDialog)
|
|
2475
2475
|
*/
|
|
2476
2476
|
OnFilterModeSwitchCancelled() {
|
|
2477
|
-
this.
|
|
2478
|
-
this.
|
|
2477
|
+
this.ShowFilterModeSwitchConfirm = false;
|
|
2478
|
+
this.PendingFilterModeSwitch = null;
|
|
2479
2479
|
}
|
|
2480
2480
|
/**
|
|
2481
2481
|
* Apply the filter mode switch - saves current mode data and restores target mode data
|
|
2482
2482
|
*/
|
|
2483
2483
|
applyFilterModeSwitch(mode) {
|
|
2484
2484
|
// Save current mode's data before switching
|
|
2485
|
-
if (this.
|
|
2486
|
-
this.savedSmartFilterPrompt = this.
|
|
2485
|
+
if (this.FilterMode === 'smart') {
|
|
2486
|
+
this.savedSmartFilterPrompt = this.SmartFilterPrompt;
|
|
2487
2487
|
}
|
|
2488
2488
|
else {
|
|
2489
|
-
this.savedTraditionalFilter = this.
|
|
2489
|
+
this.savedTraditionalFilter = this.FilterState;
|
|
2490
2490
|
}
|
|
2491
|
-
this.
|
|
2491
|
+
this.FilterMode = mode;
|
|
2492
2492
|
// Restore target mode's saved data or clear
|
|
2493
2493
|
if (mode === 'smart') {
|
|
2494
|
-
this.
|
|
2495
|
-
this.
|
|
2496
|
-
this.
|
|
2494
|
+
this.SmartFilterEnabled = true;
|
|
2495
|
+
this.SmartFilterPrompt = this.savedSmartFilterPrompt;
|
|
2496
|
+
this.FilterState = createEmptyFilter();
|
|
2497
2497
|
}
|
|
2498
2498
|
else {
|
|
2499
|
-
this.
|
|
2500
|
-
this.
|
|
2501
|
-
this.
|
|
2502
|
-
this.
|
|
2499
|
+
this.SmartFilterEnabled = false;
|
|
2500
|
+
this.SmartFilterPrompt = '';
|
|
2501
|
+
this.SmartFilterExplanation = '';
|
|
2502
|
+
this.FilterState = this.savedTraditionalFilter;
|
|
2503
2503
|
}
|
|
2504
2504
|
this.cdr.detectChanges();
|
|
2505
2505
|
}
|
|
2506
2506
|
/**
|
|
2507
2507
|
* Apply a smart filter example to the prompt field
|
|
2508
2508
|
*/
|
|
2509
|
-
|
|
2510
|
-
this.
|
|
2509
|
+
ApplySmartFilterExample(example) {
|
|
2510
|
+
this.SmartFilterPrompt = example;
|
|
2511
2511
|
this.cdr.detectChanges();
|
|
2512
2512
|
}
|
|
2513
2513
|
// ========================================
|
|
@@ -2516,10 +2516,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2516
2516
|
/**
|
|
2517
2517
|
* Toggle a header style property
|
|
2518
2518
|
*/
|
|
2519
|
-
|
|
2520
|
-
if (!this.
|
|
2519
|
+
ToggleHeaderStyle(prop) {
|
|
2520
|
+
if (!this.FormatEditingColumn?.format)
|
|
2521
2521
|
return;
|
|
2522
|
-
const format = this.
|
|
2522
|
+
const format = this.FormatEditingColumn.format;
|
|
2523
2523
|
if (!format.headerStyle) {
|
|
2524
2524
|
format.headerStyle = {};
|
|
2525
2525
|
}
|
|
@@ -2531,20 +2531,20 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2531
2531
|
/**
|
|
2532
2532
|
* Update the user-defined display name for a column
|
|
2533
2533
|
*/
|
|
2534
|
-
|
|
2535
|
-
if (!this.
|
|
2534
|
+
UpdateUserDisplayName(value) {
|
|
2535
|
+
if (!this.FormatEditingColumn)
|
|
2536
2536
|
return;
|
|
2537
2537
|
// Set to undefined if empty string, otherwise use the value
|
|
2538
|
-
this.
|
|
2538
|
+
this.FormatEditingColumn.userDisplayName = value.trim() || undefined;
|
|
2539
2539
|
this.cdr.detectChanges();
|
|
2540
2540
|
}
|
|
2541
2541
|
/**
|
|
2542
2542
|
* Update a header style color property
|
|
2543
2543
|
*/
|
|
2544
|
-
|
|
2545
|
-
if (!this.
|
|
2544
|
+
UpdateHeaderColor(prop, value) {
|
|
2545
|
+
if (!this.FormatEditingColumn?.format)
|
|
2546
2546
|
return;
|
|
2547
|
-
const format = this.
|
|
2547
|
+
const format = this.FormatEditingColumn.format;
|
|
2548
2548
|
if (!format.headerStyle) {
|
|
2549
2549
|
format.headerStyle = {};
|
|
2550
2550
|
}
|
|
@@ -2554,10 +2554,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2554
2554
|
/**
|
|
2555
2555
|
* Toggle a cell style property
|
|
2556
2556
|
*/
|
|
2557
|
-
|
|
2558
|
-
if (!this.
|
|
2557
|
+
ToggleCellStyle(prop) {
|
|
2558
|
+
if (!this.FormatEditingColumn?.format)
|
|
2559
2559
|
return;
|
|
2560
|
-
const format = this.
|
|
2560
|
+
const format = this.FormatEditingColumn.format;
|
|
2561
2561
|
if (!format.cellStyle) {
|
|
2562
2562
|
format.cellStyle = {};
|
|
2563
2563
|
}
|
|
@@ -2569,10 +2569,10 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2569
2569
|
/**
|
|
2570
2570
|
* Update a cell style color property
|
|
2571
2571
|
*/
|
|
2572
|
-
|
|
2573
|
-
if (!this.
|
|
2572
|
+
UpdateCellColor(prop, value) {
|
|
2573
|
+
if (!this.FormatEditingColumn?.format)
|
|
2574
2574
|
return;
|
|
2575
|
-
const format = this.
|
|
2575
|
+
const format = this.FormatEditingColumn.format;
|
|
2576
2576
|
if (!format.cellStyle) {
|
|
2577
2577
|
format.cellStyle = {};
|
|
2578
2578
|
}
|
|
@@ -2585,59 +2585,59 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2585
2585
|
/**
|
|
2586
2586
|
* Open dialog to add a new aggregate
|
|
2587
2587
|
*/
|
|
2588
|
-
|
|
2589
|
-
this.
|
|
2590
|
-
this.
|
|
2588
|
+
OpenAddAggregateDialog() {
|
|
2589
|
+
this.EditingAggregate = null;
|
|
2590
|
+
this.ShowAggregateDialog = true;
|
|
2591
2591
|
this.cdr.detectChanges();
|
|
2592
2592
|
}
|
|
2593
2593
|
/**
|
|
2594
2594
|
* Open dialog to edit an existing aggregate
|
|
2595
2595
|
*/
|
|
2596
|
-
|
|
2597
|
-
this.
|
|
2598
|
-
this.
|
|
2596
|
+
EditAggregate(aggregate) {
|
|
2597
|
+
this.EditingAggregate = { ...aggregate };
|
|
2598
|
+
this.ShowAggregateDialog = true;
|
|
2599
2599
|
this.cdr.detectChanges();
|
|
2600
2600
|
}
|
|
2601
2601
|
/**
|
|
2602
2602
|
* Close the aggregate dialog
|
|
2603
2603
|
*/
|
|
2604
|
-
|
|
2605
|
-
this.
|
|
2606
|
-
this.
|
|
2604
|
+
CloseAggregateDialog() {
|
|
2605
|
+
this.ShowAggregateDialog = false;
|
|
2606
|
+
this.EditingAggregate = null;
|
|
2607
2607
|
this.cdr.detectChanges();
|
|
2608
2608
|
}
|
|
2609
2609
|
/**
|
|
2610
2610
|
* Handle saving an aggregate from the dialog
|
|
2611
2611
|
*/
|
|
2612
|
-
|
|
2613
|
-
const existingIndex = this.
|
|
2612
|
+
OnAggregateSave(aggregate) {
|
|
2613
|
+
const existingIndex = this.Aggregates.findIndex(a => a.id === aggregate.id);
|
|
2614
2614
|
if (existingIndex >= 0) {
|
|
2615
2615
|
// Update existing
|
|
2616
|
-
this.
|
|
2616
|
+
this.Aggregates[existingIndex] = aggregate;
|
|
2617
2617
|
}
|
|
2618
2618
|
else {
|
|
2619
2619
|
// Add new with order at end
|
|
2620
|
-
aggregate.order = this.
|
|
2621
|
-
this.
|
|
2620
|
+
aggregate.order = this.Aggregates.length;
|
|
2621
|
+
this.Aggregates.push(aggregate);
|
|
2622
2622
|
}
|
|
2623
|
-
this.
|
|
2623
|
+
this.CloseAggregateDialog();
|
|
2624
2624
|
}
|
|
2625
2625
|
/**
|
|
2626
2626
|
* Remove an aggregate
|
|
2627
2627
|
*/
|
|
2628
|
-
|
|
2629
|
-
const index = this.
|
|
2628
|
+
RemoveAggregate(aggregate) {
|
|
2629
|
+
const index = this.Aggregates.findIndex(a => a.id === aggregate.id);
|
|
2630
2630
|
if (index >= 0) {
|
|
2631
|
-
this.
|
|
2631
|
+
this.Aggregates.splice(index, 1);
|
|
2632
2632
|
// Re-order remaining aggregates
|
|
2633
|
-
this.
|
|
2633
|
+
this.Aggregates.forEach((a, i) => a.order = i);
|
|
2634
2634
|
this.cdr.detectChanges();
|
|
2635
2635
|
}
|
|
2636
2636
|
}
|
|
2637
2637
|
/**
|
|
2638
2638
|
* Toggle aggregate enabled state (BUG-012: immutable update, no excessive logging)
|
|
2639
2639
|
*/
|
|
2640
|
-
|
|
2640
|
+
ToggleAggregateEnabled(aggregate, event) {
|
|
2641
2641
|
// Stop event propagation to prevent any parent handlers
|
|
2642
2642
|
if (event) {
|
|
2643
2643
|
event.preventDefault();
|
|
@@ -2646,88 +2646,88 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2646
2646
|
// Find by ID first, fall back to object reference or label
|
|
2647
2647
|
let index = -1;
|
|
2648
2648
|
if (aggregate.id) {
|
|
2649
|
-
index = this.
|
|
2649
|
+
index = this.Aggregates.findIndex(a => a.id === aggregate.id);
|
|
2650
2650
|
}
|
|
2651
2651
|
if (index < 0) {
|
|
2652
|
-
index = this.
|
|
2652
|
+
index = this.Aggregates.indexOf(aggregate);
|
|
2653
2653
|
}
|
|
2654
2654
|
if (index < 0 && aggregate.label) {
|
|
2655
|
-
index = this.
|
|
2655
|
+
index = this.Aggregates.findIndex(a => a.label === aggregate.label && a.expression === aggregate.expression);
|
|
2656
2656
|
}
|
|
2657
2657
|
if (index >= 0) {
|
|
2658
2658
|
const updatedAggregate = {
|
|
2659
|
-
...this.
|
|
2660
|
-
enabled: this.
|
|
2659
|
+
...this.Aggregates[index],
|
|
2660
|
+
enabled: this.Aggregates[index].enabled === false
|
|
2661
2661
|
};
|
|
2662
2662
|
// Replace entire array to trigger change detection
|
|
2663
|
-
const newAggregates = [...this.
|
|
2663
|
+
const newAggregates = [...this.Aggregates];
|
|
2664
2664
|
newAggregates[index] = updatedAggregate;
|
|
2665
|
-
this.
|
|
2665
|
+
this.Aggregates = newAggregates;
|
|
2666
2666
|
this.cdr.detectChanges();
|
|
2667
2667
|
}
|
|
2668
2668
|
}
|
|
2669
2669
|
/**
|
|
2670
2670
|
* Move aggregate up in order
|
|
2671
2671
|
*/
|
|
2672
|
-
|
|
2673
|
-
const index = this.
|
|
2672
|
+
MoveAggregateUp(aggregate) {
|
|
2673
|
+
const index = this.Aggregates.indexOf(aggregate);
|
|
2674
2674
|
if (index > 0) {
|
|
2675
|
-
const prev = this.
|
|
2676
|
-
this.
|
|
2677
|
-
this.
|
|
2678
|
-
this.
|
|
2675
|
+
const prev = this.Aggregates[index - 1];
|
|
2676
|
+
this.Aggregates[index - 1] = aggregate;
|
|
2677
|
+
this.Aggregates[index] = prev;
|
|
2678
|
+
this.Aggregates.forEach((a, i) => a.order = i);
|
|
2679
2679
|
this.cdr.detectChanges();
|
|
2680
2680
|
}
|
|
2681
2681
|
}
|
|
2682
2682
|
/**
|
|
2683
2683
|
* Move aggregate down in order
|
|
2684
2684
|
*/
|
|
2685
|
-
|
|
2686
|
-
const index = this.
|
|
2687
|
-
if (index < this.
|
|
2688
|
-
const next = this.
|
|
2689
|
-
this.
|
|
2690
|
-
this.
|
|
2691
|
-
this.
|
|
2685
|
+
MoveAggregateDown(aggregate) {
|
|
2686
|
+
const index = this.Aggregates.indexOf(aggregate);
|
|
2687
|
+
if (index < this.Aggregates.length - 1) {
|
|
2688
|
+
const next = this.Aggregates[index + 1];
|
|
2689
|
+
this.Aggregates[index + 1] = aggregate;
|
|
2690
|
+
this.Aggregates[index] = next;
|
|
2691
|
+
this.Aggregates.forEach((a, i) => a.order = i);
|
|
2692
2692
|
this.cdr.detectChanges();
|
|
2693
2693
|
}
|
|
2694
2694
|
}
|
|
2695
2695
|
/**
|
|
2696
2696
|
* Get enabled aggregates count
|
|
2697
2697
|
*/
|
|
2698
|
-
get
|
|
2699
|
-
return this.
|
|
2698
|
+
get EnabledAggregatesCount() {
|
|
2699
|
+
return this.Aggregates.filter(a => a.enabled !== false).length;
|
|
2700
2700
|
}
|
|
2701
2701
|
/**
|
|
2702
2702
|
* Get card aggregates
|
|
2703
2703
|
*/
|
|
2704
|
-
get
|
|
2705
|
-
return this.
|
|
2704
|
+
get CardAggregates() {
|
|
2705
|
+
return this.Aggregates.filter(a => a.displayType === 'card');
|
|
2706
2706
|
}
|
|
2707
2707
|
/**
|
|
2708
2708
|
* Get column aggregates
|
|
2709
2709
|
*/
|
|
2710
|
-
get
|
|
2711
|
-
return this.
|
|
2710
|
+
get ColumnAggregates() {
|
|
2711
|
+
return this.Aggregates.filter(a => a.displayType === 'column');
|
|
2712
2712
|
}
|
|
2713
2713
|
/**
|
|
2714
2714
|
* Build aggregates config from current state
|
|
2715
2715
|
*/
|
|
2716
2716
|
buildAggregatesConfig() {
|
|
2717
|
-
if (this.
|
|
2717
|
+
if (this.Aggregates.length === 0)
|
|
2718
2718
|
return null;
|
|
2719
2719
|
return {
|
|
2720
2720
|
display: { ...DEFAULT_AGGREGATE_DISPLAY },
|
|
2721
|
-
expressions: [...this.
|
|
2721
|
+
expressions: [...this.Aggregates]
|
|
2722
2722
|
};
|
|
2723
2723
|
}
|
|
2724
2724
|
static ɵfac = function ViewConfigPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ViewConfigPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
2725
2725
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewConfigPanelComponent, selectors: [["mj-view-config-panel"]], hostBindings: function ViewConfigPanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2726
|
-
i0.ɵɵlistener("keydown.escape", function ViewConfigPanelComponent_keydown_escape_HostBindingHandler() { return ctx.
|
|
2727
|
-
} }, inputs: {
|
|
2726
|
+
i0.ɵɵlistener("keydown.escape", function ViewConfigPanelComponent_keydown_escape_HostBindingHandler() { return ctx.HandleEscape(); }, i0.ɵɵresolveDocument);
|
|
2727
|
+
} }, inputs: { Entity: "Entity", ViewEntity: "ViewEntity", IsOpen: "IsOpen", CurrentGridState: "CurrentGridState", SampleData: "SampleData", ExternalFilterState: "ExternalFilterState", DefaultSaveAsNew: "DefaultSaveAsNew", PendingNewViewName: "PendingNewViewName", PendingNewViewDescription: "PendingNewViewDescription", PendingNewViewIsShared: "PendingNewViewIsShared", IsSaving: "IsSaving" }, outputs: { Close: "Close", Save: "Save", SaveDefaults: "SaveDefaults", Delete: "Delete", OpenFilterDialogRequest: "OpenFilterDialogRequest", Duplicate: "Duplicate" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 45, vars: 46, consts: [[1, "panel-backdrop"], [1, "config-panel"], ["title", "Drag to resize", 1, "resize-handle", 3, "mousedown"], [1, "resize-grip"], [1, "panel-header"], [1, "header-title"], [1, "fa-solid", "fa-sliders-h"], ["title", "Close", "aria-label", "Close panel", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "tab-nav"], [1, "tab-btn", 3, "click", "title"], [1, "fa-solid", "fa-columns"], [1, "fa-solid", "fa-arrow-up-wide-short"], [1, "tab-badge"], [1, "fa-solid", "fa-filter"], [1, "fa-solid", "fa-chart-simple"], [1, "tab-btn", 3, "active", "title"], [1, "panel-content"], [1, "tab-content"], [1, "format-editor"], [1, "validation-banner"], [1, "panel-footer"], [1, "footer-left"], [1, "footer-btn", "save-btn", "primary", 3, "disabled"], [1, "footer-btn", "cancel-btn", 3, "click"], [3, "Close", "Save", "Entity", "Aggregate", "IsOpen"], ["Title", "Delete View", "DetailMessage", "This action cannot be undone. All users who have access to this view will lose it.", "ConfirmText", "Delete", "ConfirmStyle", "danger", "Icon", "fa-solid fa-trash", 3, "Confirmed", "Cancelled", "IsOpen", "Message"], ["Title", "Switch Filter Mode", "DetailMessage", "You can switch back later, but the current filter data will be lost.", "ConfirmText", "Switch", "ConfirmStyle", "primary", "Icon", "fa-solid fa-exchange-alt", 3, "Confirmed", "Cancelled", "IsOpen", "Message"], [1, "panel-backdrop", 3, "click"], [1, "fa-solid", "fa-cog"], [1, "config-section"], [1, "section-header"], [1, "fa-solid", "fa-eye"], [1, "column-count"], [1, "column-list", "visible-columns"], [1, "empty-list"], [1, "fa-solid", "fa-eye-slash"], [1, "column-search"], [1, "column-list", "hidden-columns"], [1, "column-item", "hidden"], [1, "drop-indicator"], ["draggable", "true", 1, "column-item", 3, "dragstart", "dragover", "dragleave", "drop", "dragend"], [1, "drag-handle"], [1, "fa-solid", "fa-grip-vertical"], [1, "column-name"], [1, "fa-solid", "fa-pen-nib", "alias-indicator", 3, "title"], ["title", "Custom formatting applied", 1, "fa-solid", "fa-paintbrush", "format-indicator"], [1, "column-actions"], ["title", "Format column", 1, "action-btn", "format-btn", 3, "click"], [1, "fa-solid", "fa-paintbrush"], ["title", "Move up", 1, "action-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-up"], ["title", "Move down", 1, "action-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-down"], ["title", "Hide column", 1, "action-btn", "hide-btn", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search columns...", 3, "ngModelChange", "ngModel"], ["title", "Show column", 1, "action-btn", "show-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-check-circle"], [1, "format-editor-header"], [1, "back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "format-editor-title"], [1, "format-section"], [1, "format-section-header"], [1, "fa-solid", "fa-pen-nib"], [1, "format-row"], ["type", "text", 1, "format-input", 3, "input", "value", "placeholder"], [1, "format-row", "alias-info"], [1, "format-preview-section"], [1, "preview-header"], [1, "preview-table"], [1, "preview-header-cell"], [1, "preview-cell", 3, "text-align", "font-weight", "font-style", "text-decoration", "color", "background-color"], [1, "fa-solid", "fa-hashtag"], [1, "format-select", 3, "ngModelChange", "ngModel"], ["value", "auto"], ["value", "text"], ["value", "number"], ["value", "currency"], ["value", "percent"], ["value", "date"], ["value", "datetime"], ["value", "boolean"], [1, "fa-solid", "fa-align-left"], [1, "alignment-toggle"], ["title", "Left", 1, "align-btn", 3, "click"], ["title", "Center", 1, "align-btn", 3, "click"], [1, "fa-solid", "fa-align-center"], ["title", "Right", 1, "align-btn", 3, "click"], [1, "fa-solid", "fa-align-right"], [1, "fa-solid", "fa-heading"], [1, "style-buttons"], ["title", "Bold", 1, "style-btn", 3, "click"], [1, "fa-solid", "fa-bold"], ["title", "Italic", 1, "style-btn", 3, "click"], [1, "fa-solid", "fa-italic"], ["title", "Underline", 1, "style-btn", 3, "click"], [1, "fa-solid", "fa-underline"], ["type", "color", 1, "color-input", 3, "input", "value"], [1, "fa-solid", "fa-table-cells"], [1, "format-actions"], [1, "clear-format-btn", 3, "click"], [1, "fa-solid", "fa-eraser"], [1, "muted-text"], ["title", "Clear alias", "aria-label", "Clear alias", 1, "clear-alias-btn", 3, "click"], [1, "preview-cell"], [1, "fa-solid", "fa-sliders"], ["type", "number", "min", "0", "max", "10", 1, "format-input", "small", 3, "ngModelChange", "ngModel"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], ["value", "USD"], ["value", "EUR"], ["value", "GBP"], ["value", "JPY"], ["value", "CAD"], ["value", "AUD"], [1, "fa-solid", "fa-calendar"], ["value", "short"], ["value", "short-weekday"], ["value", "medium"], ["value", "medium-weekday"], ["value", "long"], ["value", "long-weekday"], [1, "fa-solid", "fa-toggle-on"], ["type", "text", "placeholder", "Yes", 1, "format-input", 3, "ngModelChange", "ngModel"], ["type", "text", "placeholder", "No", 1, "format-input", 3, "ngModelChange", "ngModel"], ["value", "checkbox"], ["value", "icon"], [1, "config-section", "sorting-section"], [1, "sorting-header"], [1, "sorting-description"], ["title", "Add another sort level", 1, "add-sort-btn", 3, "click", "disabled"], [1, "sort-empty-state"], [1, "sort-items-list"], [1, "sort-hint"], [1, "sort-drop-indicator"], ["draggable", "true", 1, "sort-item", 3, "dragstart", "dragover", "dragleave", "drop", "dragend"], [1, "sort-priority-badge"], ["title", "Drag to reorder", 1, "sort-drag-handle"], [1, "sort-field-dropdown", 3, "ngModelChange", "ngModel", "disabled"], [3, "value"], [1, "sort-direction-toggle"], ["title", "Ascending (A-Z, 1-9)", 1, "direction-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-up"], ["title", "Descending (Z-A, 9-1)", 1, "direction-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-down"], ["title", "Remove sort level", 1, "sort-remove-btn", 3, "click", "disabled"], [1, "sort-empty-hint"], [1, "filter-mode-selector"], [1, "filter-mode-btn", 3, "click", "disabled"], [1, "mode-icon"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "mode-content"], [1, "mode-title"], [1, "mode-subtitle"], [1, "fa-solid", "fa-check", "mode-check"], [1, "config-section", "smart-filter-section"], [1, "config-section", "traditional-filter-section"], [1, "smart-filter-input-container"], [1, "smart-filter-icon"], ["id", "SmartFilterPrompt", "placeholder", "Describe what you're looking for...", "rows", "3", 1, "smart-filter-textarea", 3, "ngModelChange", "ngModel", "disabled"], [1, "smart-filter-explanation"], [1, "smart-filter-examples"], [1, "examples-header"], [1, "fa-solid", "fa-lightbulb"], [1, "example-chips"], [1, "example-chip", 3, "click", "disabled"], [1, "fa-regular", "fa-calendar"], [1, "fa-solid", "fa-circle-check"], [1, "fa-solid", "fa-star"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "smart-filter-tip"], [1, "fa-solid", "fa-robot"], [1, "filter-summary-container"], [1, "filter-summary"], [1, "summary-info"], [1, "summary-text", "no-filters"], [1, "summary-actions"], ["title", "Clear all filters", 1, "summary-btn", "clear-btn"], ["title", "Edit filters", 1, "summary-btn", "edit-btn", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-pen"], [1, "traditional-filter-tip"], [1, "filter-badge"], [1, "summary-text"], ["title", "Clear all filters", 1, "summary-btn", "clear-btn", 3, "click"], [1, "config-section", "aggregates-section"], [1, "aggregates-header"], [1, "aggregates-description"], ["title", "Add a new aggregate", 1, "add-aggregate-btn", 3, "click", "disabled"], [1, "aggregates-empty-state"], [1, "aggregates-tip"], [1, "aggregates-list"], [1, "aggregate-item", 3, "disabled"], [1, "aggregates-summary"], [1, "summary-item"], [1, "fa-solid", "fa-id-card"], [1, "fa-solid", "fa-table-columns"], [1, "aggregate-item"], [1, "agg-icon"], [1, "agg-content"], [1, "agg-label"], [1, "agg-details"], [1, "agg-type"], ["title", "AI-generated", 1, "agg-smart-badge"], [1, "agg-actions"], ["title", "Move up", 1, "agg-action-btn", 3, "click", "disabled"], ["title", "Move down", 1, "agg-action-btn", 3, "click", "disabled"], [1, "agg-action-btn", "toggle-btn", 3, "click", "disabled", "title"], ["title", "Edit", 1, "agg-action-btn", "edit-btn", 3, "click", "disabled"], ["title", "Remove", 1, "agg-action-btn", "remove-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-trash"], [1, "empty-hint"], [1, "form-group"], ["for", "ViewName"], ["id", "ViewName", "type", "text", "placeholder", "Enter view name...", 1, "form-input", 3, "ngModelChange", "ngModel", "disabled"], [1, "validation-error"], ["for", "ViewDescription"], ["id", "ViewDescription", "placeholder", "Describe this view...", "rows", "3", 1, "form-input", "form-textarea", 3, "ngModelChange", "ngModel", "disabled"], [1, "fa-solid", "fa-share-alt"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel", "disabled"], [1, "checkbox-text"], [1, "config-section", "danger-zone"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "delete-btn", 3, "click"], [1, "footer-btn", "save-btn", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-save"]], template: function ViewConfigPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2728
2728
|
i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_0_Template, 1, 0, "div", 0);
|
|
2729
2729
|
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2);
|
|
2730
|
-
i0.ɵɵlistener("mousedown", function ViewConfigPanelComponent_Template_div_mousedown_2_listener($event) { return ctx.
|
|
2730
|
+
i0.ɵɵlistener("mousedown", function ViewConfigPanelComponent_Template_div_mousedown_2_listener($event) { return ctx.OnResizeStart($event); });
|
|
2731
2731
|
i0.ɵɵelement(3, "div", 3);
|
|
2732
2732
|
i0.ɵɵelementEnd();
|
|
2733
2733
|
i0.ɵɵelementStart(4, "div", 4)(5, "div", 5);
|
|
@@ -2736,27 +2736,27 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2736
2736
|
i0.ɵɵtext(8);
|
|
2737
2737
|
i0.ɵɵelementEnd()();
|
|
2738
2738
|
i0.ɵɵelementStart(9, "button", 7);
|
|
2739
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_9_listener() { return ctx.
|
|
2739
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_9_listener() { return ctx.OnClose(); });
|
|
2740
2740
|
i0.ɵɵelement(10, "i", 8);
|
|
2741
2741
|
i0.ɵɵelementEnd()();
|
|
2742
2742
|
i0.ɵɵelementStart(11, "div", 9)(12, "button", 10);
|
|
2743
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_12_listener() { return ctx.
|
|
2743
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_12_listener() { return ctx.SetActiveTab("columns"); });
|
|
2744
2744
|
i0.ɵɵelement(13, "i", 11);
|
|
2745
2745
|
i0.ɵɵconditionalCreate(14, ViewConfigPanelComponent_Conditional_14_Template, 2, 0, "span");
|
|
2746
2746
|
i0.ɵɵelementEnd();
|
|
2747
2747
|
i0.ɵɵelementStart(15, "button", 10);
|
|
2748
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_15_listener() { return ctx.
|
|
2748
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_15_listener() { return ctx.SetActiveTab("sorting"); });
|
|
2749
2749
|
i0.ɵɵelement(16, "i", 12);
|
|
2750
2750
|
i0.ɵɵconditionalCreate(17, ViewConfigPanelComponent_Conditional_17_Template, 2, 0, "span");
|
|
2751
2751
|
i0.ɵɵconditionalCreate(18, ViewConfigPanelComponent_Conditional_18_Template, 2, 1, "span", 13);
|
|
2752
2752
|
i0.ɵɵelementEnd();
|
|
2753
2753
|
i0.ɵɵelementStart(19, "button", 10);
|
|
2754
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_19_listener() { return ctx.
|
|
2754
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_19_listener() { return ctx.SetActiveTab("filters"); });
|
|
2755
2755
|
i0.ɵɵelement(20, "i", 14);
|
|
2756
2756
|
i0.ɵɵconditionalCreate(21, ViewConfigPanelComponent_Conditional_21_Template, 2, 0, "span");
|
|
2757
2757
|
i0.ɵɵelementEnd();
|
|
2758
2758
|
i0.ɵɵelementStart(22, "button", 10);
|
|
2759
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_22_listener() { return ctx.
|
|
2759
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_22_listener() { return ctx.SetActiveTab("aggregates"); });
|
|
2760
2760
|
i0.ɵɵelement(23, "i", 15);
|
|
2761
2761
|
i0.ɵɵconditionalCreate(24, ViewConfigPanelComponent_Conditional_24_Template, 2, 0, "span");
|
|
2762
2762
|
i0.ɵɵconditionalCreate(25, ViewConfigPanelComponent_Conditional_25_Template, 2, 1, "span", 13);
|
|
@@ -2778,11 +2778,11 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2778
2778
|
i0.ɵɵconditionalCreate(39, ViewConfigPanelComponent_Conditional_39_Template, 4, 3, "button", 23);
|
|
2779
2779
|
i0.ɵɵelementEnd();
|
|
2780
2780
|
i0.ɵɵelementStart(40, "button", 24);
|
|
2781
|
-
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_40_listener() { return ctx.
|
|
2781
|
+
i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_40_listener() { return ctx.OnClose(); });
|
|
2782
2782
|
i0.ɵɵtext(41, " Cancel ");
|
|
2783
2783
|
i0.ɵɵelementEnd()()();
|
|
2784
2784
|
i0.ɵɵelementStart(42, "mj-aggregate-setup-dialog", 25);
|
|
2785
|
-
i0.ɵɵlistener("Close", function ViewConfigPanelComponent_Template_mj_aggregate_setup_dialog_Close_42_listener() { return ctx.
|
|
2785
|
+
i0.ɵɵlistener("Close", function ViewConfigPanelComponent_Template_mj_aggregate_setup_dialog_Close_42_listener() { return ctx.CloseAggregateDialog(); })("Save", function ViewConfigPanelComponent_Template_mj_aggregate_setup_dialog_Save_42_listener($event) { return ctx.OnAggregateSave($event); });
|
|
2786
2786
|
i0.ɵɵelementEnd();
|
|
2787
2787
|
i0.ɵɵelementStart(43, "mj-ev-confirm-dialog", 26);
|
|
2788
2788
|
i0.ɵɵlistener("Confirmed", function ViewConfigPanelComponent_Template_mj_ev_confirm_dialog_Confirmed_43_listener() { return ctx.OnDeleteConfirmed(); })("Cancelled", function ViewConfigPanelComponent_Template_mj_ev_confirm_dialog_Cancelled_43_listener() { return ctx.OnDeleteCancelled(); });
|
|
@@ -2791,92 +2791,92 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2791
2791
|
i0.ɵɵlistener("Confirmed", function ViewConfigPanelComponent_Template_mj_ev_confirm_dialog_Confirmed_44_listener() { return ctx.OnFilterModeSwitchConfirmed(); })("Cancelled", function ViewConfigPanelComponent_Template_mj_ev_confirm_dialog_Cancelled_44_listener() { return ctx.OnFilterModeSwitchCancelled(); });
|
|
2792
2792
|
i0.ɵɵelementEnd();
|
|
2793
2793
|
} if (rf & 2) {
|
|
2794
|
-
i0.ɵɵconditional(ctx.
|
|
2794
|
+
i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
|
|
2795
2795
|
i0.ɵɵadvance();
|
|
2796
|
-
i0.ɵɵstyleProp("width", ctx.
|
|
2797
|
-
i0.ɵɵclassProp("open", ctx.
|
|
2796
|
+
i0.ɵɵstyleProp("width", ctx.PanelWidth, "px");
|
|
2797
|
+
i0.ɵɵclassProp("open", ctx.IsOpen)("resizing", ctx.IsResizing);
|
|
2798
2798
|
i0.ɵɵadvance(7);
|
|
2799
|
-
i0.ɵɵtextInterpolate(ctx.
|
|
2799
|
+
i0.ɵɵtextInterpolate(ctx.ViewEntity ? "Edit View" : "Configure View");
|
|
2800
2800
|
i0.ɵɵadvance(3);
|
|
2801
|
-
i0.ɵɵclassProp("icon-only", ctx.
|
|
2801
|
+
i0.ɵɵclassProp("icon-only", ctx.IsIconOnlyMode);
|
|
2802
2802
|
i0.ɵɵadvance();
|
|
2803
|
-
i0.ɵɵclassProp("active", ctx.
|
|
2804
|
-
i0.ɵɵproperty("title", ctx.
|
|
2803
|
+
i0.ɵɵclassProp("active", ctx.ActiveTab === "columns");
|
|
2804
|
+
i0.ɵɵproperty("title", ctx.IsIconOnlyMode ? "Columns" : "");
|
|
2805
2805
|
i0.ɵɵadvance(2);
|
|
2806
|
-
i0.ɵɵconditional(!ctx.
|
|
2806
|
+
i0.ɵɵconditional(!ctx.IsIconOnlyMode ? 14 : -1);
|
|
2807
2807
|
i0.ɵɵadvance();
|
|
2808
|
-
i0.ɵɵclassProp("active", ctx.
|
|
2809
|
-
i0.ɵɵproperty("title", ctx.
|
|
2808
|
+
i0.ɵɵclassProp("active", ctx.ActiveTab === "sorting");
|
|
2809
|
+
i0.ɵɵproperty("title", ctx.IsIconOnlyMode ? "Sorting" + (ctx.SortItems.length > 0 ? " (" + ctx.SortItems.length + ")" : "") : "");
|
|
2810
2810
|
i0.ɵɵadvance(2);
|
|
2811
|
-
i0.ɵɵconditional(!ctx.
|
|
2811
|
+
i0.ɵɵconditional(!ctx.IsIconOnlyMode ? 17 : -1);
|
|
2812
2812
|
i0.ɵɵadvance();
|
|
2813
|
-
i0.ɵɵconditional(ctx.
|
|
2813
|
+
i0.ɵɵconditional(ctx.SortItems.length > 0 ? 18 : -1);
|
|
2814
2814
|
i0.ɵɵadvance();
|
|
2815
|
-
i0.ɵɵclassProp("active", ctx.
|
|
2816
|
-
i0.ɵɵproperty("title", ctx.
|
|
2815
|
+
i0.ɵɵclassProp("active", ctx.ActiveTab === "filters");
|
|
2816
|
+
i0.ɵɵproperty("title", ctx.IsIconOnlyMode ? "Filters" : "");
|
|
2817
2817
|
i0.ɵɵadvance(2);
|
|
2818
|
-
i0.ɵɵconditional(!ctx.
|
|
2818
|
+
i0.ɵɵconditional(!ctx.IsIconOnlyMode ? 21 : -1);
|
|
2819
2819
|
i0.ɵɵadvance();
|
|
2820
|
-
i0.ɵɵclassProp("active", ctx.
|
|
2821
|
-
i0.ɵɵproperty("title", ctx.
|
|
2820
|
+
i0.ɵɵclassProp("active", ctx.ActiveTab === "aggregates");
|
|
2821
|
+
i0.ɵɵproperty("title", ctx.IsIconOnlyMode ? "Aggregates" + (ctx.EnabledAggregatesCount > 0 ? " (" + ctx.EnabledAggregatesCount + ")" : "") : "");
|
|
2822
2822
|
i0.ɵɵadvance(2);
|
|
2823
|
-
i0.ɵɵconditional(!ctx.
|
|
2823
|
+
i0.ɵɵconditional(!ctx.IsIconOnlyMode ? 24 : -1);
|
|
2824
2824
|
i0.ɵɵadvance();
|
|
2825
|
-
i0.ɵɵconditional(ctx.
|
|
2825
|
+
i0.ɵɵconditional(ctx.EnabledAggregatesCount > 0 ? 25 : -1);
|
|
2826
2826
|
i0.ɵɵadvance();
|
|
2827
|
-
i0.ɵɵconditional(ctx.
|
|
2827
|
+
i0.ɵɵconditional(ctx.ViewEntity || ctx.DefaultSaveAsNew ? 26 : -1);
|
|
2828
2828
|
i0.ɵɵadvance(2);
|
|
2829
|
-
i0.ɵɵconditional(ctx.
|
|
2829
|
+
i0.ɵɵconditional(ctx.ActiveTab === "columns" && !ctx.FormatEditingColumn ? 28 : -1);
|
|
2830
2830
|
i0.ɵɵadvance();
|
|
2831
|
-
i0.ɵɵconditional(ctx.
|
|
2831
|
+
i0.ɵɵconditional(ctx.ActiveTab === "columns" && ctx.FormatEditingColumn ? 29 : -1);
|
|
2832
2832
|
i0.ɵɵadvance();
|
|
2833
|
-
i0.ɵɵconditional(ctx.
|
|
2833
|
+
i0.ɵɵconditional(ctx.ActiveTab === "sorting" ? 30 : -1);
|
|
2834
2834
|
i0.ɵɵadvance();
|
|
2835
|
-
i0.ɵɵconditional(ctx.
|
|
2835
|
+
i0.ɵɵconditional(ctx.ActiveTab === "filters" ? 31 : -1);
|
|
2836
2836
|
i0.ɵɵadvance();
|
|
2837
|
-
i0.ɵɵconditional(ctx.
|
|
2837
|
+
i0.ɵɵconditional(ctx.ActiveTab === "aggregates" ? 32 : -1);
|
|
2838
2838
|
i0.ɵɵadvance();
|
|
2839
|
-
i0.ɵɵconditional(ctx.
|
|
2839
|
+
i0.ɵɵconditional(ctx.ActiveTab === "settings" ? 33 : -1);
|
|
2840
2840
|
i0.ɵɵadvance();
|
|
2841
|
-
i0.ɵɵconditional(ctx.ValidationErrors.length > 0 && ctx.
|
|
2841
|
+
i0.ɵɵconditional(ctx.ValidationErrors.length > 0 && ctx.VisibleColumns.length === 0 ? 34 : -1);
|
|
2842
2842
|
i0.ɵɵadvance(3);
|
|
2843
|
-
i0.ɵɵconditional(ctx.
|
|
2843
|
+
i0.ɵɵconditional(ctx.ViewEntity && ctx.CanEdit ? 37 : -1);
|
|
2844
2844
|
i0.ɵɵadvance();
|
|
2845
|
-
i0.ɵɵconditional(!ctx.
|
|
2845
|
+
i0.ɵɵconditional(!ctx.ViewEntity && ctx.DefaultSaveAsNew ? 38 : -1);
|
|
2846
2846
|
i0.ɵɵadvance();
|
|
2847
|
-
i0.ɵɵconditional(!ctx.
|
|
2847
|
+
i0.ɵɵconditional(!ctx.ViewEntity && !ctx.DefaultSaveAsNew ? 39 : -1);
|
|
2848
2848
|
i0.ɵɵadvance(3);
|
|
2849
|
-
i0.ɵɵproperty("Entity", ctx.
|
|
2849
|
+
i0.ɵɵproperty("Entity", ctx.Entity)("Aggregate", ctx.EditingAggregate)("IsOpen", ctx.ShowAggregateDialog);
|
|
2850
2850
|
i0.ɵɵadvance();
|
|
2851
|
-
i0.ɵɵproperty("IsOpen", ctx.
|
|
2851
|
+
i0.ɵɵproperty("IsOpen", ctx.ShowDeleteConfirm)("Message", "Are you sure you want to delete '" + ctx.ViewName + "'?");
|
|
2852
2852
|
i0.ɵɵadvance();
|
|
2853
|
-
i0.ɵɵproperty("IsOpen", ctx.
|
|
2853
|
+
i0.ɵɵproperty("IsOpen", ctx.ShowFilterModeSwitchConfirm)("Message", ctx.FilterMode === "smart" ? "Switching to Traditional mode will clear your smart filter prompt." : "Switching to Smart mode will clear your traditional filter rules.");
|
|
2854
2854
|
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.AggregateSetupDialogComponent, i3.ConfirmDialogComponent], styles: ["\n\n.panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1200; \n\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1201; \n\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.config-panel.resizing[_ngcontent-%COMP%] {\n transition: none;\n user-select: none;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover, \n.config-panel.resizing[_ngcontent-%COMP%] .resize-handle[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover .resize-grip[_ngcontent-%COMP%], \n.config-panel.resizing[_ngcontent-%COMP%] .resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n.tab-nav[_ngcontent-%COMP%] {\n display: flex;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n transition: all 0.15s ease;\n position: relative;\n white-space: nowrap;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.tab-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 8px;\n right: 8px;\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 2px 2px 0 0;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n}\n\n\n\n.tab-nav.icon-only[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n padding: 12px 8px;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.column-count[_ngcontent-%COMP%] {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 500;\n}\n\n\n\n.column-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n}\n\n.column-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.column-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 13px;\n background: transparent;\n color: var(--mj-text-primary);\n}\n\n.column-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.column-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n\n\n.column-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n transition: background 0.15s ease;\n cursor: default;\n}\n\n.column-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.column-item.hidden[_ngcontent-%COMP%] {\n opacity: 0.7;\n}\n\n.column-item.hidden[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.column-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.4;\n}\n\n.column-item.drop-target[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n\n.drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n\n\n.drag-handle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n cursor: grab;\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px 2px;\n}\n\n.drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .drag-handle[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.column-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.alias-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-brand-primary);\n margin-left: 4px;\n}\n\n.format-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-status-warning);\n margin-left: 4px;\n}\n\n\n\n.column-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .column-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.action-btn.show-btn[_ngcontent-%COMP%] {\n opacity: 0;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .action-btn.show-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn.show-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.action-btn.format-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\n}\n\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.empty-list[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.empty-list[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n\n\n\n.format-editor[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.format-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.back-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.format-editor-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.format-section[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.format-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.format-section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.format-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.format-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.format-row.alias-info[_ngcontent-%COMP%] {\n padding: 4px 0;\n}\n\n.muted-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.clear-alias-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n}\n\n\n\n.format-input[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n}\n\n.format-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.format-input.small[_ngcontent-%COMP%] {\n width: 60px;\n text-align: center;\n}\n\n.format-select[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n}\n\n.format-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.color-input[_ngcontent-%COMP%] {\n width: 36px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n}\n\n\n\n.alignment-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.align-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.align-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.align-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n\n\n.style-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 12px;\n}\n\n.style-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.style-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.style-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n.format-preview-section[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.preview-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.preview-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.preview-header-cell[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.preview-cell[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-cell[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n\n\n.format-actions[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.clear-format-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.clear-format-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n\n\n.sorting-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.sorting-header[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.sorting-description[_ngcontent-%COMP%], \n.aggregates-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n\n\n\n.add-sort-btn[_ngcontent-%COMP%], \n.add-aggregate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n width: 100%;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n margin-bottom: 12px;\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:hover:not(:disabled), \n.add-aggregate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:disabled, \n.add-aggregate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.sort-items-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.sort-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.sort-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.sort-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.4;\n}\n\n.sort-item.drop-target[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n\n\n.sort-drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n\n\n.sort-priority-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n\n\n.sort-drag-handle[_ngcontent-%COMP%] {\n cursor: grab;\n color: var(--mj-text-disabled);\n padding: 2px;\n font-size: 12px;\n}\n\n.sort-drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.sort-item[_ngcontent-%COMP%]:hover .sort-drag-handle[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.sort-field-dropdown[_ngcontent-%COMP%] {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n min-width: 0;\n}\n\n.sort-field-dropdown[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.sort-direction-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n}\n\n.direction-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.direction-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: var(--mj-text-secondary);\n}\n\n.direction-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.direction-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n\n\n.sort-remove-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n\n\n.sort-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.sort-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n\n\n.sort-empty-state[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.sort-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n opacity: 0.4;\n}\n\n.sort-empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n}\n\n.sort-empty-hint[_ngcontent-%COMP%], \n.empty-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.filter-mode-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mode-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n font-size: 16px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] .mode-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.mode-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mode-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.mode-check[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n\n\n.smart-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n margin-bottom: 12px;\n}\n\n.smart-filter-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding-top: 4px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n resize: vertical;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n min-height: 60px;\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n}\n\n\n\n.smart-filter-explanation[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n color: var(--mj-brand-primary);\n}\n\n.smart-filter-explanation[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 2px;\n}\n\n\n\n.smart-filter-examples[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.examples-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.examples-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.example-chip[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n.smart-filter-tip[_ngcontent-%COMP%], \n.traditional-filter-tip[_ngcontent-%COMP%], \n.aggregates-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 12px;\n}\n\n.smart-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.traditional-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.aggregates-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n\n\n.traditional-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.filter-summary-container[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.summary-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 11px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.summary-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.summary-text.no-filters[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.summary-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.summary-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.summary-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn.clear-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n.summary-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.summary-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n\n.aggregates-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.aggregates-header[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n\n\n.aggregates-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.aggregate-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.aggregate-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n\n\n.agg-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n\n\n.agg-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.agg-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n}\n\n.agg-type[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.agg-smart-badge[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n\n\n.agg-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.aggregate-item[_ngcontent-%COMP%]:hover .agg-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.agg-action-btn[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.agg-action-btn.remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.agg-action-btn.edit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.aggregates-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-bottom: 12px;\n}\n\n.aggregates-summary[_ngcontent-%COMP%] .summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.aggregates-summary[_ngcontent-%COMP%] .summary-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n\n\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.form-input.invalid[_ngcontent-%COMP%] {\n border-color: var(--mj-status-error);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 60px;\n font-family: inherit;\n}\n\n.validation-error[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-status-error);\n margin-top: 4px;\n}\n\n\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n background: var(--mj-status-error-bg);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-status-error);\n transition: all 0.15s ease;\n}\n\n.delete-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n\n\n.validation-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error-bg);\n border-top: 1px solid var(--mj-status-error);\n font-size: 13px;\n color: var(--mj-status-error);\n flex-shrink: 0;\n}\n\n\n\n.panel-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 18px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.footer-btn.cancel-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.footer-btn.cancel-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}\n\n\n\n@media (max-width: 480px) {\n .config-panel[_ngcontent-%COMP%] {\n width: 100vw;\n min-width: auto;\n }\n\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
2855
2855
|
}
|
|
2856
2856
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewConfigPanelComponent, [{
|
|
2857
2857
|
type: Component,
|
|
2858
|
-
args: [{ standalone: false, selector: 'mj-view-config-panel', template: "<!-- Backdrop -->\n@if (isOpen) {\n <div class=\"panel-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Sliding Panel -->\n<div class=\"config-panel\"\n [class.open]=\"isOpen\"\n [class.resizing]=\"isResizing\"\n [style.width.px]=\"panelWidth\">\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n (mousedown)=\"onResizeStart($event)\"\n title=\"Drag to resize\">\n <div class=\"resize-grip\"></div>\n </div>\n\n <!-- Panel Header -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n <span>{{ viewEntity ? 'Edit View' : 'Configure View' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\" aria-label=\"Close panel\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-nav\" [class.icon-only]=\"isIconOnlyMode\">\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'columns'\"\n (click)=\"setActiveTab('columns')\"\n [title]=\"isIconOnlyMode ? 'Columns' : ''\">\n <i class=\"fa-solid fa-columns\"></i>\n @if (!isIconOnlyMode) {\n <span>Columns</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'sorting'\"\n (click)=\"setActiveTab('sorting')\"\n [title]=\"isIconOnlyMode ? 'Sorting' + (sortItems.length > 0 ? ' (' + sortItems.length + ')' : '') : ''\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n @if (!isIconOnlyMode) {\n <span>Sorting</span>\n }\n @if (sortItems.length > 0) {\n <span class=\"tab-badge\">{{ sortItems.length }}</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'filters'\"\n (click)=\"setActiveTab('filters')\"\n [title]=\"isIconOnlyMode ? 'Filters' : ''\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (!isIconOnlyMode) {\n <span>Filters</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'aggregates'\"\n (click)=\"setActiveTab('aggregates')\"\n [title]=\"isIconOnlyMode ? 'Aggregates' + (enabledAggregatesCount > 0 ? ' (' + enabledAggregatesCount + ')' : '') : ''\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n @if (!isIconOnlyMode) {\n <span>Aggregates</span>\n }\n @if (enabledAggregatesCount > 0) {\n <span class=\"tab-badge\">{{ enabledAggregatesCount }}</span>\n }\n </button>\n @if (viewEntity || DefaultSaveAsNew) {\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'settings'\"\n (click)=\"setActiveTab('settings')\"\n [title]=\"isIconOnlyMode ? 'Settings' : ''\">\n <i class=\"fa-solid fa-cog\"></i>\n @if (!isIconOnlyMode) {\n <span>Settings</span>\n }\n </button>\n }\n </div>\n\n <!-- Panel Content -->\n <div class=\"panel-content\">\n <!-- Columns Tab -->\n @if (activeTab === 'columns' && !formatEditingColumn) {\n <div class=\"tab-content\">\n <!-- Visible Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Visible Columns</span>\n <span class=\"column-count\">{{ visibleColumns.length }}</span>\n </div>\n <div class=\"column-list visible-columns\">\n @for (column of visibleColumns; track column.fieldId; let i = $index) {\n <!-- Drop indicator before -->\n @if (isDropBefore(column)) {\n <div class=\"drop-indicator\"></div>\n }\n <div\n class=\"column-item\"\n [class.dragging]=\"draggedColumn === column\"\n [class.drop-target]=\"dropTargetColumn === column\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, column)\"\n (dragover)=\"onDragOver($event, column)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event, column)\"\n (dragend)=\"onDragEnd($event)\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <span class=\"column-name\">\n {{ column.userDisplayName || column.displayName }}\n @if (column.userDisplayName) {\n <i class=\"fa-solid fa-pen-nib alias-indicator\" title=\"Custom name: {{ column.userDisplayName }}\"></i>\n }\n @if (hasCustomFormat(column)) {\n <i class=\"fa-solid fa-paintbrush format-indicator\" title=\"Custom formatting applied\"></i>\n }\n </span>\n <div class=\"column-actions\">\n <button\n class=\"action-btn format-btn\"\n (click)=\"openFormatEditor(column)\"\n title=\"Format column\">\n <i class=\"fa-solid fa-paintbrush\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === 0\"\n (click)=\"moveColumnUp(column)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === visibleColumns.length - 1\"\n (click)=\"moveColumnDown(column)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"action-btn hide-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Hide column\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n </button>\n </div>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isDropAfter(column) && i === visibleColumns.length - 1) {\n <div class=\"drop-indicator\"></div>\n }\n }\n @if (visibleColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No columns visible. Add columns from below.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Hidden Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n <span>Hidden Columns</span>\n <span class=\"column-count\">{{ hiddenColumns.length }}</span>\n </div>\n @if (hiddenColumns.length > 5) {\n <div class=\"column-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearchText\"\n />\n </div>\n }\n <div class=\"column-list hidden-columns\">\n @for (column of filteredHiddenColumns; track column.fieldId) {\n <div class=\"column-item hidden\">\n <span class=\"column-name\">{{ column.displayName }}</span>\n <button\n class=\"action-btn show-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Show column\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n @if (hiddenColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>All columns are visible</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Column Format Editor Sub-Panel -->\n @if (activeTab === 'columns' && formatEditingColumn) {\n <div class=\"format-editor\">\n <!-- Format Editor Header -->\n <div class=\"format-editor-header\">\n <button class=\"back-btn\" (click)=\"closeFormatEditor()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n </button>\n <div class=\"format-editor-title\">\n <span>Format: {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}</span>\n </div>\n </div>\n\n <!-- Column Alias Section -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-pen-nib\"></i>\n <span>Column Name</span>\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <input type=\"text\" class=\"format-input\"\n [value]=\"formatEditingColumn.userDisplayName || ''\"\n (input)=\"updateUserDisplayName($any($event.target).value)\"\n [placeholder]=\"formatEditingColumn.displayName\" />\n </div>\n @if (formatEditingColumn.userDisplayName) {\n <div class=\"format-row alias-info\">\n <small class=\"muted-text\">Original: {{ formatEditingColumn.displayName }}</small>\n <button class=\"clear-alias-btn\" (click)=\"formatEditingColumn.userDisplayName = undefined\" title=\"Clear alias\" aria-label=\"Clear alias\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Preview Section -->\n <div class=\"format-preview-section\">\n <div class=\"preview-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-table\">\n <div class=\"preview-header-cell\"\n [style.font-weight]=\"formatEditingColumn.format?.headerStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.headerStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.headerStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.headerStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.headerStyle?.backgroundColor\">\n {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}\n </div>\n @for (value of getSampleValues(formatEditingColumn); track $index) {\n <div class=\"preview-cell\"\n [style.text-align]=\"formatEditingColumn.format?.align || 'left'\"\n [style.font-weight]=\"formatEditingColumn.format?.cellStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.cellStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.cellStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.cellStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.cellStyle?.backgroundColor\">\n {{ formatPreviewValue(value, formatEditingColumn.format) }}\n </div>\n }\n </div>\n </div>\n\n <!-- Format Type -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-hashtag\"></i>\n <span>Format Type</span>\n </div>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.type\">\n <option value=\"auto\">Auto (Smart Default)</option>\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percent\">Percent</option>\n <option value=\"date\">Date</option>\n <option value=\"datetime\">Date & Time</option>\n <option value=\"boolean\">Boolean</option>\n </select>\n </div>\n\n <!-- Type-Specific Options -->\n @if (formatEditingColumn.format?.type === 'number' || formatEditingColumn.format?.type === 'currency' || formatEditingColumn.format?.type === 'percent') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Number Options</span>\n </div>\n <div class=\"format-row\">\n <label>Decimal Places</label>\n <input type=\"number\" class=\"format-input small\" min=\"0\" max=\"10\"\n [(ngModel)]=\"formatEditingColumn.format!.decimals\" />\n </div>\n @if (formatEditingColumn.format?.type === 'currency') {\n <div class=\"format-row\">\n <label>Currency</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.currencyCode\">\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR (\u20AC)</option>\n <option value=\"GBP\">GBP (\u00A3)</option>\n <option value=\"JPY\">JPY (\u00A5)</option>\n <option value=\"CAD\">CAD ($)</option>\n <option value=\"AUD\">AUD ($)</option>\n </select>\n </div>\n }\n <div class=\"format-row\">\n <label>Thousands Separator</label>\n <input type=\"checkbox\" [(ngModel)]=\"formatEditingColumn.format!.thousandsSeparator\" />\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'date' || formatEditingColumn.format?.type === 'datetime') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span>Date Options</span>\n </div>\n <div class=\"format-row\">\n <label>Format</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.dateFormat\">\n <option value=\"short\">Short (1/15/25)</option>\n <option value=\"short-weekday\">Short + Day (Wed, 1/15/25)</option>\n <option value=\"medium\">Medium (Jan 15, 2025)</option>\n <option value=\"medium-weekday\">Medium + Day (Wed, Jan 15, 2025)</option>\n <option value=\"long\">Long (January 15, 2025)</option>\n <option value=\"long-weekday\">Long + Day (Wednesday, January 15, 2025)</option>\n </select>\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'boolean') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n <span>Boolean Options</span>\n </div>\n <div class=\"format-row\">\n <label>True Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.trueLabel\" placeholder=\"Yes\" />\n </div>\n <div class=\"format-row\">\n <label>False Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.falseLabel\" placeholder=\"No\" />\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.booleanDisplay\">\n <option value=\"text\">Text</option>\n <option value=\"checkbox\">Checkbox</option>\n <option value=\"icon\">Icon</option>\n </select>\n </div>\n </div>\n }\n\n <!-- Alignment -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-align-left\"></i>\n <span>Alignment</span>\n </div>\n <div class=\"alignment-toggle\">\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'left' || !formatEditingColumn.format?.align\"\n (click)=\"formatEditingColumn.format!.align = 'left'\" title=\"Left\">\n <i class=\"fa-solid fa-align-left\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'center'\"\n (click)=\"formatEditingColumn.format!.align = 'center'\" title=\"Center\">\n <i class=\"fa-solid fa-align-center\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'right'\"\n (click)=\"formatEditingColumn.format!.align = 'right'\" title=\"Right\">\n <i class=\"fa-solid fa-align-right\"></i>\n </button>\n </div>\n </div>\n\n <!-- Header Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-heading\"></i>\n <span>Header Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.bold\"\n (click)=\"toggleHeaderStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.italic\"\n (click)=\"toggleHeaderStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.underline\"\n (click)=\"toggleHeaderStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.color || '#000000'\"\n (input)=\"updateHeaderColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateHeaderColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Cell Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Cell Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.bold\"\n (click)=\"toggleCellStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.italic\"\n (click)=\"toggleCellStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.underline\"\n (click)=\"toggleCellStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.color || '#000000'\"\n (input)=\"updateCellColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateCellColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Clear Format Button -->\n <div class=\"format-actions\">\n <button class=\"clear-format-btn\" (click)=\"clearColumnFormat(formatEditingColumn); closeFormatEditor()\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear Formatting\n </button>\n </div>\n </div>\n }\n\n <!-- Sorting Tab -->\n @if (activeTab === 'sorting') {\n <div class=\"tab-content\">\n <div class=\"config-section sorting-section\">\n <div class=\"sorting-header\">\n <p class=\"sorting-description\">\n Define how records should be ordered. Add multiple levels to sort by secondary fields when values are equal.\n </p>\n </div>\n\n <!-- Add Sort Button -->\n <button\n class=\"add-sort-btn\"\n (click)=\"addSortLevel()\"\n [disabled]=\"!canEdit || sortItems.length >= sortableFields.length\"\n title=\"Add another sort level\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Sort Level</span>\n </button>\n\n <!-- Sort Items List -->\n @if (sortItems.length > 0) {\n <div class=\"sort-items-list\">\n @for (sortItem of sortItems; track $index; let i = $index) {\n <!-- Drop indicator before -->\n @if (isSortDropBefore(sortItem)) {\n <div class=\"sort-drop-indicator\"></div>\n }\n <div\n class=\"sort-item\"\n [class.dragging]=\"draggedSortItem === sortItem\"\n [class.drop-target]=\"dropTargetSortItem === sortItem\"\n draggable=\"true\"\n (dragstart)=\"onSortDragStart($event, sortItem)\"\n (dragover)=\"onSortDragOver($event, sortItem)\"\n (dragleave)=\"onSortDragLeave($event)\"\n (drop)=\"onSortDrop($event, sortItem)\"\n (dragend)=\"onSortDragEnd($event)\">\n <!-- Priority Badge -->\n <div class=\"sort-priority-badge\">{{ i + 1 }}</div>\n <!-- Drag Handle -->\n <div class=\"sort-drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <!-- Field Dropdown -->\n <select\n class=\"sort-field-dropdown\"\n [(ngModel)]=\"sortItem.field\"\n (ngModelChange)=\"onSortFieldChange(sortItem, $event)\"\n [disabled]=\"!canEdit\">\n @for (field of sortableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ field.DisplayNameOrName }}</option>\n }\n </select>\n <!-- Direction Toggle -->\n <div class=\"sort-direction-toggle\">\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'asc'\"\n (click)=\"onSortDirectionChange(sortItem, 'asc')\"\n [disabled]=\"!canEdit\"\n title=\"Ascending (A-Z, 1-9)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'desc'\"\n (click)=\"onSortDirectionChange(sortItem, 'desc')\"\n [disabled]=\"!canEdit\"\n title=\"Descending (Z-A, 9-1)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </button>\n </div>\n <!-- Remove Button -->\n <button\n class=\"sort-remove-btn\"\n (click)=\"removeSortLevel(sortItem)\"\n [disabled]=\"!canEdit\"\n title=\"Remove sort level\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isSortDropAfter(sortItem) && i === sortItems.length - 1) {\n <div class=\"sort-drop-indicator\"></div>\n }\n }\n </div>\n <!-- Multi-sort hint -->\n @if (sortItems.length > 1) {\n <div class=\"sort-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Drag items to change priority. Records sort by first level, then second, etc.</span>\n </div>\n }\n } @else {\n <div class=\"sort-empty-state\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>No sorting configured</span>\n <p class=\"sort-empty-hint\">Click \"Add Sort Level\" to define how records should be ordered</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Filters Tab -->\n @if (activeTab === 'filters') {\n <div class=\"tab-content\">\n <!-- Filter Mode Selection -->\n <div class=\"filter-mode-selector\">\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'smart'\"\n (click)=\"setFilterMode('smart')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Smart Filter</span>\n <span class=\"mode-subtitle\">Use AI to filter with natural language</span>\n </div>\n @if (filterMode === 'smart') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'traditional'\"\n (click)=\"setFilterMode('traditional')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Traditional Filter</span>\n <span class=\"mode-subtitle\">Build filters with field/operator/value</span>\n </div>\n @if (filterMode === 'traditional') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n </div>\n\n <!-- Smart Filter Section -->\n @if (filterMode === 'smart') {\n <div class=\"config-section smart-filter-section\">\n <div class=\"smart-filter-input-container\">\n <div class=\"smart-filter-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <textarea\n id=\"smartFilterPrompt\"\n class=\"smart-filter-textarea\"\n placeholder=\"Describe what you're looking for...\"\n [(ngModel)]=\"smartFilterPrompt\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n\n @if (smartFilterExplanation) {\n <div class=\"smart-filter-explanation\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>{{ smartFilterExplanation }}</span>\n </div>\n }\n\n <!-- Example Prompts -->\n <div class=\"smart-filter-examples\">\n <div class=\"examples-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Try these examples:</span>\n </div>\n <div class=\"example-chips\">\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Show records created in the last 30 days')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-regular fa-calendar\"></i>\n Last 30 days\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Active records only')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Active only\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records with high priority')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-star\"></i>\n High priority\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records modified this week')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Modified this week\n </button>\n </div>\n </div>\n\n <div class=\"smart-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>The AI will interpret your description and create the appropriate filter when you save the view.</span>\n </div>\n </div>\n }\n\n <!-- Traditional Filter Section -->\n @if (filterMode === 'traditional') {\n <div class=\"config-section traditional-filter-section\">\n <div class=\"filter-summary-container\">\n <div class=\"filter-summary\">\n <div class=\"summary-info\">\n @if (getFilterCount() > 0) {\n <span class=\"filter-badge\">{{ getFilterCount() }}</span>\n <span class=\"summary-text\">{{ getFilterSummary() }}</span>\n } @else {\n <span class=\"summary-text no-filters\">No filters configured</span>\n }\n </div>\n <div class=\"summary-actions\">\n @if (getFilterCount() > 0 && canEdit) {\n <button\n class=\"summary-btn clear-btn\"\n (click)=\"clearFilters()\"\n title=\"Clear all filters\">\n <i class=\"fa-solid fa-times\"></i>\n Clear\n </button>\n }\n <button\n class=\"summary-btn edit-btn primary\"\n (click)=\"openFilterDialog()\"\n [disabled]=\"!canEdit && getFilterCount() === 0\"\n title=\"Edit filters\">\n <i class=\"fa-solid fa-pen\"></i>\n {{ getFilterCount() > 0 ? 'Edit Filters' : 'Add Filters' }}\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"traditional-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Build precise filters by selecting fields, operators, and values. Use groups for complex AND/OR logic.</span>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Aggregates Tab -->\n @if (activeTab === 'aggregates') {\n <div class=\"tab-content\">\n <div class=\"config-section aggregates-section\">\n <div class=\"aggregates-header\">\n <p class=\"aggregates-description\">\n Add summary calculations like totals, averages, and counts. Display them in cards or as column footers.\n </p>\n </div>\n\n <!-- Add Aggregate Button -->\n <button\n class=\"add-aggregate-btn\"\n (click)=\"openAddAggregateDialog()\"\n [disabled]=\"!canEdit\"\n title=\"Add a new aggregate\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Aggregate</span>\n </button>\n\n <!-- Aggregates List -->\n @if (aggregates.length > 0) {\n <div class=\"aggregates-list\">\n @for (agg of aggregates; track agg.id; let i = $index) {\n <div class=\"aggregate-item\" [class.disabled]=\"agg.enabled === false\">\n <!-- Icon -->\n <div class=\"agg-icon\">\n <i [class]=\"agg.icon || 'fa-solid fa-chart-simple'\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"agg-content\">\n <div class=\"agg-label\">{{ agg.label }}</div>\n <div class=\"agg-details\">\n <span class=\"agg-type\">\n <i [class]=\"agg.displayType === 'card' ? 'fa-solid fa-id-card' : 'fa-solid fa-table-columns'\"></i>\n {{ agg.displayType === 'card' ? 'Card' : 'Column Footer' }}\n </span>\n @if (agg.smartPrompt) {\n <span class=\"agg-smart-badge\" title=\"AI-generated\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"agg-actions\">\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === 0 || !canEdit\"\n (click)=\"moveAggregateUp(agg)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === aggregates.length - 1 || !canEdit\"\n (click)=\"moveAggregateDown(agg)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"agg-action-btn toggle-btn\"\n [class.enabled]=\"agg.enabled !== false\"\n (click)=\"toggleAggregateEnabled(agg, $event)\"\n [disabled]=\"!canEdit\"\n [title]=\"agg.enabled !== false ? 'Disable' : 'Enable'\">\n <i [class]=\"agg.enabled !== false ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'\"></i>\n </button>\n <button\n class=\"agg-action-btn edit-btn\"\n (click)=\"editAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button\n class=\"agg-action-btn remove-btn\"\n (click)=\"removeAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Remove\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Summary -->\n <div class=\"aggregates-summary\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>{{ cardAggregates.length }} card{{ cardAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>{{ columnAggregates.length }} column footer{{ columnAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n </div>\n } @else {\n <div class=\"aggregates-empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>No aggregates configured</span>\n <p class=\"empty-hint\">Click \"Add Aggregate\" to create summary calculations</p>\n </div>\n }\n\n <!-- Info Tip -->\n <div class=\"aggregates-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Aggregates are calculated server-side for accuracy with filtered/paginated data.</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Settings Tab -->\n @if (activeTab === 'settings') {\n <div class=\"tab-content\">\n <!-- View Name & Description -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>View Details</span>\n </div>\n <div class=\"form-group\">\n <label for=\"viewName\">Name</label>\n <input\n id=\"viewName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"!viewName || !viewName.trim()\"\n placeholder=\"Enter view name...\"\n [(ngModel)]=\"viewName\"\n [disabled]=\"!canEdit\"\n />\n @if (!viewName || !viewName.trim()) {\n <span class=\"validation-error\">View name is required</span>\n }\n </div>\n <div class=\"form-group\">\n <label for=\"viewDescription\">Description</label>\n <textarea\n id=\"viewDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"Describe this view...\"\n [(ngModel)]=\"viewDescription\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n </div>\n\n <!-- Sharing -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-share-alt\"></i>\n <span>Sharing</span>\n </div>\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"isShared\"\n [disabled]=\"!canEdit\"\n />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n </div>\n\n <!-- Danger Zone -->\n @if (viewEntity && canDelete) {\n <div class=\"config-section danger-zone\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Danger Zone</span>\n </div>\n <button class=\"delete-btn\" (click)=\"onDelete()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span>Delete View</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Validation Errors Banner -->\n @if (ValidationErrors.length > 0 && visibleColumns.length === 0) {\n <div class=\"validation-banner\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>At least one column must be visible</span>\n </div>\n }\n\n <!-- Panel Footer -->\n <div class=\"panel-footer\">\n <!-- Action buttons on LEFT -->\n <div class=\"footer-left\">\n @if (viewEntity && canEdit) {\n <!-- Editing an existing saved view -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSave()\"\n [disabled]=\"isSaving || !IsValid\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n @if (!viewEntity && DefaultSaveAsNew) {\n <!-- Creating a new view (from quick save dialog) -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving || !IsValidForSaveAsNew\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n @if (!viewEntity && !DefaultSaveAsNew) {\n <!-- Default/Dynamic view - Save to user settings -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveDefaults()\"\n [disabled]=\"isSaving\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n </div>\n <!-- Cancel button on RIGHT -->\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n</div>\n\n<!-- Aggregate Setup Dialog -->\n<mj-aggregate-setup-dialog\n [Entity]=\"entity\"\n [Aggregate]=\"editingAggregate\"\n [IsOpen]=\"showAggregateDialog\"\n (Close)=\"closeAggregateDialog()\"\n (Save)=\"onAggregateSave($event)\">\n</mj-aggregate-setup-dialog>\n\n<!-- Delete Confirmation Dialog -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete View\"\n [Message]=\"'Are you sure you want to delete \\'' + viewName + '\\'?'\"\n DetailMessage=\"This action cannot be undone. All users who have access to this view will lose it.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"OnDeleteConfirmed()\"\n (Cancelled)=\"OnDeleteCancelled()\">\n</mj-ev-confirm-dialog>\n\n<!-- Filter Mode Switch Confirmation Dialog (BUG-006) -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showFilterModeSwitchConfirm\"\n Title=\"Switch Filter Mode\"\n [Message]=\"filterMode === 'smart' ? 'Switching to Traditional mode will clear your smart filter prompt.' : 'Switching to Smart mode will clear your traditional filter rules.'\"\n DetailMessage=\"You can switch back later, but the current filter data will be lost.\"\n ConfirmText=\"Switch\"\n ConfirmStyle=\"primary\"\n Icon=\"fa-solid fa-exchange-alt\"\n (Confirmed)=\"OnFilterModeSwitchConfirmed()\"\n (Cancelled)=\"OnFilterModeSwitchCancelled()\">\n</mj-ev-confirm-dialog>\n", styles: ["/* Backdrop */\n.panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1200; /* Above Leaflet map (1000), content-header (1100) */\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Sliding Panel */\n.config-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1201; /* Above backdrop (1200) */\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open {\n transform: translateX(0);\n}\n\n.config-panel.resizing {\n transition: none;\n user-select: none;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle:hover,\n.config-panel.resizing .resize-handle {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle:hover .resize-grip,\n.config-panel.resizing .resize-grip {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n transition: all 0.15s ease;\n position: relative;\n white-space: nowrap;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.tab-btn.active::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 8px;\n right: 8px;\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 2px 2px 0 0;\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n}\n\n/* Icon-only mode for narrow panel */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.tab-content {\n padding: 16px;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 20px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.column-count {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 13px;\n background: transparent;\n color: var(--mj-text-primary);\n}\n\n.column-search input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Column List */\n.column-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n/* Column Item */\n.column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n transition: background 0.15s ease;\n cursor: default;\n}\n\n.column-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.column-item.hidden {\n opacity: 0.7;\n}\n\n.column-item.hidden:hover {\n opacity: 1;\n}\n\n.column-item.dragging {\n opacity: 0.4;\n}\n\n.column-item.drop-target {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Drop Indicator */\n.drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Drag Handle */\n.drag-handle {\n display: flex;\n align-items: center;\n cursor: grab;\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px 2px;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.column-item:hover .drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Column Name */\n.column-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.alias-indicator {\n font-size: 10px;\n color: var(--mj-brand-primary);\n margin-left: 4px;\n}\n\n.format-indicator {\n font-size: 10px;\n color: var(--mj-status-warning);\n margin-left: 4px;\n}\n\n/* Column Actions */\n.column-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.column-item:hover .column-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.action-btn.show-btn {\n opacity: 0;\n}\n\n.column-item:hover .action-btn.show-btn {\n opacity: 1;\n}\n\n.action-btn.show-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.action-btn.format-btn:hover {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n/* Empty List */\n.empty-list {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.empty-list i {\n color: var(--mj-text-disabled);\n}\n\n/* Format Editor */\n.format-editor {\n padding: 0;\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.back-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.format-editor-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Format Sections */\n.format-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.format-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.format-section-header i {\n color: var(--mj-text-muted);\n}\n\n/* Format Rows */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.format-row.alias-info {\n padding: 4px 0;\n}\n\n.muted-text {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.clear-alias-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n color: var(--mj-status-error);\n}\n\n/* Format Input */\n.format-input {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n}\n\n.format-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.format-input.small {\n width: 60px;\n text-align: center;\n}\n\n.format-select {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n}\n\n.format-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Color Input */\n.color-input {\n width: 36px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.align-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 4px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.style-btn:hover {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.style-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Format Preview */\n.format-preview-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.preview-header i {\n color: var(--mj-text-muted);\n}\n\n.preview-table {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.preview-header-cell {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.preview-cell {\n padding: 8px 12px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-cell:last-child {\n border-bottom: none;\n}\n\n/* Format Actions */\n.format-actions {\n padding: 16px;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n/* Sorting Section */\n.sorting-section {\n padding: 0;\n}\n\n.sorting-header {\n margin-bottom: 12px;\n}\n\n.sorting-description,\n.aggregates-description {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n\n/* Add Sort Button */\n.add-sort-btn,\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n width: 100%;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled),\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-sort-btn:disabled,\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.sort-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.sort-item.dragging {\n opacity: 0.4;\n}\n\n.sort-item.drop-target {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Sort Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n/* Sort Drag Handle */\n.sort-drag-handle {\n cursor: grab;\n color: var(--mj-text-disabled);\n padding: 2px;\n font-size: 12px;\n}\n\n.sort-drag-handle:active {\n cursor: grabbing;\n}\n\n.sort-item:hover .sort-drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n min-width: 0;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Sort Direction Toggle */\n.sort-direction-toggle {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n}\n\n.direction-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover:not(:disabled) {\n color: var(--mj-text-secondary);\n}\n\n.direction-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.direction-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Remove Button */\n.sort-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Hint */\n.sort-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.sort-hint i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Sort Empty State */\n.sort-empty-state,\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.sort-empty-state i,\n.aggregates-empty-state i {\n font-size: 32px;\n opacity: 0.4;\n}\n\n.sort-empty-state span,\n.aggregates-empty-state span {\n font-size: 14px;\n font-weight: 500;\n}\n\n.sort-empty-hint,\n.empty-hint {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-disabled);\n}\n\n/* Filter Mode Selector */\n.filter-mode-selector {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.filter-mode-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mode-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n font-size: 16px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mode-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.mode-check {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n/* Smart Filter Section */\n.smart-filter-section {\n padding: 0;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n margin-bottom: 12px;\n}\n\n.smart-filter-icon {\n display: flex;\n align-items: flex-start;\n padding-top: 4px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.smart-filter-textarea {\n flex: 1;\n border: none;\n outline: none;\n resize: vertical;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n min-height: 60px;\n}\n\n.smart-filter-textarea::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.smart-filter-textarea:disabled {\n color: var(--mj-text-muted);\n}\n\n/* Smart Filter Explanation */\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n color: var(--mj-brand-primary);\n}\n\n.smart-filter-explanation i {\n margin-top: 2px;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 12px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.examples-header i {\n color: var(--mj-status-warning);\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.example-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.example-chip:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip i {\n font-size: 11px;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip,\n.traditional-filter-tip,\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 12px;\n}\n\n.smart-filter-tip i,\n.traditional-filter-tip i,\n.aggregates-tip i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Traditional Filter Section */\n.traditional-filter-section {\n padding: 0;\n}\n\n.filter-summary-container {\n margin-bottom: 12px;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 11px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.summary-text {\n font-size: 13px;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.summary-text.no-filters {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.summary-actions {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.summary-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn.clear-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n.summary-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.summary-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* Aggregates Section */\n.aggregates-section {\n padding: 0;\n}\n\n.aggregates-header {\n margin-bottom: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.aggregate-item.disabled {\n opacity: 0.5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.agg-smart-badge {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.aggregate-item:hover .agg-actions {\n opacity: 1;\n}\n\n.agg-action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.agg-action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled {\n color: var(--mj-brand-primary);\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-bottom: 12px;\n}\n\n.aggregates-summary .summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.aggregates-summary .summary-item i {\n color: var(--mj-text-disabled);\n}\n\n/* Settings Tab */\n.form-group {\n margin-bottom: 16px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.form-input.invalid {\n border-color: var(--mj-status-error);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 60px;\n font-family: inherit;\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n margin-top: 4px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Danger Zone */\n.danger-zone .section-header {\n color: var(--mj-status-error);\n}\n\n.danger-zone .section-header i {\n color: var(--mj-status-error);\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n background: var(--mj-status-error-bg);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-status-error);\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n/* Validation Banner */\n.validation-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error-bg);\n border-top: 1px solid var(--mj-status-error);\n font-size: 13px;\n color: var(--mj-status-error);\n flex-shrink: 0;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 18px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.footer-btn.cancel-btn {\n background: var(--mj-bg-surface-card);\n}\n\n.footer-btn.cancel-btn:hover {\n background: var(--mj-bg-surface-active);\n}\n\n/* Responsive */\n@media (max-width: 480px) {\n .config-panel {\n width: 100vw;\n min-width: auto;\n }\n\n .resize-handle {\n display: none;\n }\n}\n"] }]
|
|
2859
|
-
}], () => [{ type: i0.ChangeDetectorRef }], {
|
|
2858
|
+
args: [{ standalone: false, selector: 'mj-view-config-panel', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"panel-backdrop\" (click)=\"OnClose()\"></div>\n}\n\n<!-- Sliding Panel -->\n<div class=\"config-panel\"\n [class.open]=\"IsOpen\"\n [class.resizing]=\"IsResizing\"\n [style.width.px]=\"PanelWidth\">\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n (mousedown)=\"OnResizeStart($event)\"\n title=\"Drag to resize\">\n <div class=\"resize-grip\"></div>\n </div>\n\n <!-- Panel Header -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n <span>{{ ViewEntity ? 'Edit View' : 'Configure View' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\" aria-label=\"Close panel\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-nav\" [class.icon-only]=\"IsIconOnlyMode\">\n <button\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'columns'\"\n (click)=\"SetActiveTab('columns')\"\n [title]=\"IsIconOnlyMode ? 'Columns' : ''\">\n <i class=\"fa-solid fa-columns\"></i>\n @if (!IsIconOnlyMode) {\n <span>Columns</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'sorting'\"\n (click)=\"SetActiveTab('sorting')\"\n [title]=\"IsIconOnlyMode ? 'Sorting' + (SortItems.length > 0 ? ' (' + SortItems.length + ')' : '') : ''\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n @if (!IsIconOnlyMode) {\n <span>Sorting</span>\n }\n @if (SortItems.length > 0) {\n <span class=\"tab-badge\">{{ SortItems.length }}</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'filters'\"\n (click)=\"SetActiveTab('filters')\"\n [title]=\"IsIconOnlyMode ? 'Filters' : ''\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (!IsIconOnlyMode) {\n <span>Filters</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'aggregates'\"\n (click)=\"SetActiveTab('aggregates')\"\n [title]=\"IsIconOnlyMode ? 'Aggregates' + (EnabledAggregatesCount > 0 ? ' (' + EnabledAggregatesCount + ')' : '') : ''\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n @if (!IsIconOnlyMode) {\n <span>Aggregates</span>\n }\n @if (EnabledAggregatesCount > 0) {\n <span class=\"tab-badge\">{{ EnabledAggregatesCount }}</span>\n }\n </button>\n @if (ViewEntity || DefaultSaveAsNew) {\n <button\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'settings'\"\n (click)=\"SetActiveTab('settings')\"\n [title]=\"IsIconOnlyMode ? 'Settings' : ''\">\n <i class=\"fa-solid fa-cog\"></i>\n @if (!IsIconOnlyMode) {\n <span>Settings</span>\n }\n </button>\n }\n </div>\n\n <!-- Panel Content -->\n <div class=\"panel-content\">\n <!-- Columns Tab -->\n @if (ActiveTab === 'columns' && !FormatEditingColumn) {\n <div class=\"tab-content\">\n <!-- Visible Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Visible Columns</span>\n <span class=\"column-count\">{{ VisibleColumns.length }}</span>\n </div>\n <div class=\"column-list visible-columns\">\n @for (column of VisibleColumns; track column.fieldId; let i = $index) {\n <!-- Drop indicator before -->\n @if (IsDropBefore(column)) {\n <div class=\"drop-indicator\"></div>\n }\n <div\n class=\"column-item\"\n [class.dragging]=\"DraggedColumn === column\"\n [class.drop-target]=\"DropTargetColumn === column\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, column)\"\n (dragover)=\"OnDragOver($event, column)\"\n (dragleave)=\"OnDragLeave($event)\"\n (drop)=\"OnDrop($event, column)\"\n (dragend)=\"OnDragEnd($event)\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <span class=\"column-name\">\n {{ column.userDisplayName || column.displayName }}\n @if (column.userDisplayName) {\n <i class=\"fa-solid fa-pen-nib alias-indicator\" title=\"Custom name: {{ column.userDisplayName }}\"></i>\n }\n @if (HasCustomFormat(column)) {\n <i class=\"fa-solid fa-paintbrush format-indicator\" title=\"Custom formatting applied\"></i>\n }\n </span>\n <div class=\"column-actions\">\n <button\n class=\"action-btn format-btn\"\n (click)=\"OpenFormatEditor(column)\"\n title=\"Format column\">\n <i class=\"fa-solid fa-paintbrush\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === 0\"\n (click)=\"MoveColumnUp(column)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === VisibleColumns.length - 1\"\n (click)=\"MoveColumnDown(column)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"action-btn hide-btn\"\n (click)=\"ToggleColumnVisibility(column)\"\n title=\"Hide column\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n </button>\n </div>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (IsDropAfter(column) && i === VisibleColumns.length - 1) {\n <div class=\"drop-indicator\"></div>\n }\n }\n @if (VisibleColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No columns visible. Add columns from below.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Hidden Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n <span>Hidden Columns</span>\n <span class=\"column-count\">{{ HiddenColumns.length }}</span>\n </div>\n @if (HiddenColumns.length > 5) {\n <div class=\"column-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"ColumnSearchText\"\n />\n </div>\n }\n <div class=\"column-list hidden-columns\">\n @for (column of FilteredHiddenColumns; track column.fieldId) {\n <div class=\"column-item hidden\">\n <span class=\"column-name\">{{ column.displayName }}</span>\n <button\n class=\"action-btn show-btn\"\n (click)=\"ToggleColumnVisibility(column)\"\n title=\"Show column\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n @if (HiddenColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>All columns are visible</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Column Format Editor Sub-Panel -->\n @if (ActiveTab === 'columns' && FormatEditingColumn) {\n <div class=\"format-editor\">\n <!-- Format Editor Header -->\n <div class=\"format-editor-header\">\n <button class=\"back-btn\" (click)=\"CloseFormatEditor()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n </button>\n <div class=\"format-editor-title\">\n <span>Format: {{ FormatEditingColumn.userDisplayName || FormatEditingColumn.displayName }}</span>\n </div>\n </div>\n\n <!-- Column Alias Section -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-pen-nib\"></i>\n <span>Column Name</span>\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <input type=\"text\" class=\"format-input\"\n [value]=\"FormatEditingColumn.userDisplayName || ''\"\n (input)=\"UpdateUserDisplayName($any($event.target).value)\"\n [placeholder]=\"FormatEditingColumn.displayName\" />\n </div>\n @if (FormatEditingColumn.userDisplayName) {\n <div class=\"format-row alias-info\">\n <small class=\"muted-text\">Original: {{ FormatEditingColumn.displayName }}</small>\n <button class=\"clear-alias-btn\" (click)=\"FormatEditingColumn.userDisplayName = undefined\" title=\"Clear alias\" aria-label=\"Clear alias\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Preview Section -->\n <div class=\"format-preview-section\">\n <div class=\"preview-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-table\">\n <div class=\"preview-header-cell\"\n [style.font-weight]=\"FormatEditingColumn.format?.headerStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"FormatEditingColumn.format?.headerStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"FormatEditingColumn.format?.headerStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"FormatEditingColumn.format?.headerStyle?.color\"\n [style.background-color]=\"FormatEditingColumn.format?.headerStyle?.backgroundColor\">\n {{ FormatEditingColumn.userDisplayName || FormatEditingColumn.displayName }}\n </div>\n @for (value of GetSampleValues(FormatEditingColumn); track $index) {\n <div class=\"preview-cell\"\n [style.text-align]=\"FormatEditingColumn.format?.align || 'left'\"\n [style.font-weight]=\"FormatEditingColumn.format?.cellStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"FormatEditingColumn.format?.cellStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"FormatEditingColumn.format?.cellStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"FormatEditingColumn.format?.cellStyle?.color\"\n [style.background-color]=\"FormatEditingColumn.format?.cellStyle?.backgroundColor\">\n {{ FormatPreviewValue(value, FormatEditingColumn.format) }}\n </div>\n }\n </div>\n </div>\n\n <!-- Format Type -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-hashtag\"></i>\n <span>Format Type</span>\n </div>\n <select class=\"format-select\" [(ngModel)]=\"FormatEditingColumn.format!.type\">\n <option value=\"auto\">Auto (Smart Default)</option>\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percent\">Percent</option>\n <option value=\"date\">Date</option>\n <option value=\"datetime\">Date & Time</option>\n <option value=\"boolean\">Boolean</option>\n </select>\n </div>\n\n <!-- Type-Specific Options -->\n @if (FormatEditingColumn.format?.type === 'number' || FormatEditingColumn.format?.type === 'currency' || FormatEditingColumn.format?.type === 'percent') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Number Options</span>\n </div>\n <div class=\"format-row\">\n <label>Decimal Places</label>\n <input type=\"number\" class=\"format-input small\" min=\"0\" max=\"10\"\n [(ngModel)]=\"FormatEditingColumn.format!.decimals\" />\n </div>\n @if (FormatEditingColumn.format?.type === 'currency') {\n <div class=\"format-row\">\n <label>Currency</label>\n <select class=\"format-select\" [(ngModel)]=\"FormatEditingColumn.format!.currencyCode\">\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR (\u20AC)</option>\n <option value=\"GBP\">GBP (\u00A3)</option>\n <option value=\"JPY\">JPY (\u00A5)</option>\n <option value=\"CAD\">CAD ($)</option>\n <option value=\"AUD\">AUD ($)</option>\n </select>\n </div>\n }\n <div class=\"format-row\">\n <label>Thousands Separator</label>\n <input type=\"checkbox\" [(ngModel)]=\"FormatEditingColumn.format!.thousandsSeparator\" />\n </div>\n </div>\n }\n\n @if (FormatEditingColumn.format?.type === 'date' || FormatEditingColumn.format?.type === 'datetime') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span>Date Options</span>\n </div>\n <div class=\"format-row\">\n <label>Format</label>\n <select class=\"format-select\" [(ngModel)]=\"FormatEditingColumn.format!.dateFormat\">\n <option value=\"short\">Short (1/15/25)</option>\n <option value=\"short-weekday\">Short + Day (Wed, 1/15/25)</option>\n <option value=\"medium\">Medium (Jan 15, 2025)</option>\n <option value=\"medium-weekday\">Medium + Day (Wed, Jan 15, 2025)</option>\n <option value=\"long\">Long (January 15, 2025)</option>\n <option value=\"long-weekday\">Long + Day (Wednesday, January 15, 2025)</option>\n </select>\n </div>\n </div>\n }\n\n @if (FormatEditingColumn.format?.type === 'boolean') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n <span>Boolean Options</span>\n </div>\n <div class=\"format-row\">\n <label>True Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"FormatEditingColumn.format!.trueLabel\" placeholder=\"Yes\" />\n </div>\n <div class=\"format-row\">\n <label>False Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"FormatEditingColumn.format!.falseLabel\" placeholder=\"No\" />\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <select class=\"format-select\" [(ngModel)]=\"FormatEditingColumn.format!.booleanDisplay\">\n <option value=\"text\">Text</option>\n <option value=\"checkbox\">Checkbox</option>\n <option value=\"icon\">Icon</option>\n </select>\n </div>\n </div>\n }\n\n <!-- Alignment -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-align-left\"></i>\n <span>Alignment</span>\n </div>\n <div class=\"alignment-toggle\">\n <button class=\"align-btn\" [class.active]=\"FormatEditingColumn.format?.align === 'left' || !FormatEditingColumn.format?.align\"\n (click)=\"FormatEditingColumn.format!.align = 'left'\" title=\"Left\">\n <i class=\"fa-solid fa-align-left\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"FormatEditingColumn.format?.align === 'center'\"\n (click)=\"FormatEditingColumn.format!.align = 'center'\" title=\"Center\">\n <i class=\"fa-solid fa-align-center\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"FormatEditingColumn.format?.align === 'right'\"\n (click)=\"FormatEditingColumn.format!.align = 'right'\" title=\"Right\">\n <i class=\"fa-solid fa-align-right\"></i>\n </button>\n </div>\n </div>\n\n <!-- Header Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-heading\"></i>\n <span>Header Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.headerStyle?.bold\"\n (click)=\"ToggleHeaderStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.headerStyle?.italic\"\n (click)=\"ToggleHeaderStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.headerStyle?.underline\"\n (click)=\"ToggleHeaderStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"FormatEditingColumn.format?.headerStyle?.color || '#000000'\"\n (input)=\"UpdateHeaderColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"FormatEditingColumn.format?.headerStyle?.backgroundColor || '#ffffff'\"\n (input)=\"UpdateHeaderColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Cell Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Cell Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.cellStyle?.bold\"\n (click)=\"ToggleCellStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.cellStyle?.italic\"\n (click)=\"ToggleCellStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"FormatEditingColumn.format?.cellStyle?.underline\"\n (click)=\"ToggleCellStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"FormatEditingColumn.format?.cellStyle?.color || '#000000'\"\n (input)=\"UpdateCellColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"FormatEditingColumn.format?.cellStyle?.backgroundColor || '#ffffff'\"\n (input)=\"UpdateCellColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Clear Format Button -->\n <div class=\"format-actions\">\n <button class=\"clear-format-btn\" (click)=\"ClearColumnFormat(FormatEditingColumn); CloseFormatEditor()\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear Formatting\n </button>\n </div>\n </div>\n }\n\n <!-- Sorting Tab -->\n @if (ActiveTab === 'sorting') {\n <div class=\"tab-content\">\n <div class=\"config-section sorting-section\">\n <div class=\"sorting-header\">\n <p class=\"sorting-description\">\n Define how records should be ordered. Add multiple levels to sort by secondary fields when values are equal.\n </p>\n </div>\n\n <!-- Add Sort Button -->\n <button\n class=\"add-sort-btn\"\n (click)=\"AddSortLevel()\"\n [disabled]=\"!CanEdit || SortItems.length >= SortableFields.length\"\n title=\"Add another sort level\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Sort Level</span>\n </button>\n\n <!-- Sort Items List -->\n @if (SortItems.length > 0) {\n <div class=\"sort-items-list\">\n @for (sortItem of SortItems; track $index; let i = $index) {\n <!-- Drop indicator before -->\n @if (IsSortDropBefore(sortItem)) {\n <div class=\"sort-drop-indicator\"></div>\n }\n <div\n class=\"sort-item\"\n [class.dragging]=\"DraggedSortItem === sortItem\"\n [class.drop-target]=\"DropTargetSortItem === sortItem\"\n draggable=\"true\"\n (dragstart)=\"OnSortDragStart($event, sortItem)\"\n (dragover)=\"OnSortDragOver($event, sortItem)\"\n (dragleave)=\"OnSortDragLeave($event)\"\n (drop)=\"OnSortDrop($event, sortItem)\"\n (dragend)=\"OnSortDragEnd($event)\">\n <!-- Priority Badge -->\n <div class=\"sort-priority-badge\">{{ i + 1 }}</div>\n <!-- Drag Handle -->\n <div class=\"sort-drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <!-- Field Dropdown -->\n <select\n class=\"sort-field-dropdown\"\n [(ngModel)]=\"sortItem.field\"\n (ngModelChange)=\"OnSortFieldChange(sortItem, $event)\"\n [disabled]=\"!CanEdit\">\n @for (field of SortableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ field.DisplayNameOrName }}</option>\n }\n </select>\n <!-- Direction Toggle -->\n <div class=\"sort-direction-toggle\">\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'asc'\"\n (click)=\"OnSortDirectionChange(sortItem, 'asc')\"\n [disabled]=\"!CanEdit\"\n title=\"Ascending (A-Z, 1-9)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'desc'\"\n (click)=\"OnSortDirectionChange(sortItem, 'desc')\"\n [disabled]=\"!CanEdit\"\n title=\"Descending (Z-A, 9-1)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </button>\n </div>\n <!-- Remove Button -->\n <button\n class=\"sort-remove-btn\"\n (click)=\"RemoveSortLevel(sortItem)\"\n [disabled]=\"!CanEdit\"\n title=\"Remove sort level\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (IsSortDropAfter(sortItem) && i === SortItems.length - 1) {\n <div class=\"sort-drop-indicator\"></div>\n }\n }\n </div>\n <!-- Multi-sort hint -->\n @if (SortItems.length > 1) {\n <div class=\"sort-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Drag items to change priority. Records sort by first level, then second, etc.</span>\n </div>\n }\n } @else {\n <div class=\"sort-empty-state\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>No sorting configured</span>\n <p class=\"sort-empty-hint\">Click \"Add Sort Level\" to define how records should be ordered</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Filters Tab -->\n @if (ActiveTab === 'filters') {\n <div class=\"tab-content\">\n <!-- Filter Mode Selection -->\n <div class=\"filter-mode-selector\">\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"FilterMode === 'smart'\"\n (click)=\"SetFilterMode('smart')\"\n [disabled]=\"!CanEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Smart Filter</span>\n <span class=\"mode-subtitle\">Use AI to filter with natural language</span>\n </div>\n @if (FilterMode === 'smart') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"FilterMode === 'traditional'\"\n (click)=\"SetFilterMode('traditional')\"\n [disabled]=\"!CanEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Traditional Filter</span>\n <span class=\"mode-subtitle\">Build filters with field/operator/value</span>\n </div>\n @if (FilterMode === 'traditional') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n </div>\n\n <!-- Smart Filter Section -->\n @if (FilterMode === 'smart') {\n <div class=\"config-section smart-filter-section\">\n <div class=\"smart-filter-input-container\">\n <div class=\"smart-filter-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <textarea\n id=\"SmartFilterPrompt\"\n class=\"smart-filter-textarea\"\n placeholder=\"Describe what you're looking for...\"\n [(ngModel)]=\"SmartFilterPrompt\"\n [disabled]=\"!CanEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n\n @if (SmartFilterExplanation) {\n <div class=\"smart-filter-explanation\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>{{ SmartFilterExplanation }}</span>\n </div>\n }\n\n <!-- Example Prompts -->\n <div class=\"smart-filter-examples\">\n <div class=\"examples-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Try these examples:</span>\n </div>\n <div class=\"example-chips\">\n <button\n class=\"example-chip\"\n (click)=\"ApplySmartFilterExample('Show records created in the last 30 days')\"\n [disabled]=\"!CanEdit\">\n <i class=\"fa-regular fa-calendar\"></i>\n Last 30 days\n </button>\n <button\n class=\"example-chip\"\n (click)=\"ApplySmartFilterExample('Active records only')\"\n [disabled]=\"!CanEdit\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Active only\n </button>\n <button\n class=\"example-chip\"\n (click)=\"ApplySmartFilterExample('Records with high priority')\"\n [disabled]=\"!CanEdit\">\n <i class=\"fa-solid fa-star\"></i>\n High priority\n </button>\n <button\n class=\"example-chip\"\n (click)=\"ApplySmartFilterExample('Records modified this week')\"\n [disabled]=\"!CanEdit\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Modified this week\n </button>\n </div>\n </div>\n\n <div class=\"smart-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>The AI will interpret your description and create the appropriate filter when you save the view.</span>\n </div>\n </div>\n }\n\n <!-- Traditional Filter Section -->\n @if (FilterMode === 'traditional') {\n <div class=\"config-section traditional-filter-section\">\n <div class=\"filter-summary-container\">\n <div class=\"filter-summary\">\n <div class=\"summary-info\">\n @if (GetFilterCount() > 0) {\n <span class=\"filter-badge\">{{ GetFilterCount() }}</span>\n <span class=\"summary-text\">{{ GetFilterSummary() }}</span>\n } @else {\n <span class=\"summary-text no-filters\">No filters configured</span>\n }\n </div>\n <div class=\"summary-actions\">\n @if (GetFilterCount() > 0 && CanEdit) {\n <button\n class=\"summary-btn clear-btn\"\n (click)=\"ClearFilters()\"\n title=\"Clear all filters\">\n <i class=\"fa-solid fa-times\"></i>\n Clear\n </button>\n }\n <button\n class=\"summary-btn edit-btn primary\"\n (click)=\"OpenFilterDialog()\"\n [disabled]=\"!CanEdit && GetFilterCount() === 0\"\n title=\"Edit filters\">\n <i class=\"fa-solid fa-pen\"></i>\n {{ GetFilterCount() > 0 ? 'Edit Filters' : 'Add Filters' }}\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"traditional-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Build precise filters by selecting fields, operators, and values. Use groups for complex AND/OR logic.</span>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Aggregates Tab -->\n @if (ActiveTab === 'aggregates') {\n <div class=\"tab-content\">\n <div class=\"config-section aggregates-section\">\n <div class=\"aggregates-header\">\n <p class=\"aggregates-description\">\n Add summary calculations like totals, averages, and counts. Display them in cards or as column footers.\n </p>\n </div>\n\n <!-- Add Aggregate Button -->\n <button\n class=\"add-aggregate-btn\"\n (click)=\"OpenAddAggregateDialog()\"\n [disabled]=\"!CanEdit\"\n title=\"Add a new aggregate\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Aggregate</span>\n </button>\n\n <!-- Aggregates List -->\n @if (Aggregates.length > 0) {\n <div class=\"aggregates-list\">\n @for (agg of Aggregates; track agg.id; let i = $index) {\n <div class=\"aggregate-item\" [class.disabled]=\"agg.enabled === false\">\n <!-- Icon -->\n <div class=\"agg-icon\">\n <i [class]=\"agg.icon || 'fa-solid fa-chart-simple'\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"agg-content\">\n <div class=\"agg-label\">{{ agg.label }}</div>\n <div class=\"agg-details\">\n <span class=\"agg-type\">\n <i [class]=\"agg.displayType === 'card' ? 'fa-solid fa-id-card' : 'fa-solid fa-table-columns'\"></i>\n {{ agg.displayType === 'card' ? 'Card' : 'Column Footer' }}\n </span>\n @if (agg.smartPrompt) {\n <span class=\"agg-smart-badge\" title=\"AI-generated\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"agg-actions\">\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === 0 || !CanEdit\"\n (click)=\"MoveAggregateUp(agg)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === Aggregates.length - 1 || !CanEdit\"\n (click)=\"MoveAggregateDown(agg)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"agg-action-btn toggle-btn\"\n [class.enabled]=\"agg.enabled !== false\"\n (click)=\"ToggleAggregateEnabled(agg, $event)\"\n [disabled]=\"!CanEdit\"\n [title]=\"agg.enabled !== false ? 'Disable' : 'Enable'\">\n <i [class]=\"agg.enabled !== false ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'\"></i>\n </button>\n <button\n class=\"agg-action-btn edit-btn\"\n (click)=\"EditAggregate(agg)\"\n [disabled]=\"!CanEdit\"\n title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button\n class=\"agg-action-btn remove-btn\"\n (click)=\"RemoveAggregate(agg)\"\n [disabled]=\"!CanEdit\"\n title=\"Remove\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Summary -->\n <div class=\"aggregates-summary\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>{{ CardAggregates.length }} card{{ CardAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>{{ ColumnAggregates.length }} column footer{{ ColumnAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n </div>\n } @else {\n <div class=\"aggregates-empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>No aggregates configured</span>\n <p class=\"empty-hint\">Click \"Add Aggregate\" to create summary calculations</p>\n </div>\n }\n\n <!-- Info Tip -->\n <div class=\"aggregates-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Aggregates are calculated server-side for accuracy with filtered/paginated data.</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Settings Tab -->\n @if (ActiveTab === 'settings') {\n <div class=\"tab-content\">\n <!-- View Name & Description -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>View Details</span>\n </div>\n <div class=\"form-group\">\n <label for=\"ViewName\">Name</label>\n <input\n id=\"ViewName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"!ViewName || !ViewName.trim()\"\n placeholder=\"Enter view name...\"\n [(ngModel)]=\"ViewName\"\n [disabled]=\"!CanEdit\"\n />\n @if (!ViewName || !ViewName.trim()) {\n <span class=\"validation-error\">View name is required</span>\n }\n </div>\n <div class=\"form-group\">\n <label for=\"ViewDescription\">Description</label>\n <textarea\n id=\"ViewDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"Describe this view...\"\n [(ngModel)]=\"ViewDescription\"\n [disabled]=\"!CanEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n </div>\n\n <!-- Sharing -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-share-alt\"></i>\n <span>Sharing</span>\n </div>\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"IsShared\"\n [disabled]=\"!CanEdit\"\n />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n </div>\n\n <!-- Danger Zone -->\n @if (ViewEntity && CanDelete) {\n <div class=\"config-section danger-zone\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Danger Zone</span>\n </div>\n <button class=\"delete-btn\" (click)=\"OnDelete()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span>Delete View</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Validation Errors Banner -->\n @if (ValidationErrors.length > 0 && VisibleColumns.length === 0) {\n <div class=\"validation-banner\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>At least one column must be visible</span>\n </div>\n }\n\n <!-- Panel Footer -->\n <div class=\"panel-footer\">\n <!-- Action buttons on LEFT -->\n <div class=\"footer-left\">\n @if (ViewEntity && CanEdit) {\n <!-- Editing an existing saved view -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"OnSave()\"\n [disabled]=\"IsSaving || !IsValid\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n @if (!ViewEntity && DefaultSaveAsNew) {\n <!-- Creating a new view (from quick Save dialog) -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"OnSaveAsNew()\"\n [disabled]=\"IsSaving || !IsValidForSaveAsNew\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n @if (!ViewEntity && !DefaultSaveAsNew) {\n <!-- Default/Dynamic view - Save to user settings -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"OnSaveDefaults()\"\n [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n </div>\n <!-- Cancel button on RIGHT -->\n <button class=\"footer-btn cancel-btn\" (click)=\"OnClose()\">\n Cancel\n </button>\n </div>\n</div>\n\n<!-- Aggregate Setup Dialog -->\n<mj-aggregate-setup-dialog\n [Entity]=\"Entity\"\n [Aggregate]=\"EditingAggregate\"\n [IsOpen]=\"ShowAggregateDialog\"\n (Close)=\"CloseAggregateDialog()\"\n (Save)=\"OnAggregateSave($event)\">\n</mj-aggregate-setup-dialog>\n\n<!-- Delete Confirmation Dialog -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"ShowDeleteConfirm\"\n Title=\"Delete View\"\n [Message]=\"'Are you sure you want to delete \\'' + ViewName + '\\'?'\"\n DetailMessage=\"This action cannot be undone. All users who have access to this view will lose it.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"OnDeleteConfirmed()\"\n (Cancelled)=\"OnDeleteCancelled()\">\n</mj-ev-confirm-dialog>\n\n<!-- Filter Mode Switch Confirmation Dialog (BUG-006) -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"ShowFilterModeSwitchConfirm\"\n Title=\"Switch Filter Mode\"\n [Message]=\"FilterMode === 'smart' ? 'Switching to Traditional mode will clear your smart filter prompt.' : 'Switching to Smart mode will clear your traditional filter rules.'\"\n DetailMessage=\"You can switch back later, but the current filter data will be lost.\"\n ConfirmText=\"Switch\"\n ConfirmStyle=\"primary\"\n Icon=\"fa-solid fa-exchange-alt\"\n (Confirmed)=\"OnFilterModeSwitchConfirmed()\"\n (Cancelled)=\"OnFilterModeSwitchCancelled()\">\n</mj-ev-confirm-dialog>\n", styles: ["/* Backdrop */\n.panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1200; /* Above Leaflet map (1000), content-header (1100) */\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Sliding Panel */\n.config-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1201; /* Above backdrop (1200) */\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open {\n transform: translateX(0);\n}\n\n.config-panel.resizing {\n transition: none;\n user-select: none;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle:hover,\n.config-panel.resizing .resize-handle {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle:hover .resize-grip,\n.config-panel.resizing .resize-grip {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n transition: all 0.15s ease;\n position: relative;\n white-space: nowrap;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.tab-btn.active::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 8px;\n right: 8px;\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 2px 2px 0 0;\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n}\n\n/* Icon-only mode for narrow panel */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.tab-content {\n padding: 16px;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 20px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.column-count {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 13px;\n background: transparent;\n color: var(--mj-text-primary);\n}\n\n.column-search input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Column List */\n.column-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n/* Column Item */\n.column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n transition: background 0.15s ease;\n cursor: default;\n}\n\n.column-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.column-item.hidden {\n opacity: 0.7;\n}\n\n.column-item.hidden:hover {\n opacity: 1;\n}\n\n.column-item.dragging {\n opacity: 0.4;\n}\n\n.column-item.drop-target {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Drop Indicator */\n.drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Drag Handle */\n.drag-handle {\n display: flex;\n align-items: center;\n cursor: grab;\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px 2px;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.column-item:hover .drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Column Name */\n.column-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.alias-indicator {\n font-size: 10px;\n color: var(--mj-brand-primary);\n margin-left: 4px;\n}\n\n.format-indicator {\n font-size: 10px;\n color: var(--mj-status-warning);\n margin-left: 4px;\n}\n\n/* Column Actions */\n.column-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.column-item:hover .column-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.action-btn.show-btn {\n opacity: 0;\n}\n\n.column-item:hover .action-btn.show-btn {\n opacity: 1;\n}\n\n.action-btn.show-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.action-btn.format-btn:hover {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n/* Empty List */\n.empty-list {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.empty-list i {\n color: var(--mj-text-disabled);\n}\n\n/* Format Editor */\n.format-editor {\n padding: 0;\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.back-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.format-editor-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Format Sections */\n.format-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.format-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.format-section-header i {\n color: var(--mj-text-muted);\n}\n\n/* Format Rows */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.format-row.alias-info {\n padding: 4px 0;\n}\n\n.muted-text {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.clear-alias-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n color: var(--mj-status-error);\n}\n\n/* Format Input */\n.format-input {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n}\n\n.format-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.format-input.small {\n width: 60px;\n text-align: center;\n}\n\n.format-select {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n}\n\n.format-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Color Input */\n.color-input {\n width: 36px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.align-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 4px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.style-btn:hover {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.style-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Format Preview */\n.format-preview-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.preview-header i {\n color: var(--mj-text-muted);\n}\n\n.preview-table {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.preview-header-cell {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.preview-cell {\n padding: 8px 12px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-cell:last-child {\n border-bottom: none;\n}\n\n/* Format Actions */\n.format-actions {\n padding: 16px;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n/* Sorting Section */\n.sorting-section {\n padding: 0;\n}\n\n.sorting-header {\n margin-bottom: 12px;\n}\n\n.sorting-description,\n.aggregates-description {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n\n/* Add Sort Button */\n.add-sort-btn,\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n width: 100%;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled),\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-sort-btn:disabled,\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.sort-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.sort-item.dragging {\n opacity: 0.4;\n}\n\n.sort-item.drop-target {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Sort Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n/* Sort Drag Handle */\n.sort-drag-handle {\n cursor: grab;\n color: var(--mj-text-disabled);\n padding: 2px;\n font-size: 12px;\n}\n\n.sort-drag-handle:active {\n cursor: grabbing;\n}\n\n.sort-item:hover .sort-drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n min-width: 0;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Sort Direction Toggle */\n.sort-direction-toggle {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n}\n\n.direction-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover:not(:disabled) {\n color: var(--mj-text-secondary);\n}\n\n.direction-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.direction-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Remove Button */\n.sort-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Hint */\n.sort-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.sort-hint i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Sort Empty State */\n.sort-empty-state,\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.sort-empty-state i,\n.aggregates-empty-state i {\n font-size: 32px;\n opacity: 0.4;\n}\n\n.sort-empty-state span,\n.aggregates-empty-state span {\n font-size: 14px;\n font-weight: 500;\n}\n\n.sort-empty-hint,\n.empty-hint {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-disabled);\n}\n\n/* Filter Mode Selector */\n.filter-mode-selector {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.filter-mode-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mode-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n font-size: 16px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mode-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.mode-check {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n/* Smart Filter Section */\n.smart-filter-section {\n padding: 0;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n margin-bottom: 12px;\n}\n\n.smart-filter-icon {\n display: flex;\n align-items: flex-start;\n padding-top: 4px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.smart-filter-textarea {\n flex: 1;\n border: none;\n outline: none;\n resize: vertical;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n min-height: 60px;\n}\n\n.smart-filter-textarea::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.smart-filter-textarea:disabled {\n color: var(--mj-text-muted);\n}\n\n/* Smart Filter Explanation */\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n color: var(--mj-brand-primary);\n}\n\n.smart-filter-explanation i {\n margin-top: 2px;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 12px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.examples-header i {\n color: var(--mj-status-warning);\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.example-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.example-chip:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip i {\n font-size: 11px;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip,\n.traditional-filter-tip,\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 12px;\n}\n\n.smart-filter-tip i,\n.traditional-filter-tip i,\n.aggregates-tip i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Traditional Filter Section */\n.traditional-filter-section {\n padding: 0;\n}\n\n.filter-summary-container {\n margin-bottom: 12px;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 11px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.summary-text {\n font-size: 13px;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.summary-text.no-filters {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.summary-actions {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.summary-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn.clear-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n.summary-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.summary-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* Aggregates Section */\n.aggregates-section {\n padding: 0;\n}\n\n.aggregates-header {\n margin-bottom: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.aggregate-item.disabled {\n opacity: 0.5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.agg-smart-badge {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.aggregate-item:hover .agg-actions {\n opacity: 1;\n}\n\n.agg-action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.agg-action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled {\n color: var(--mj-brand-primary);\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-bottom: 12px;\n}\n\n.aggregates-summary .summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.aggregates-summary .summary-item i {\n color: var(--mj-text-disabled);\n}\n\n/* Settings Tab */\n.form-group {\n margin-bottom: 16px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.form-input.invalid {\n border-color: var(--mj-status-error);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 60px;\n font-family: inherit;\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n margin-top: 4px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Danger Zone */\n.danger-zone .section-header {\n color: var(--mj-status-error);\n}\n\n.danger-zone .section-header i {\n color: var(--mj-status-error);\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n background: var(--mj-status-error-bg);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-status-error);\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n/* Validation Banner */\n.validation-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error-bg);\n border-top: 1px solid var(--mj-status-error);\n font-size: 13px;\n color: var(--mj-status-error);\n flex-shrink: 0;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 18px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.footer-btn.cancel-btn {\n background: var(--mj-bg-surface-card);\n}\n\n.footer-btn.cancel-btn:hover {\n background: var(--mj-bg-surface-active);\n}\n\n/* Responsive */\n@media (max-width: 480px) {\n .config-panel {\n width: 100vw;\n min-width: auto;\n }\n\n .resize-handle {\n display: none;\n }\n}\n"] }]
|
|
2859
|
+
}], () => [{ type: i0.ChangeDetectorRef }], { Entity: [{
|
|
2860
2860
|
type: Input
|
|
2861
|
-
}],
|
|
2861
|
+
}], ViewEntity: [{
|
|
2862
2862
|
type: Input
|
|
2863
|
-
}],
|
|
2863
|
+
}], IsOpen: [{
|
|
2864
2864
|
type: Input
|
|
2865
|
-
}],
|
|
2865
|
+
}], CurrentGridState: [{
|
|
2866
2866
|
type: Input
|
|
2867
|
-
}],
|
|
2867
|
+
}], SampleData: [{
|
|
2868
2868
|
type: Input
|
|
2869
|
-
}],
|
|
2869
|
+
}], Close: [{
|
|
2870
2870
|
type: Output
|
|
2871
|
-
}],
|
|
2871
|
+
}], Save: [{
|
|
2872
2872
|
type: Output
|
|
2873
|
-
}],
|
|
2873
|
+
}], SaveDefaults: [{
|
|
2874
2874
|
type: Output
|
|
2875
|
-
}],
|
|
2875
|
+
}], Delete: [{
|
|
2876
2876
|
type: Output
|
|
2877
|
-
}],
|
|
2877
|
+
}], OpenFilterDialogRequest: [{
|
|
2878
2878
|
type: Output
|
|
2879
|
-
}],
|
|
2879
|
+
}], ExternalFilterState: [{
|
|
2880
2880
|
type: Input
|
|
2881
2881
|
}], DefaultSaveAsNew: [{
|
|
2882
2882
|
type: Input
|
|
@@ -2886,11 +2886,11 @@ export class ViewConfigPanelComponent extends BaseAngularComponent {
|
|
|
2886
2886
|
type: Input
|
|
2887
2887
|
}], PendingNewViewIsShared: [{
|
|
2888
2888
|
type: Input
|
|
2889
|
-
}],
|
|
2889
|
+
}], Duplicate: [{
|
|
2890
2890
|
type: Output
|
|
2891
|
-
}],
|
|
2891
|
+
}], IsSaving: [{
|
|
2892
2892
|
type: Input
|
|
2893
|
-
}],
|
|
2893
|
+
}], HandleEscape: [{
|
|
2894
2894
|
type: HostListener,
|
|
2895
2895
|
args: ['document:keydown.escape']
|
|
2896
2896
|
}] }); })();
|