@memberjunction/ng-entity-viewer 3.1.1 → 3.3.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.
Files changed (35) hide show
  1. package/dist/lib/aggregate-panel/aggregate-panel.component.d.ts +118 -0
  2. package/dist/lib/aggregate-panel/aggregate-panel.component.d.ts.map +1 -0
  3. package/dist/lib/aggregate-panel/aggregate-panel.component.js +366 -0
  4. package/dist/lib/aggregate-panel/aggregate-panel.component.js.map +1 -0
  5. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts +196 -0
  6. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts.map +1 -0
  7. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +948 -0
  8. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js.map +1 -0
  9. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +134 -8
  10. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  11. package/dist/lib/entity-data-grid/entity-data-grid.component.js +769 -150
  12. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  13. package/dist/lib/entity-data-grid/models/grid-types.d.ts +15 -1
  14. package/dist/lib/entity-data-grid/models/grid-types.d.ts.map +1 -1
  15. package/dist/lib/entity-data-grid/models/grid-types.js.map +1 -1
  16. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +12 -3
  17. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  18. package/dist/lib/entity-viewer/entity-viewer.component.js +29 -4
  19. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  20. package/dist/lib/types.d.ts +9 -21
  21. package/dist/lib/types.d.ts.map +1 -1
  22. package/dist/lib/types.js.map +1 -1
  23. package/dist/lib/view-config-panel/view-config-panel.component.d.ts +71 -3
  24. package/dist/lib/view-config-panel/view-config-panel.component.d.ts.map +1 -1
  25. package/dist/lib/view-config-panel/view-config-panel.component.js +726 -320
  26. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  27. package/dist/module.d.ts +9 -7
  28. package/dist/module.d.ts.map +1 -1
  29. package/dist/module.js +14 -4
  30. package/dist/module.js.map +1 -1
  31. package/dist/public-api.d.ts +2 -0
  32. package/dist/public-api.d.ts.map +1 -1
  33. package/dist/public-api.js +4 -0
  34. package/dist/public-api.js.map +1 -1
  35. package/package.json +9 -9
@@ -0,0 +1,948 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/forms";
4
+ const _forTrack0 = ($index, $item) => $item.value;
5
+ const _forTrack1 = ($index, $item) => $item.ID;
6
+ function AggregateSetupDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
7
+ const _r1 = i0.ɵɵgetCurrentView();
8
+ i0.ɵɵelementStart(0, "div", 40);
9
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onClose()); });
10
+ i0.ɵɵelementEnd();
11
+ } }
12
+ function AggregateSetupDialogComponent_Conditional_23_For_10_Template(rf, ctx) { if (rf & 1) {
13
+ const _r4 = i0.ɵɵgetCurrentView();
14
+ i0.ɵɵelementStart(0, "button", 51);
15
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_23_For_10_Template_button_click_0_listener() { const func_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectFunction(func_r5.value)); });
16
+ i0.ɵɵelement(1, "i");
17
+ i0.ɵɵelementStart(2, "span");
18
+ i0.ɵɵtext(3);
19
+ i0.ɵɵelementEnd()();
20
+ } if (rf & 2) {
21
+ const func_r5 = ctx.$implicit;
22
+ const ctx_r1 = i0.ɵɵnextContext(2);
23
+ i0.ɵɵclassProp("active", ctx_r1.SelectedFunction === func_r5.value);
24
+ i0.ɵɵproperty("title", func_r5.label);
25
+ i0.ɵɵadvance();
26
+ i0.ɵɵclassMap(func_r5.icon);
27
+ i0.ɵɵadvance(2);
28
+ i0.ɵɵtextInterpolate(func_r5.label);
29
+ } }
30
+ function AggregateSetupDialogComponent_Conditional_23_For_18_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelementStart(0, "option", 47);
32
+ i0.ɵɵtext(1);
33
+ i0.ɵɵelementEnd();
34
+ } if (rf & 2) {
35
+ const field_r6 = ctx.$implicit;
36
+ const ctx_r1 = i0.ɵɵnextContext(2);
37
+ i0.ɵɵproperty("value", field_r6.Name);
38
+ i0.ɵɵadvance();
39
+ i0.ɵɵtextInterpolate(ctx_r1.getFieldDisplayLabel(field_r6));
40
+ } }
41
+ function AggregateSetupDialogComponent_Conditional_23_Conditional_19_Template(rf, ctx) { if (rf & 1) {
42
+ i0.ɵɵelementStart(0, "div", 48);
43
+ i0.ɵɵelement(1, "i", 52);
44
+ i0.ɵɵelementStart(2, "span");
45
+ i0.ɵɵtext(3, "No numeric fields available. Use COUNT or switch to Advanced mode.");
46
+ i0.ɵɵelementEnd()();
47
+ } }
48
+ function AggregateSetupDialogComponent_Conditional_23_Conditional_20_Template(rf, ctx) { if (rf & 1) {
49
+ i0.ɵɵelementStart(0, "div", 49);
50
+ i0.ɵɵelement(1, "i", 42);
51
+ i0.ɵɵelementStart(2, "span");
52
+ i0.ɵɵtext(3, "No column selected - will count all records (COUNT(*))");
53
+ i0.ɵɵelementEnd()();
54
+ } }
55
+ function AggregateSetupDialogComponent_Conditional_23_Conditional_21_Template(rf, ctx) { if (rf & 1) {
56
+ i0.ɵɵelementStart(0, "div", 50)(1, "label", 53);
57
+ i0.ɵɵtext(2, "Expression Preview");
58
+ i0.ɵɵelementEnd();
59
+ i0.ɵɵelementStart(3, "code", 54);
60
+ i0.ɵɵtext(4);
61
+ i0.ɵɵelementEnd()();
62
+ } if (rf & 2) {
63
+ const ctx_r1 = i0.ɵɵnextContext(2);
64
+ i0.ɵɵadvance(4);
65
+ i0.ɵɵtextInterpolate(!ctx_r1.SelectedColumn && ctx_r1.SelectedFunction === "COUNT" ? "COUNT(*)" : ctx_r1.SelectedFunction === "COUNT_DISTINCT" ? "COUNT(DISTINCT " + ctx_r1.SelectedColumn + ")" : ctx_r1.SelectedFunction + "(" + ctx_r1.SelectedColumn + ")");
66
+ } }
67
+ function AggregateSetupDialogComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
68
+ const _r3 = i0.ɵɵgetCurrentView();
69
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 41);
70
+ i0.ɵɵelement(2, "i", 42);
71
+ i0.ɵɵelementStart(3, "span");
72
+ i0.ɵɵtext(4, "Select a column and an aggregate function to calculate");
73
+ i0.ɵɵelementEnd()();
74
+ i0.ɵɵelementStart(5, "div", 20)(6, "label", 23);
75
+ i0.ɵɵtext(7, "Function");
76
+ i0.ɵɵelementEnd();
77
+ i0.ɵɵelementStart(8, "div", 43);
78
+ i0.ɵɵrepeaterCreate(9, AggregateSetupDialogComponent_Conditional_23_For_10_Template, 4, 6, "button", 44, _forTrack0);
79
+ i0.ɵɵelementEnd()();
80
+ i0.ɵɵelementStart(11, "div", 20)(12, "label", 23);
81
+ i0.ɵɵtext(13, "Column");
82
+ i0.ɵɵelementEnd();
83
+ i0.ɵɵelementStart(14, "select", 45);
84
+ i0.ɵɵtwoWayListener("ngModelChange", function AggregateSetupDialogComponent_Conditional_23_Template_select_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedColumn, $event) || (ctx_r1.SelectedColumn = $event); return i0.ɵɵresetView($event); });
85
+ i0.ɵɵlistener("ngModelChange", function AggregateSetupDialogComponent_Conditional_23_Template_select_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onColumnSelected($event)); });
86
+ i0.ɵɵelementStart(15, "option", 46);
87
+ i0.ɵɵtext(16, "Select a column...");
88
+ i0.ɵɵelementEnd();
89
+ i0.ɵɵrepeaterCreate(17, AggregateSetupDialogComponent_Conditional_23_For_18_Template, 2, 2, "option", 47, _forTrack1);
90
+ i0.ɵɵelementEnd();
91
+ i0.ɵɵtemplate(19, AggregateSetupDialogComponent_Conditional_23_Conditional_19_Template, 4, 0, "div", 48)(20, AggregateSetupDialogComponent_Conditional_23_Conditional_20_Template, 4, 0, "div", 49);
92
+ i0.ɵɵelementEnd();
93
+ i0.ɵɵtemplate(21, AggregateSetupDialogComponent_Conditional_23_Conditional_21_Template, 5, 1, "div", 50);
94
+ i0.ɵɵelementEnd();
95
+ } if (rf & 2) {
96
+ const ctx_r1 = i0.ɵɵnextContext();
97
+ i0.ɵɵadvance(9);
98
+ i0.ɵɵrepeater(ctx_r1.AggregateFunctions);
99
+ i0.ɵɵadvance(5);
100
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SelectedColumn);
101
+ i0.ɵɵadvance(3);
102
+ i0.ɵɵrepeater(ctx_r1.AvailableFields);
103
+ i0.ɵɵadvance(2);
104
+ i0.ɵɵconditional(ctx_r1.SelectedFunction !== "COUNT" && ctx_r1.SelectedFunction !== "COUNT_DISTINCT" && ctx_r1.NumericFields.length === 0 ? 19 : -1);
105
+ i0.ɵɵadvance();
106
+ i0.ɵɵconditional(ctx_r1.SelectedFunction === "COUNT" && !ctx_r1.SelectedColumn ? 20 : -1);
107
+ i0.ɵɵadvance();
108
+ i0.ɵɵconditional(ctx_r1.SelectedFunction && (ctx_r1.SelectedColumn || ctx_r1.SelectedFunction === "COUNT") ? 21 : -1);
109
+ } }
110
+ function AggregateSetupDialogComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
111
+ const _r7 = i0.ɵɵgetCurrentView();
112
+ i0.ɵɵelementStart(0, "div", 16)(1, "div", 41);
113
+ i0.ɵɵelement(2, "i", 42);
114
+ i0.ɵɵelementStart(3, "span");
115
+ i0.ɵɵtext(4, "Write a custom SQL aggregate expression. Use field names as they appear in the database.");
116
+ i0.ɵɵelementEnd()();
117
+ i0.ɵɵelementStart(5, "div", 20)(6, "label", 23);
118
+ i0.ɵɵtext(7, "SQL Expression");
119
+ i0.ɵɵelementEnd();
120
+ i0.ɵɵelementStart(8, "textarea", 55);
121
+ i0.ɵɵtwoWayListener("ngModelChange", function AggregateSetupDialogComponent_Conditional_24_Template_textarea_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.Expression, $event) || (ctx_r1.Expression = $event); return i0.ɵɵresetView($event); });
122
+ i0.ɵɵelementEnd();
123
+ i0.ɵɵelementStart(9, "div", 56);
124
+ i0.ɵɵelement(10, "i", 57);
125
+ i0.ɵɵelementStart(11, "span");
126
+ i0.ɵɵtext(12, "Tip: Use brackets for column names with spaces, e.g., [Total Amount]");
127
+ i0.ɵɵelementEnd()()();
128
+ i0.ɵɵelementStart(13, "div", 20)(14, "label", 58);
129
+ i0.ɵɵtext(15, "Quick Examples");
130
+ i0.ɵɵelementEnd();
131
+ i0.ɵɵelementStart(16, "div", 59)(17, "button", 60);
132
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_24_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Expression = "SUM(Amount)"); });
133
+ i0.ɵɵtext(18, " SUM(Amount) ");
134
+ i0.ɵɵelementEnd();
135
+ i0.ɵɵelementStart(19, "button", 60);
136
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_24_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Expression = "AVG(Price * Quantity)"); });
137
+ i0.ɵɵtext(20, " AVG(Price * Quantity) ");
138
+ i0.ɵɵelementEnd();
139
+ i0.ɵɵelementStart(21, "button", 60);
140
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_24_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Expression = "COUNT(CASE WHEN Status = 'Active' THEN 1 END)"); });
141
+ i0.ɵɵtext(22, " COUNT with condition ");
142
+ i0.ɵɵelementEnd();
143
+ i0.ɵɵelementStart(23, "button", 60);
144
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_24_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Expression = "SUM(CASE WHEN Type = 'Credit' THEN Amount ELSE -Amount END)"); });
145
+ i0.ɵɵtext(24, " Conditional SUM ");
146
+ i0.ɵɵelementEnd()()()();
147
+ } if (rf & 2) {
148
+ const ctx_r1 = i0.ɵɵnextContext();
149
+ i0.ɵɵadvance(8);
150
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.Expression);
151
+ } }
152
+ function AggregateSetupDialogComponent_Conditional_25_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵelement(0, "i", 69);
154
+ i0.ɵɵelementStart(1, "span");
155
+ i0.ɵɵtext(2, "Generating...");
156
+ i0.ɵɵelementEnd();
157
+ } }
158
+ function AggregateSetupDialogComponent_Conditional_25_Conditional_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
159
+ i0.ɵɵelement(0, "i", 13);
160
+ i0.ɵɵelementStart(1, "span");
161
+ i0.ɵɵtext(2, "Generate");
162
+ i0.ɵɵelementEnd();
163
+ } }
164
+ function AggregateSetupDialogComponent_Conditional_25_Conditional_10_Template(rf, ctx) { if (rf & 1) {
165
+ const _r9 = i0.ɵɵgetCurrentView();
166
+ i0.ɵɵelementStart(0, "button", 68);
167
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_25_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onGenerateFromPrompt()); });
168
+ i0.ɵɵtemplate(1, AggregateSetupDialogComponent_Conditional_25_Conditional_10_Conditional_1_Template, 3, 0)(2, AggregateSetupDialogComponent_Conditional_25_Conditional_10_Conditional_2_Template, 3, 0);
169
+ i0.ɵɵelementEnd();
170
+ } if (rf & 2) {
171
+ const ctx_r1 = i0.ɵɵnextContext(2);
172
+ i0.ɵɵproperty("disabled", !ctx_r1.SmartPrompt.trim() || ctx_r1.IsGenerating);
173
+ i0.ɵɵadvance();
174
+ i0.ɵɵconditional(ctx_r1.IsGenerating ? 1 : 2);
175
+ } }
176
+ function AggregateSetupDialogComponent_Conditional_25_Conditional_11_Template(rf, ctx) { if (rf & 1) {
177
+ const _r10 = i0.ɵɵgetCurrentView();
178
+ i0.ɵɵelementStart(0, "div", 64)(1, "div", 70)(2, "label", 23);
179
+ i0.ɵɵtext(3, "Generated Expression");
180
+ i0.ɵɵelementEnd();
181
+ i0.ɵɵelementStart(4, "button", 71);
182
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_25_Conditional_11_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearGeneratedExpression()); });
183
+ i0.ɵɵelement(5, "i", 72);
184
+ i0.ɵɵelementStart(6, "span");
185
+ i0.ɵɵtext(7, "Edit Prompt");
186
+ i0.ɵɵelementEnd()()();
187
+ i0.ɵɵelementStart(8, "code", 73);
188
+ i0.ɵɵtext(9);
189
+ i0.ɵɵelementEnd();
190
+ i0.ɵɵelementStart(10, "div", 74);
191
+ i0.ɵɵelement(11, "i", 42);
192
+ i0.ɵɵelementStart(12, "span");
193
+ i0.ɵɵtext(13, "This expression was generated from your description. Clear it to edit the prompt.");
194
+ i0.ɵɵelementEnd()()();
195
+ } if (rf & 2) {
196
+ const ctx_r1 = i0.ɵɵnextContext(2);
197
+ i0.ɵɵadvance(9);
198
+ i0.ɵɵtextInterpolate(ctx_r1.GeneratedExpression);
199
+ } }
200
+ function AggregateSetupDialogComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
201
+ const _r8 = i0.ɵɵgetCurrentView();
202
+ i0.ɵɵelementStart(0, "div", 17)(1, "div", 41);
203
+ i0.ɵɵelement(2, "i", 13);
204
+ i0.ɵɵelementStart(3, "span");
205
+ i0.ɵɵtext(4, "Describe what you want to calculate in plain English. AI will generate the expression.");
206
+ i0.ɵɵelementEnd()();
207
+ i0.ɵɵelementStart(5, "div", 20)(6, "label", 23);
208
+ i0.ɵɵtext(7, "What would you like to calculate?");
209
+ i0.ɵɵelementEnd();
210
+ i0.ɵɵelementStart(8, "div", 61)(9, "textarea", 62);
211
+ i0.ɵɵtwoWayListener("ngModelChange", function AggregateSetupDialogComponent_Conditional_25_Template_textarea_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SmartPrompt, $event) || (ctx_r1.SmartPrompt = $event); return i0.ɵɵresetView($event); });
212
+ i0.ɵɵelementEnd();
213
+ i0.ɵɵtemplate(10, AggregateSetupDialogComponent_Conditional_25_Conditional_10_Template, 3, 2, "button", 63);
214
+ i0.ɵɵelementEnd()();
215
+ i0.ɵɵtemplate(11, AggregateSetupDialogComponent_Conditional_25_Conditional_11_Template, 14, 1, "div", 64);
216
+ i0.ɵɵelementStart(12, "div", 65)(13, "div", 66);
217
+ i0.ɵɵelement(14, "i", 57);
218
+ i0.ɵɵelementStart(15, "span");
219
+ i0.ɵɵtext(16, "Tips for better results:");
220
+ i0.ɵɵelementEnd()();
221
+ i0.ɵɵelementStart(17, "ul", 67)(18, "li");
222
+ i0.ɵɵtext(19, "Be specific about which fields to use");
223
+ i0.ɵɵelementEnd();
224
+ i0.ɵɵelementStart(20, "li");
225
+ i0.ɵɵtext(21, "Mention any conditions or filters");
226
+ i0.ɵɵelementEnd();
227
+ i0.ɵɵelementStart(22, "li");
228
+ i0.ɵɵtext(23, "Specify the type of calculation (sum, average, count, etc.)");
229
+ i0.ɵɵelementEnd()()()();
230
+ } if (rf & 2) {
231
+ const ctx_r1 = i0.ɵɵnextContext();
232
+ i0.ɵɵadvance(9);
233
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SmartPrompt);
234
+ i0.ɵɵproperty("disabled", !!ctx_r1.GeneratedExpression);
235
+ i0.ɵɵadvance();
236
+ i0.ɵɵconditional(!ctx_r1.GeneratedExpression ? 10 : -1);
237
+ i0.ɵɵadvance();
238
+ i0.ɵɵconditional(ctx_r1.GeneratedExpression ? 11 : -1);
239
+ } }
240
+ function AggregateSetupDialogComponent_Conditional_62_Template(rf, ctx) { if (rf & 1) {
241
+ const _r11 = i0.ɵɵgetCurrentView();
242
+ i0.ɵɵelementStart(0, "div", 31);
243
+ i0.ɵɵelement(1, "i");
244
+ i0.ɵɵelementStart(2, "button", 75);
245
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Conditional_62_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.clearIcon()); });
246
+ i0.ɵɵelement(3, "i", 6);
247
+ i0.ɵɵelementEnd()();
248
+ } if (rf & 2) {
249
+ const ctx_r1 = i0.ɵɵnextContext();
250
+ i0.ɵɵadvance();
251
+ i0.ɵɵclassMap(ctx_r1.Icon);
252
+ } }
253
+ function AggregateSetupDialogComponent_For_65_Template(rf, ctx) { if (rf & 1) {
254
+ const _r12 = i0.ɵɵgetCurrentView();
255
+ i0.ɵɵelementStart(0, "button", 76);
256
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_For_65_Template_button_click_0_listener() { const icon_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.selectIcon(icon_r13)); });
257
+ i0.ɵɵelement(1, "i");
258
+ i0.ɵɵelementEnd();
259
+ } if (rf & 2) {
260
+ const icon_r13 = ctx.$implicit;
261
+ const ctx_r1 = i0.ɵɵnextContext();
262
+ i0.ɵɵclassProp("active", ctx_r1.Icon === icon_r13);
263
+ i0.ɵɵproperty("title", icon_r13);
264
+ i0.ɵɵadvance();
265
+ i0.ɵɵclassMap(icon_r13);
266
+ } }
267
+ function AggregateSetupDialogComponent_Conditional_74_Template(rf, ctx) { if (rf & 1) {
268
+ i0.ɵɵelementStart(0, "div", 39);
269
+ i0.ɵɵelement(1, "i", 77);
270
+ i0.ɵɵelementStart(2, "span");
271
+ i0.ɵɵtext(3);
272
+ i0.ɵɵelementEnd()();
273
+ } if (rf & 2) {
274
+ const ctx_r1 = i0.ɵɵnextContext();
275
+ i0.ɵɵadvance(3);
276
+ i0.ɵɵtextInterpolate(ctx_r1.ValidationMessage);
277
+ } }
278
+ /**
279
+ * Default icons for aggregate functions
280
+ */
281
+ const FUNCTION_ICONS = {
282
+ 'SUM': 'fa-solid fa-plus',
283
+ 'AVG': 'fa-solid fa-divide',
284
+ 'COUNT': 'fa-solid fa-hashtag',
285
+ 'MIN': 'fa-solid fa-arrow-down',
286
+ 'MAX': 'fa-solid fa-arrow-up',
287
+ 'COUNT_DISTINCT': 'fa-solid fa-fingerprint'
288
+ };
289
+ /**
290
+ * Friendly labels for aggregate functions
291
+ */
292
+ const FUNCTION_LABELS = {
293
+ 'SUM': 'Sum',
294
+ 'AVG': 'Average',
295
+ 'COUNT': 'Count',
296
+ 'MIN': 'Minimum',
297
+ 'MAX': 'Maximum',
298
+ 'COUNT_DISTINCT': 'Count Distinct'
299
+ };
300
+ /**
301
+ * AggregateSetupDialogComponent - Dialog for creating/editing aggregate configurations
302
+ *
303
+ * Features:
304
+ * - Simple mode: Pick column + aggregate function (SUM, AVG, COUNT, etc.)
305
+ * - Advanced mode: Write custom SQL expression
306
+ * - Smart mode: Describe in natural language (AI generates expression)
307
+ * - Progressive disclosure - simple mode covers 80% of use cases
308
+ * - Display type selection (card or column)
309
+ * - Optional label and icon customization
310
+ */
311
+ export class AggregateSetupDialogComponent {
312
+ cdr;
313
+ /**
314
+ * The entity being viewed - provides field information
315
+ */
316
+ Entity = null;
317
+ /**
318
+ * Existing aggregate to edit (null for new)
319
+ */
320
+ Aggregate = null;
321
+ /**
322
+ * Whether the dialog is open
323
+ */
324
+ IsOpen = false;
325
+ /**
326
+ * Emitted when the dialog is closed
327
+ */
328
+ Close = new EventEmitter();
329
+ /**
330
+ * Emitted when an aggregate is saved
331
+ */
332
+ Save = new EventEmitter();
333
+ // Setup mode
334
+ Mode = 'simple';
335
+ // Simple mode state
336
+ SelectedColumn = '';
337
+ SelectedFunction = 'SUM';
338
+ // Advanced mode state
339
+ Expression = '';
340
+ // Smart mode state
341
+ SmartPrompt = '';
342
+ GeneratedExpression = '';
343
+ IsGenerating = false;
344
+ // Common configuration
345
+ Label = '';
346
+ DisplayType = 'card';
347
+ Icon = '';
348
+ Description = '';
349
+ // Available functions
350
+ AggregateFunctions = [
351
+ { value: 'SUM', label: 'Sum', icon: 'fa-solid fa-plus' },
352
+ { value: 'AVG', label: 'Average', icon: 'fa-solid fa-divide' },
353
+ { value: 'COUNT', label: 'Count', icon: 'fa-solid fa-hashtag' },
354
+ { value: 'MIN', label: 'Minimum', icon: 'fa-solid fa-arrow-down' },
355
+ { value: 'MAX', label: 'Maximum', icon: 'fa-solid fa-arrow-up' },
356
+ { value: 'COUNT_DISTINCT', label: 'Count Distinct', icon: 'fa-solid fa-fingerprint' }
357
+ ];
358
+ // Common icons for selection
359
+ CommonIcons = [
360
+ 'fa-solid fa-chart-line',
361
+ 'fa-solid fa-chart-bar',
362
+ 'fa-solid fa-dollar-sign',
363
+ 'fa-solid fa-users',
364
+ 'fa-solid fa-shopping-cart',
365
+ 'fa-solid fa-box',
366
+ 'fa-solid fa-clock',
367
+ 'fa-solid fa-calendar',
368
+ 'fa-solid fa-percent',
369
+ 'fa-solid fa-star',
370
+ 'fa-solid fa-check-circle',
371
+ 'fa-solid fa-exclamation-triangle'
372
+ ];
373
+ constructor(cdr) {
374
+ this.cdr = cdr;
375
+ }
376
+ ngOnInit() {
377
+ this.initializeFromAggregate();
378
+ }
379
+ ngOnChanges(changes) {
380
+ // Re-initialize when dialog opens or aggregate changes
381
+ if (changes['IsOpen'] && this.IsOpen) {
382
+ this.initializeFromAggregate();
383
+ }
384
+ if (changes['Aggregate'] && !changes['Aggregate'].firstChange) {
385
+ this.initializeFromAggregate();
386
+ }
387
+ }
388
+ /**
389
+ * Initialize form state from existing aggregate (if editing)
390
+ */
391
+ initializeFromAggregate() {
392
+ if (!this.Aggregate) {
393
+ this.resetForm();
394
+ return;
395
+ }
396
+ const agg = this.Aggregate;
397
+ // Set common fields
398
+ this.Label = agg.label || '';
399
+ this.DisplayType = agg.displayType || 'card';
400
+ this.Icon = agg.icon || '';
401
+ this.Description = agg.description || '';
402
+ // Determine mode and populate fields
403
+ if (agg.smartPrompt) {
404
+ // Smart mode - has AI prompt
405
+ this.Mode = 'smart';
406
+ this.SmartPrompt = agg.smartPrompt;
407
+ this.GeneratedExpression = agg.expression;
408
+ this.Expression = agg.expression;
409
+ }
410
+ else if (this.isSimpleExpression(agg.expression)) {
411
+ // Simple mode - can be represented as function(column)
412
+ this.Mode = 'simple';
413
+ const parsed = this.parseSimpleExpression(agg.expression);
414
+ if (parsed) {
415
+ this.SelectedFunction = parsed.func;
416
+ this.SelectedColumn = parsed.column;
417
+ this._previousColumn = parsed.column; // Track for auto-label updates
418
+ }
419
+ }
420
+ else {
421
+ // Advanced mode - custom expression
422
+ this.Mode = 'advanced';
423
+ this.Expression = agg.expression;
424
+ }
425
+ this.cdr.detectChanges();
426
+ }
427
+ /**
428
+ * Reset form to default state
429
+ */
430
+ resetForm() {
431
+ this.Mode = 'simple';
432
+ this.SelectedColumn = '';
433
+ this._previousColumn = ''; // Reset previous column tracking
434
+ this.SelectedFunction = 'SUM';
435
+ this.Expression = '';
436
+ this.SmartPrompt = '';
437
+ this.GeneratedExpression = '';
438
+ this.Label = '';
439
+ this.DisplayType = 'card';
440
+ this.Icon = '';
441
+ this.Description = '';
442
+ }
443
+ /**
444
+ * Check if an expression matches simple function(column) pattern
445
+ * Also matches COUNT(*) for row counting
446
+ */
447
+ isSimpleExpression(expression) {
448
+ const pattern = /^(SUM|AVG|COUNT|MIN|MAX|COUNT_DISTINCT)\s*\(\s*(\*|\[?[\w\s]+\]?)\s*\)$/i;
449
+ return pattern.test(expression.trim());
450
+ }
451
+ /**
452
+ * Parse a simple expression into function and column
453
+ * Returns empty string for column if COUNT(*)
454
+ */
455
+ parseSimpleExpression(expression) {
456
+ const match = expression.trim().match(/^(SUM|AVG|COUNT|MIN|MAX|COUNT_DISTINCT)\s*\(\s*(\*|\[?([\w\s]+)\]?)\s*\)$/i);
457
+ if (!match)
458
+ return null;
459
+ const funcName = match[1].toUpperCase().replace(' ', '_');
460
+ // If it's COUNT(*), column will be empty string
461
+ const column = match[2] === '*' ? '' : (match[3] || match[2]).trim();
462
+ return { func: funcName, column };
463
+ }
464
+ /**
465
+ * Get numeric fields for SUM/AVG operations
466
+ */
467
+ get NumericFields() {
468
+ if (!this.Entity)
469
+ return [];
470
+ return this.Entity.Fields.filter(f => {
471
+ const sqlType = f.Type.toLowerCase();
472
+ return sqlType.includes('int') ||
473
+ sqlType.includes('decimal') ||
474
+ sqlType.includes('numeric') ||
475
+ sqlType.includes('float') ||
476
+ sqlType.includes('real') ||
477
+ sqlType.includes('money');
478
+ });
479
+ }
480
+ /**
481
+ * Get date/datetime fields for MIN/MAX operations
482
+ */
483
+ get DateFields() {
484
+ if (!this.Entity)
485
+ return [];
486
+ return this.Entity.Fields.filter(f => {
487
+ const sqlType = f.Type.toLowerCase();
488
+ return sqlType.includes('date') || sqlType.includes('time');
489
+ });
490
+ }
491
+ /**
492
+ * Get string fields for MIN/MAX operations
493
+ */
494
+ get StringFields() {
495
+ if (!this.Entity)
496
+ return [];
497
+ return this.Entity.Fields.filter(f => {
498
+ const sqlType = f.Type.toLowerCase();
499
+ return (sqlType.includes('char') || sqlType.includes('text')) && !f.IsBinaryFieldType;
500
+ });
501
+ }
502
+ /**
503
+ * Get all fields for COUNT operations
504
+ */
505
+ get AllFields() {
506
+ if (!this.Entity)
507
+ return [];
508
+ return this.Entity.Fields.filter(f => !f.IsBinaryFieldType);
509
+ }
510
+ /**
511
+ * Get fields available for current function
512
+ */
513
+ get AvailableFields() {
514
+ // COUNT and COUNT_DISTINCT can use any field
515
+ if (this.SelectedFunction === 'COUNT' || this.SelectedFunction === 'COUNT_DISTINCT') {
516
+ return this.AllFields;
517
+ }
518
+ // SUM and AVG only work with numeric fields
519
+ if (this.SelectedFunction === 'SUM' || this.SelectedFunction === 'AVG') {
520
+ return this.NumericFields;
521
+ }
522
+ // MIN and MAX work with numeric and date fields only (not text/varchar)
523
+ if (this.SelectedFunction === 'MIN' || this.SelectedFunction === 'MAX') {
524
+ // Combine numeric and date fields (avoiding duplicates)
525
+ const combined = [...this.NumericFields, ...this.DateFields];
526
+ // Remove duplicates by field ID
527
+ const seen = new Set();
528
+ return combined.filter(f => {
529
+ if (seen.has(f.ID))
530
+ return false;
531
+ seen.add(f.ID);
532
+ return true;
533
+ });
534
+ }
535
+ // Default to all fields
536
+ return this.AllFields;
537
+ }
538
+ /**
539
+ * Set the setup mode
540
+ */
541
+ setMode(mode) {
542
+ this.Mode = mode;
543
+ // If switching from smart mode with generated expression, populate advanced mode
544
+ if (mode === 'advanced' && this.GeneratedExpression) {
545
+ this.Expression = this.GeneratedExpression;
546
+ }
547
+ this.cdr.detectChanges();
548
+ }
549
+ /**
550
+ * Handle function button click - captures old value before changing
551
+ * Called from template when user clicks a function button
552
+ */
553
+ selectFunction(newFunction) {
554
+ if (newFunction === this.SelectedFunction)
555
+ return;
556
+ const previousFunction = this.SelectedFunction;
557
+ this.SelectedFunction = newFunction;
558
+ this.onFunctionChange(previousFunction);
559
+ }
560
+ /**
561
+ * Handle column selection from dropdown
562
+ * Called from template with the NEW value from ngModelChange
563
+ * We track the previous value internally
564
+ */
565
+ _previousColumn = '';
566
+ onColumnSelected(newColumn) {
567
+ const previousColumn = this._previousColumn;
568
+ this._previousColumn = newColumn;
569
+ this.onColumnChange(previousColumn);
570
+ }
571
+ /**
572
+ * Handle function selection change (internal)
573
+ */
574
+ onFunctionChange(previousFunction) {
575
+ // Check if label matches what we would have auto-generated for the OLD function
576
+ const shouldUpdateLabel = this.shouldAutoUpdateLabel(previousFunction, this.SelectedColumn);
577
+ // If current column is not valid for new function, clear it
578
+ const validFields = this.AvailableFields;
579
+ if (this.SelectedColumn && !validFields.find(f => f.Name === this.SelectedColumn)) {
580
+ this.SelectedColumn = '';
581
+ }
582
+ // Update label if it was auto-generated (matches old pattern) or is empty
583
+ // For COUNT, we can set auto-label even without a column (COUNT(*))
584
+ if (shouldUpdateLabel && (this.SelectedColumn || this.SelectedFunction === 'COUNT')) {
585
+ this.setAutoLabel();
586
+ }
587
+ this.cdr.detectChanges();
588
+ }
589
+ /**
590
+ * Handle column selection change
591
+ */
592
+ onColumnChange(previousColumn) {
593
+ // Check if label matches what we would have auto-generated for the OLD column
594
+ const shouldUpdateLabel = this.shouldAutoUpdateLabel(this.SelectedFunction, previousColumn);
595
+ // Update label if it was auto-generated (matches old pattern) or is empty
596
+ if (shouldUpdateLabel) {
597
+ this.setAutoLabel();
598
+ }
599
+ this.cdr.detectChanges();
600
+ }
601
+ /**
602
+ * Check if the current label matches what we would have auto-generated
603
+ * for the given function and column. If so, we should update the label
604
+ * when either changes. This allows auto-updating while preserving manual edits.
605
+ */
606
+ shouldAutoUpdateLabel(func, column) {
607
+ // Always update if label is empty
608
+ if (!this.Label)
609
+ return true;
610
+ // Check if current label matches the auto-generated pattern for the old values
611
+ const expectedOldLabel = this.generateAutoLabel(func, column);
612
+ return expectedOldLabel !== null && this.Label === expectedOldLabel;
613
+ }
614
+ /**
615
+ * Generate what the auto-label would be for a given function and column
616
+ * Returns null if we can't generate a label (missing data)
617
+ * Handles COUNT(*) case with "Record Count" label
618
+ */
619
+ generateAutoLabel(func, column) {
620
+ if (!func)
621
+ return null;
622
+ // Handle COUNT(*) case - no column needed
623
+ if (!column) {
624
+ if (func === 'COUNT') {
625
+ return 'Record Count';
626
+ }
627
+ return null; // Other functions require a column
628
+ }
629
+ const field = this.Entity?.Fields.find(f => f.Name === column);
630
+ if (!field)
631
+ return null;
632
+ const funcLabel = FUNCTION_LABELS[func] || func;
633
+ return `${funcLabel} of ${field.DisplayNameOrName}`;
634
+ }
635
+ /**
636
+ * Set the auto-generated label based on current function and column
637
+ */
638
+ setAutoLabel() {
639
+ const label = this.generateAutoLabel(this.SelectedFunction, this.SelectedColumn);
640
+ if (label) {
641
+ this.Label = label;
642
+ }
643
+ }
644
+ /**
645
+ * Select an icon
646
+ */
647
+ selectIcon(icon) {
648
+ this.Icon = icon;
649
+ this.cdr.detectChanges();
650
+ }
651
+ /**
652
+ * Clear the icon
653
+ */
654
+ clearIcon() {
655
+ this.Icon = '';
656
+ this.cdr.detectChanges();
657
+ }
658
+ /**
659
+ * Build the expression based on current mode
660
+ */
661
+ buildExpression() {
662
+ switch (this.Mode) {
663
+ case 'simple':
664
+ if (!this.SelectedFunction)
665
+ return '';
666
+ // COUNT can work without a column (uses COUNT(*))
667
+ // COUNT_DISTINCT requires a column
668
+ if (!this.SelectedColumn) {
669
+ if (this.SelectedFunction === 'COUNT') {
670
+ return 'COUNT(*)';
671
+ }
672
+ return ''; // Other functions require a column
673
+ }
674
+ // Use brackets for column names with spaces
675
+ const columnRef = this.SelectedColumn.includes(' ')
676
+ ? `[${this.SelectedColumn}]`
677
+ : this.SelectedColumn;
678
+ if (this.SelectedFunction === 'COUNT_DISTINCT') {
679
+ return `COUNT(DISTINCT ${columnRef})`;
680
+ }
681
+ return `${this.SelectedFunction}(${columnRef})`;
682
+ case 'advanced':
683
+ return this.Expression;
684
+ case 'smart':
685
+ return this.GeneratedExpression || '';
686
+ default:
687
+ return '';
688
+ }
689
+ }
690
+ /**
691
+ * Check if the form is valid
692
+ */
693
+ get IsValid() {
694
+ const hasExpression = !!this.buildExpression();
695
+ const hasLabel = !!this.Label.trim();
696
+ return hasExpression && hasLabel;
697
+ }
698
+ /**
699
+ * Get validation message
700
+ */
701
+ get ValidationMessage() {
702
+ if (!this.Label.trim()) {
703
+ return 'Please enter a label for this aggregate';
704
+ }
705
+ switch (this.Mode) {
706
+ case 'simple':
707
+ // COUNT can work without a column (uses COUNT(*))
708
+ // All other functions require a column
709
+ if (!this.SelectedColumn && this.SelectedFunction !== 'COUNT') {
710
+ return 'Please select a column';
711
+ }
712
+ break;
713
+ case 'advanced':
714
+ if (!this.Expression.trim())
715
+ return 'Please enter an expression';
716
+ break;
717
+ case 'smart':
718
+ if (!this.GeneratedExpression)
719
+ return 'Please generate an expression from your prompt';
720
+ break;
721
+ }
722
+ return '';
723
+ }
724
+ /**
725
+ * Save the aggregate
726
+ */
727
+ onSave() {
728
+ if (!this.IsValid)
729
+ return;
730
+ const aggregate = {
731
+ id: this.Aggregate?.id || this.generateId(),
732
+ expression: this.buildExpression(),
733
+ displayType: this.DisplayType,
734
+ label: this.Label.trim(),
735
+ description: this.Description.trim() || undefined,
736
+ icon: this.Icon || this.getDefaultIcon(),
737
+ enabled: this.Aggregate?.enabled ?? true, // Preserve enabled state when editing, default to true for new
738
+ order: this.Aggregate?.order || 0
739
+ };
740
+ // Only include smartPrompt if in smart mode
741
+ if (this.Mode === 'smart' && this.SmartPrompt) {
742
+ aggregate.smartPrompt = this.SmartPrompt;
743
+ }
744
+ this.Save.emit(aggregate);
745
+ this.onClose();
746
+ }
747
+ /**
748
+ * Get default icon based on function
749
+ */
750
+ getDefaultIcon() {
751
+ if (this.Mode === 'simple' && this.SelectedFunction) {
752
+ return FUNCTION_ICONS[this.SelectedFunction] || 'fa-solid fa-chart-simple';
753
+ }
754
+ return 'fa-solid fa-chart-simple';
755
+ }
756
+ /**
757
+ * Generate a unique ID for new aggregates
758
+ */
759
+ generateId() {
760
+ return `agg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
761
+ }
762
+ /**
763
+ * Close the dialog
764
+ */
765
+ onClose() {
766
+ this.Close.emit();
767
+ }
768
+ /**
769
+ * Handle smart prompt generation (placeholder - actual AI call would be made by parent)
770
+ */
771
+ onGenerateFromPrompt() {
772
+ if (!this.SmartPrompt.trim())
773
+ return;
774
+ this.IsGenerating = true;
775
+ this.cdr.detectChanges();
776
+ // This would typically call an AI service
777
+ // For now, we'll show a placeholder message
778
+ // The actual implementation would be handled by the parent component or a service
779
+ setTimeout(() => {
780
+ this.IsGenerating = false;
781
+ // Placeholder: In real implementation, this would be replaced with AI-generated expression
782
+ this.GeneratedExpression = '/* AI-generated expression will appear here */';
783
+ this.cdr.detectChanges();
784
+ }, 500);
785
+ }
786
+ /**
787
+ * Clear the generated expression and allow editing prompt
788
+ */
789
+ clearGeneratedExpression() {
790
+ this.GeneratedExpression = '';
791
+ this.cdr.detectChanges();
792
+ }
793
+ /**
794
+ * Get display label for field dropdown showing "Name (DisplayName)" format
795
+ * If DisplayName equals Name or is not set, just show Name
796
+ */
797
+ getFieldDisplayLabel(field) {
798
+ if (field.DisplayName && field.DisplayName !== field.Name) {
799
+ return `${field.Name} (${field.DisplayName})`;
800
+ }
801
+ return field.Name;
802
+ }
803
+ static ɵfac = function AggregateSetupDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AggregateSetupDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
804
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AggregateSetupDialogComponent, selectors: [["mj-aggregate-setup-dialog"]], inputs: { Entity: "Entity", Aggregate: "Aggregate", IsOpen: "IsOpen" }, outputs: { Close: "Close", Save: "Save" }, features: [i0.ɵɵNgOnChangesFeature], decls: 75, vars: 23, consts: [[1, "dialog-backdrop"], [1, "dialog-panel"], [1, "dialog-header"], [1, "header-title"], [1, "fa-solid", "fa-chart-simple"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "mode-selector"], ["title", "Pick a column and function", 1, "mode-btn", 3, "click"], [1, "fa-solid", "fa-wand-sparkles"], ["title", "Write custom SQL expression", 1, "mode-btn", 3, "click"], [1, "fa-solid", "fa-code"], ["title", "Describe in natural language", 1, "mode-btn", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "dialog-content"], [1, "mode-content", "simple-mode"], [1, "mode-content", "advanced-mode"], [1, "mode-content", "smart-mode"], [1, "config-section"], [1, "section-divider"], [1, "form-section"], [1, "form-label", "required"], ["type", "text", "placeholder", "e.g., Total Revenue, Average Order Value", 1, "form-input", 3, "ngModelChange", "ngModel"], [1, "form-label"], [1, "optional"], ["type", "text", "placeholder", "Brief explanation of what this shows", 1, "form-input", 3, "ngModelChange", "ngModel"], [1, "display-type-toggle"], [1, "display-type-btn", 3, "click"], [1, "fa-solid", "fa-id-card"], [1, "fa-solid", "fa-table-columns"], [1, "icon-selector"], [1, "selected-icon"], [1, "icon-grid"], [1, "icon-btn", 3, "active", "title"], [1, "dialog-footer"], [1, "footer-left"], [1, "footer-btn", "save-btn", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-check"], [1, "footer-btn", "cancel-btn", 3, "click"], [1, "validation-message"], [1, "dialog-backdrop", 3, "click"], [1, "mode-description"], [1, "fa-solid", "fa-info-circle"], [1, "function-grid"], [1, "function-btn", 3, "active", "title"], [1, "form-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "field-hint", "warning"], [1, "field-hint", "info"], [1, "expression-preview"], [1, "function-btn", 3, "click", "title"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "preview-label"], [1, "preview-code"], ["placeholder", "e.g., SUM(Amount * Quantity) or COUNT(CASE WHEN Status = 'Active' THEN 1 END)", "rows", "3", 1, "form-textarea", "code-input", 3, "ngModelChange", "ngModel"], [1, "field-hint"], [1, "fa-solid", "fa-lightbulb"], [1, "form-label", "examples-label"], [1, "example-chips"], [1, "example-chip", 3, "click"], [1, "smart-input-container"], ["placeholder", "e.g., 'Total revenue from completed orders' or 'Average order value for premium customers'", "rows", "3", 1, "form-textarea", "smart-input", 3, "ngModelChange", "ngModel", "disabled"], [1, "generate-btn", 3, "disabled"], [1, "generated-section"], [1, "smart-tips"], [1, "tips-header"], [1, "tips-list"], [1, "generate-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "generated-header"], ["title", "Edit prompt", 1, "clear-generated-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "generated-code"], [1, "generated-info"], ["title", "Remove icon", 1, "clear-icon-btn", 3, "click"], [1, "icon-btn", 3, "click", "title"], [1, "fa-solid", "fa-exclamation-circle"]], template: function AggregateSetupDialogComponent_Template(rf, ctx) { if (rf & 1) {
805
+ i0.ɵɵtemplate(0, AggregateSetupDialogComponent_Conditional_0_Template, 1, 0, "div", 0);
806
+ i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
807
+ i0.ɵɵelement(4, "i", 4);
808
+ i0.ɵɵelementStart(5, "span");
809
+ i0.ɵɵtext(6);
810
+ i0.ɵɵelementEnd()();
811
+ i0.ɵɵelementStart(7, "button", 5);
812
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_7_listener() { return ctx.onClose(); });
813
+ i0.ɵɵelement(8, "i", 6);
814
+ i0.ɵɵelementEnd()();
815
+ i0.ɵɵelementStart(9, "div", 7)(10, "button", 8);
816
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_10_listener() { return ctx.setMode("simple"); });
817
+ i0.ɵɵelement(11, "i", 9);
818
+ i0.ɵɵelementStart(12, "span");
819
+ i0.ɵɵtext(13, "Simple");
820
+ i0.ɵɵelementEnd()();
821
+ i0.ɵɵelementStart(14, "button", 10);
822
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_14_listener() { return ctx.setMode("advanced"); });
823
+ i0.ɵɵelement(15, "i", 11);
824
+ i0.ɵɵelementStart(16, "span");
825
+ i0.ɵɵtext(17, "Advanced");
826
+ i0.ɵɵelementEnd()();
827
+ i0.ɵɵelementStart(18, "button", 12);
828
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_18_listener() { return ctx.setMode("smart"); });
829
+ i0.ɵɵelement(19, "i", 13);
830
+ i0.ɵɵelementStart(20, "span");
831
+ i0.ɵɵtext(21, "Smart");
832
+ i0.ɵɵelementEnd()()();
833
+ i0.ɵɵelementStart(22, "div", 14);
834
+ i0.ɵɵtemplate(23, AggregateSetupDialogComponent_Conditional_23_Template, 22, 4, "div", 15)(24, AggregateSetupDialogComponent_Conditional_24_Template, 25, 1, "div", 16)(25, AggregateSetupDialogComponent_Conditional_25_Template, 24, 4, "div", 17);
835
+ i0.ɵɵelementStart(26, "div", 18)(27, "div", 19)(28, "span");
836
+ i0.ɵɵtext(29, "Display Options");
837
+ i0.ɵɵelementEnd()();
838
+ i0.ɵɵelementStart(30, "div", 20)(31, "label", 21);
839
+ i0.ɵɵtext(32, "Label");
840
+ i0.ɵɵelementEnd();
841
+ i0.ɵɵelementStart(33, "input", 22);
842
+ i0.ɵɵtwoWayListener("ngModelChange", function AggregateSetupDialogComponent_Template_input_ngModelChange_33_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.Label, $event) || (ctx.Label = $event); return $event; });
843
+ i0.ɵɵelementEnd()();
844
+ i0.ɵɵelementStart(34, "div", 20)(35, "label", 23);
845
+ i0.ɵɵtext(36, "Description ");
846
+ i0.ɵɵelementStart(37, "span", 24);
847
+ i0.ɵɵtext(38, "(optional)");
848
+ i0.ɵɵelementEnd()();
849
+ i0.ɵɵelementStart(39, "input", 25);
850
+ i0.ɵɵtwoWayListener("ngModelChange", function AggregateSetupDialogComponent_Template_input_ngModelChange_39_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.Description, $event) || (ctx.Description = $event); return $event; });
851
+ i0.ɵɵelementEnd()();
852
+ i0.ɵɵelementStart(40, "div", 20)(41, "label", 23);
853
+ i0.ɵɵtext(42, "Display As");
854
+ i0.ɵɵelementEnd();
855
+ i0.ɵɵelementStart(43, "div", 26)(44, "button", 27);
856
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_44_listener() { return ctx.DisplayType = "card"; });
857
+ i0.ɵɵelement(45, "i", 28);
858
+ i0.ɵɵelementStart(46, "span");
859
+ i0.ɵɵtext(47, "Card");
860
+ i0.ɵɵelementEnd();
861
+ i0.ɵɵelementStart(48, "small");
862
+ i0.ɵɵtext(49, "Shows in summary panel");
863
+ i0.ɵɵelementEnd()();
864
+ i0.ɵɵelementStart(50, "button", 27);
865
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_50_listener() { return ctx.DisplayType = "column"; });
866
+ i0.ɵɵelement(51, "i", 29);
867
+ i0.ɵɵelementStart(52, "span");
868
+ i0.ɵɵtext(53, "Column Footer");
869
+ i0.ɵɵelementEnd();
870
+ i0.ɵɵelementStart(54, "small");
871
+ i0.ɵɵtext(55, "Shows at bottom of grid");
872
+ i0.ɵɵelementEnd()()()();
873
+ i0.ɵɵelementStart(56, "div", 20)(57, "label", 23);
874
+ i0.ɵɵtext(58, "Icon ");
875
+ i0.ɵɵelementStart(59, "span", 24);
876
+ i0.ɵɵtext(60, "(optional)");
877
+ i0.ɵɵelementEnd()();
878
+ i0.ɵɵelementStart(61, "div", 30);
879
+ i0.ɵɵtemplate(62, AggregateSetupDialogComponent_Conditional_62_Template, 4, 2, "div", 31);
880
+ i0.ɵɵelementStart(63, "div", 32);
881
+ i0.ɵɵrepeaterCreate(64, AggregateSetupDialogComponent_For_65_Template, 2, 5, "button", 33, i0.ɵɵrepeaterTrackByIdentity);
882
+ i0.ɵɵelementEnd()()()()();
883
+ i0.ɵɵelementStart(66, "div", 34)(67, "div", 35)(68, "button", 36);
884
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_68_listener() { return ctx.onSave(); });
885
+ i0.ɵɵelement(69, "i", 37);
886
+ i0.ɵɵelementStart(70, "span");
887
+ i0.ɵɵtext(71);
888
+ i0.ɵɵelementEnd()()();
889
+ i0.ɵɵelementStart(72, "button", 38);
890
+ i0.ɵɵlistener("click", function AggregateSetupDialogComponent_Template_button_click_72_listener() { return ctx.onClose(); });
891
+ i0.ɵɵtext(73, " Cancel ");
892
+ i0.ɵɵelementEnd()();
893
+ i0.ɵɵtemplate(74, AggregateSetupDialogComponent_Conditional_74_Template, 4, 1, "div", 39);
894
+ i0.ɵɵelementEnd();
895
+ } if (rf & 2) {
896
+ i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
897
+ i0.ɵɵadvance();
898
+ i0.ɵɵclassProp("open", ctx.IsOpen);
899
+ i0.ɵɵadvance(5);
900
+ i0.ɵɵtextInterpolate(ctx.Aggregate ? "Edit Aggregate" : "Add Aggregate");
901
+ i0.ɵɵadvance(4);
902
+ i0.ɵɵclassProp("active", ctx.Mode === "simple");
903
+ i0.ɵɵadvance(4);
904
+ i0.ɵɵclassProp("active", ctx.Mode === "advanced");
905
+ i0.ɵɵadvance(4);
906
+ i0.ɵɵclassProp("active", ctx.Mode === "smart");
907
+ i0.ɵɵadvance(5);
908
+ i0.ɵɵconditional(ctx.Mode === "simple" ? 23 : -1);
909
+ i0.ɵɵadvance();
910
+ i0.ɵɵconditional(ctx.Mode === "advanced" ? 24 : -1);
911
+ i0.ɵɵadvance();
912
+ i0.ɵɵconditional(ctx.Mode === "smart" ? 25 : -1);
913
+ i0.ɵɵadvance(8);
914
+ i0.ɵɵtwoWayProperty("ngModel", ctx.Label);
915
+ i0.ɵɵadvance(6);
916
+ i0.ɵɵtwoWayProperty("ngModel", ctx.Description);
917
+ i0.ɵɵadvance(5);
918
+ i0.ɵɵclassProp("active", ctx.DisplayType === "card");
919
+ i0.ɵɵadvance(6);
920
+ i0.ɵɵclassProp("active", ctx.DisplayType === "column");
921
+ i0.ɵɵadvance(12);
922
+ i0.ɵɵconditional(ctx.Icon ? 62 : -1);
923
+ i0.ɵɵadvance(2);
924
+ i0.ɵɵrepeater(ctx.CommonIcons);
925
+ i0.ɵɵadvance(4);
926
+ i0.ɵɵproperty("disabled", !ctx.IsValid);
927
+ i0.ɵɵadvance(3);
928
+ i0.ɵɵtextInterpolate1("", ctx.Aggregate ? "Update" : "Add", " Aggregate");
929
+ i0.ɵɵadvance(3);
930
+ i0.ɵɵconditional(ctx.ValidationMessage ? 74 : -1);
931
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["\n\n.dialog-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.4);\n z-index: 2000;\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.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n font-size: 18px;\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: #6b7280;\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: #e5e7eb;\n color: #374151;\n}\n\n\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: #f8fafc;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #fafafa;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #6b7280;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n\n\n.mode-content[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.mode-description[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: #0369a1;\n line-height: 1.5;\n}\n\n.mode-description[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0284c7;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 18px;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.form-label.required[_ngcontent-%COMP%]::after {\n content: ' *';\n color: #dc2626;\n}\n\n.form-label[_ngcontent-%COMP%] .optional[_ngcontent-%COMP%] {\n font-weight: 400;\n color: #9ca3af;\n}\n\n.form-label.examples-label[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n\n\n.form-input[_ngcontent-%COMP%], \n.form-select[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: white;\n}\n\n.form-input[_ngcontent-%COMP%]:focus, \n.form-select[_ngcontent-%COMP%]:focus, \n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input[_ngcontent-%COMP%] {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n\n\n.function-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.function-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.function-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #6b7280;\n}\n\n.function-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.function-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n}\n\n.function-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n\n\n.field-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: #f8fafc;\n border-radius: 6px;\n font-size: 12px;\n color: #64748b;\n}\n\n.field-hint.warning[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: #92400e;\n}\n\n.field-hint.warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.field-hint.info[_ngcontent-%COMP%] {\n background: #eff6ff;\n color: #1e40af;\n}\n\n.field-hint.info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.field-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n.expression-preview[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #1e293b;\n}\n\n\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n\n\n.smart-input-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input[_ngcontent-%COMP%] {\n min-height: 100px;\n}\n\n.smart-input[_ngcontent-%COMP%]:disabled {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.generate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border: none;\n border-radius: 10px;\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n.generate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n\n\n.generated-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 16px;\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border: 1px solid #86efac;\n border-radius: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] .form-label[_ngcontent-%COMP%] {\n margin-bottom: 0;\n color: #166534;\n}\n\n.clear-generated-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #86efac;\n border-radius: 6px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #166534;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn[_ngcontent-%COMP%]:hover {\n background: #166534;\n color: white;\n}\n\n.generated-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #86efac;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #14532d;\n margin-bottom: 10px;\n}\n\n.generated-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: #166534;\n}\n\n.generated-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 1px;\n}\n\n\n\n.smart-tips[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding: 14px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n border-radius: 10px;\n}\n\n.tips-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #92400e;\n}\n\n.tips-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.tips-list[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: #78350f;\n line-height: 1.6;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n padding-top: 16px;\n}\n\n.section-divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider[_ngcontent-%COMP%]::before, \n.section-divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: #e5e7eb;\n}\n\n.section-divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #9ca3af;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.display-type-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.display-type-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: #6b7280;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.display-type-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n.display-type-btn[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n color: #60a5fa;\n}\n\n\n\n.icon-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #eff6ff;\n border: 1px solid #93c5fd;\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 20px;\n color: #3b82f6;\n}\n\n.clear-icon-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n border: none;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n color: #9ca3af;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn[_ngcontent-%COMP%]:hover {\n background: #dc2626;\n color: white;\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.icon-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.icon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #6b7280;\n}\n\n.icon-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid #d1d5db;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f3f4f6;\n border-color: #9ca3af;\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: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-color: #3b82f6;\n color: white;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border-color: #2563eb;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n\n\n.validation-message[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.validation-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n@media (max-width: 600px) {\n .dialog-panel[_ngcontent-%COMP%] {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header[_ngcontent-%COMP%], \n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn[_ngcontent-%COMP%] {\n padding: 10px 8px;\n }\n\n .mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .function-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"] });
932
+ }
933
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AggregateSetupDialogComponent, [{
934
+ type: Component,
935
+ args: [{ selector: 'mj-aggregate-setup-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Aggregate ? 'Edit Aggregate' : 'Add Aggregate' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'simple'\"\n (click)=\"setMode('simple')\"\n title=\"Pick a column and function\">\n <i class=\"fa-solid fa-wand-sparkles\"></i>\n <span>Simple</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'advanced'\"\n (click)=\"setMode('advanced')\"\n title=\"Write custom SQL expression\">\n <i class=\"fa-solid fa-code\"></i>\n <span>Advanced</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'smart'\"\n (click)=\"setMode('smart')\"\n title=\"Describe in natural language\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart</span>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Simple Mode -->\n @if (Mode === 'simple') {\n <div class=\"mode-content simple-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Select a column and an aggregate function to calculate</span>\n </div>\n\n <!-- Function Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Function</label>\n <div class=\"function-grid\">\n @for (func of AggregateFunctions; track func.value) {\n <button\n class=\"function-btn\"\n [class.active]=\"SelectedFunction === func.value\"\n (click)=\"selectFunction(func.value)\"\n [title]=\"func.label\">\n <i [class]=\"func.icon\"></i>\n <span>{{ func.label }}</span>\n </button>\n }\n </div>\n </div>\n\n <!-- Column Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Column</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"SelectedColumn\"\n (ngModelChange)=\"onColumnSelected($event)\">\n <option value=\"\">Select a column...</option>\n @for (field of AvailableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ getFieldDisplayLabel(field) }}</option>\n }\n </select>\n @if (SelectedFunction !== 'COUNT' && SelectedFunction !== 'COUNT_DISTINCT' && NumericFields.length === 0) {\n <div class=\"field-hint warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>No numeric fields available. Use COUNT or switch to Advanced mode.</span>\n </div>\n }\n @if (SelectedFunction === 'COUNT' && !SelectedColumn) {\n <div class=\"field-hint info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No column selected - will count all records (COUNT(*))</span>\n </div>\n }\n </div>\n\n <!-- Preview -->\n @if (SelectedFunction && (SelectedColumn || SelectedFunction === 'COUNT')) {\n <div class=\"expression-preview\">\n <label class=\"preview-label\">Expression Preview</label>\n <code class=\"preview-code\">{{\n !SelectedColumn && SelectedFunction === 'COUNT' ? 'COUNT(*)' :\n SelectedFunction === 'COUNT_DISTINCT' ? 'COUNT(DISTINCT ' + SelectedColumn + ')' :\n SelectedFunction + '(' + SelectedColumn + ')'\n }}</code>\n </div>\n }\n </div>\n }\n\n <!-- Advanced Mode -->\n @if (Mode === 'advanced') {\n <div class=\"mode-content advanced-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Write a custom SQL aggregate expression. Use field names as they appear in the database.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">SQL Expression</label>\n <textarea\n class=\"form-textarea code-input\"\n [(ngModel)]=\"Expression\"\n placeholder=\"e.g., SUM(Amount * Quantity) or COUNT(CASE WHEN Status = 'Active' THEN 1 END)\"\n rows=\"3\"\n ></textarea>\n <div class=\"field-hint\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use brackets for column names with spaces, e.g., [Total Amount]</span>\n </div>\n </div>\n\n <!-- Quick Examples -->\n <div class=\"form-section\">\n <label class=\"form-label examples-label\">Quick Examples</label>\n <div class=\"example-chips\">\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(Amount)'\">\n SUM(Amount)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'AVG(Price * Quantity)'\">\n AVG(Price * Quantity)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'COUNT(CASE WHEN Status = \\'Active\\' THEN 1 END)'\">\n COUNT with condition\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(CASE WHEN Type = \\'Credit\\' THEN Amount ELSE -Amount END)'\">\n Conditional SUM\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Smart Mode -->\n @if (Mode === 'smart') {\n <div class=\"mode-content smart-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Describe what you want to calculate in plain English. AI will generate the expression.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">What would you like to calculate?</label>\n <div class=\"smart-input-container\">\n <textarea\n class=\"form-textarea smart-input\"\n [(ngModel)]=\"SmartPrompt\"\n [disabled]=\"!!GeneratedExpression\"\n placeholder=\"e.g., 'Total revenue from completed orders' or 'Average order value for premium customers'\"\n rows=\"3\"\n ></textarea>\n @if (!GeneratedExpression) {\n <button\n class=\"generate-btn\"\n [disabled]=\"!SmartPrompt.trim() || IsGenerating\"\n (click)=\"onGenerateFromPrompt()\">\n @if (IsGenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Generating...</span>\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Generate</span>\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Generated Expression -->\n @if (GeneratedExpression) {\n <div class=\"generated-section\">\n <div class=\"generated-header\">\n <label class=\"form-label\">Generated Expression</label>\n <button class=\"clear-generated-btn\" (click)=\"clearGeneratedExpression()\" title=\"Edit prompt\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit Prompt</span>\n </button>\n </div>\n <code class=\"generated-code\">{{ GeneratedExpression }}</code>\n <div class=\"generated-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>This expression was generated from your description. Clear it to edit the prompt.</span>\n </div>\n </div>\n }\n\n <!-- Smart Mode Tips -->\n <div class=\"smart-tips\">\n <div class=\"tips-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tips for better results:</span>\n </div>\n <ul class=\"tips-list\">\n <li>Be specific about which fields to use</li>\n <li>Mention any conditions or filters</li>\n <li>Specify the type of calculation (sum, average, count, etc.)</li>\n </ul>\n </div>\n </div>\n }\n\n <!-- Common Configuration -->\n <div class=\"config-section\">\n <div class=\"section-divider\">\n <span>Display Options</span>\n </div>\n\n <!-- Label -->\n <div class=\"form-section\">\n <label class=\"form-label required\">Label</label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Label\"\n placeholder=\"e.g., Total Revenue, Average Order Value\"\n />\n </div>\n\n <!-- Description (optional) -->\n <div class=\"form-section\">\n <label class=\"form-label\">Description <span class=\"optional\">(optional)</span></label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Description\"\n placeholder=\"Brief explanation of what this shows\"\n />\n </div>\n\n <!-- Display Type -->\n <div class=\"form-section\">\n <label class=\"form-label\">Display As</label>\n <div class=\"display-type-toggle\">\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'card'\"\n (click)=\"DisplayType = 'card'\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>Card</span>\n <small>Shows in summary panel</small>\n </button>\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'column'\"\n (click)=\"DisplayType = 'column'\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>Column Footer</span>\n <small>Shows at bottom of grid</small>\n </button>\n </div>\n </div>\n\n <!-- Icon Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Icon <span class=\"optional\">(optional)</span></label>\n <div class=\"icon-selector\">\n @if (Icon) {\n <div class=\"selected-icon\">\n <i [class]=\"Icon\"></i>\n <button class=\"clear-icon-btn\" (click)=\"clearIcon()\" title=\"Remove icon\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n <div class=\"icon-grid\">\n @for (icon of CommonIcons; track icon) {\n <button\n class=\"icon-btn\"\n [class.active]=\"Icon === icon\"\n (click)=\"selectIcon(icon)\"\n [title]=\"icon\">\n <i [class]=\"icon\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n <button\n class=\"footer-btn save-btn primary\"\n [disabled]=\"!IsValid\"\n (click)=\"onSave()\">\n <i class=\"fa-solid fa-check\"></i>\n <span>{{ Aggregate ? 'Update' : 'Add' }} Aggregate</span>\n </button>\n </div>\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n\n <!-- Validation Message -->\n @if (ValidationMessage) {\n <div class=\"validation-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ ValidationMessage }}</span>\n </div>\n }\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title i {\n color: #3b82f6;\n font-size: 18px;\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: #6b7280;\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: #e5e7eb;\n color: #374151;\n}\n\n/* Mode Selector */\n.mode-selector {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: #f8fafc;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.mode-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn:hover {\n border-color: #d1d5db;\n background: #fafafa;\n}\n\n.mode-btn.active {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.mode-btn i {\n font-size: 18px;\n color: #6b7280;\n}\n\n.mode-btn.active i {\n color: #3b82f6;\n}\n\n.mode-btn span {\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.mode-btn.active span {\n color: #1d4ed8;\n}\n\n/* Dialog Content */\n.dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n/* Mode Content */\n.mode-content {\n margin-bottom: 20px;\n}\n\n.mode-description {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: #0369a1;\n line-height: 1.5;\n}\n\n.mode-description i {\n color: #0284c7;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Form Sections */\n.form-section {\n margin-bottom: 18px;\n}\n\n.form-label {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.form-label.required::after {\n content: ' *';\n color: #dc2626;\n}\n\n.form-label .optional {\n font-weight: 400;\n color: #9ca3af;\n}\n\n.form-label.examples-label {\n color: #6b7280;\n}\n\n/* Form Inputs */\n.form-input,\n.form-select,\n.form-textarea {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: white;\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n/* Function Grid */\n.function-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.function-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.function-btn i {\n font-size: 18px;\n color: #6b7280;\n}\n\n.function-btn.active i {\n color: #3b82f6;\n}\n\n.function-btn span {\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n}\n\n.function-btn.active span {\n color: #1d4ed8;\n}\n\n/* Field Hint */\n.field-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: #f8fafc;\n border-radius: 6px;\n font-size: 12px;\n color: #64748b;\n}\n\n.field-hint.warning {\n background: #fffbeb;\n color: #92400e;\n}\n\n.field-hint.warning i {\n color: #f59e0b;\n}\n\n.field-hint.info {\n background: #eff6ff;\n color: #1e40af;\n}\n\n.field-hint.info i {\n color: #3b82f6;\n}\n\n.field-hint i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Expression Preview */\n.expression-preview {\n margin-top: 16px;\n padding: 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n}\n\n.preview-label {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #1e293b;\n}\n\n/* Example Chips */\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n/* Smart Mode Input */\n.smart-input-container {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input {\n min-height: 100px;\n}\n\n.smart-input:disabled {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.generate-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border: none;\n border-radius: 10px;\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n.generate-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n/* Generated Section */\n.generated-section {\n margin-top: 16px;\n padding: 16px;\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border: 1px solid #86efac;\n border-radius: 10px;\n}\n\n.generated-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header .form-label {\n margin-bottom: 0;\n color: #166534;\n}\n\n.clear-generated-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #86efac;\n border-radius: 6px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #166534;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn:hover {\n background: #166534;\n color: white;\n}\n\n.generated-code {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #86efac;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #14532d;\n margin-bottom: 10px;\n}\n\n.generated-info {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: #166534;\n}\n\n.generated-info i {\n margin-top: 1px;\n}\n\n/* Smart Tips */\n.smart-tips {\n margin-top: 20px;\n padding: 14px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n border-radius: 10px;\n}\n\n.tips-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #92400e;\n}\n\n.tips-header i {\n color: #f59e0b;\n}\n\n.tips-list {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: #78350f;\n line-height: 1.6;\n}\n\n/* Config Section */\n.config-section {\n padding-top: 16px;\n}\n\n.section-divider {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider::before,\n.section-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: #e5e7eb;\n}\n\n.section-divider span {\n font-size: 12px;\n font-weight: 600;\n color: #9ca3af;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Display Type Toggle */\n.display-type-toggle {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.display-type-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.display-type-btn i {\n font-size: 22px;\n color: #6b7280;\n}\n\n.display-type-btn.active i {\n color: #3b82f6;\n}\n\n.display-type-btn span {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n}\n\n.display-type-btn.active span {\n color: #1d4ed8;\n}\n\n.display-type-btn small {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.display-type-btn.active small {\n color: #60a5fa;\n}\n\n/* Icon Selector */\n.icon-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #eff6ff;\n border: 1px solid #93c5fd;\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon i:first-child {\n font-size: 20px;\n color: #3b82f6;\n}\n\n.clear-icon-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n color: #9ca3af;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn:hover {\n background: #dc2626;\n color: white;\n}\n\n.icon-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.icon-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.icon-btn i {\n font-size: 16px;\n color: #6b7280;\n}\n\n.icon-btn.active i {\n color: #3b82f6;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid #d1d5db;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: #f3f4f6;\n border-color: #9ca3af;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-color: #3b82f6;\n color: white;\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border-color: #2563eb;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n/* Validation Message */\n.validation-message {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.validation-message i {\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 600px) {\n .dialog-panel {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header,\n .dialog-footer {\n border-radius: 0;\n }\n\n .dialog-header {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn {\n padding: 10px 8px;\n }\n\n .mode-btn span {\n font-size: 11px;\n }\n\n .function-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle {\n flex-direction: column;\n }\n}\n"] }]
936
+ }], () => [{ type: i0.ChangeDetectorRef }], { Entity: [{
937
+ type: Input
938
+ }], Aggregate: [{
939
+ type: Input
940
+ }], IsOpen: [{
941
+ type: Input
942
+ }], Close: [{
943
+ type: Output
944
+ }], Save: [{
945
+ type: Output
946
+ }] }); })();
947
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AggregateSetupDialogComponent, { className: "AggregateSetupDialogComponent", filePath: "src/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.ts", lineNumber: 55 }); })();
948
+ //# sourceMappingURL=aggregate-setup-dialog.component.js.map