@memberjunction/ng-entity-viewer 3.4.0 → 4.0.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 (34) hide show
  1. package/dist/lib/aggregate-panel/aggregate-panel.component.d.ts.map +1 -1
  2. package/dist/lib/aggregate-panel/aggregate-panel.component.js +36 -35
  3. package/dist/lib/aggregate-panel/aggregate-panel.component.js.map +1 -1
  4. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts.map +1 -1
  5. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +15 -12
  6. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js.map +1 -1
  7. package/dist/lib/entity-cards/entity-cards.component.d.ts.map +1 -1
  8. package/dist/lib/entity-cards/entity-cards.component.js +14 -13
  9. package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
  10. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +1 -1
  11. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  12. package/dist/lib/entity-data-grid/entity-data-grid.component.js +280 -266
  13. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  14. package/dist/lib/entity-grid/entity-grid.component.d.ts +216 -0
  15. package/dist/lib/entity-grid/entity-grid.component.d.ts.map +1 -0
  16. package/dist/lib/entity-grid/entity-grid.component.js +676 -0
  17. package/dist/lib/entity-grid/entity-grid.component.js.map +1 -0
  18. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.d.ts.map +1 -1
  19. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +16 -15
  20. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js.map +1 -1
  21. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +1 -1
  22. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  23. package/dist/lib/entity-viewer/entity-viewer.component.js +13 -10
  24. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  25. package/dist/lib/pagination/pagination.component.d.ts.map +1 -1
  26. package/dist/lib/pagination/pagination.component.js +8 -6
  27. package/dist/lib/pagination/pagination.component.js.map +1 -1
  28. package/dist/lib/pill/pill.component.d.ts.map +1 -1
  29. package/dist/lib/pill/pill.component.js +3 -3
  30. package/dist/lib/pill/pill.component.js.map +1 -1
  31. package/dist/lib/view-config-panel/view-config-panel.component.d.ts.map +1 -1
  32. package/dist/lib/view-config-panel/view-config-panel.component.js +56 -43
  33. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  34. package/package.json +19 -19
@@ -64,7 +64,7 @@ function ViewConfigPanelComponent_Conditional_30_For_10_Conditional_6_Template(r
64
64
  i0.ɵɵelement(0, "i", 42);
65
65
  } if (rf & 2) {
66
66
  const column_r4 = i0.ɵɵnextContext().$implicit;
67
- i0.ɵɵpropertyInterpolate1("title", "Custom name: ", column_r4.userDisplayName, "");
67
+ i0.ɵɵproperty("title", i0.ɵɵinterpolate1("Custom name: ", column_r4.userDisplayName));
68
68
  } }
69
69
  function ViewConfigPanelComponent_Conditional_30_For_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
70
70
  i0.ɵɵelement(0, "i", 43);
@@ -74,7 +74,7 @@ function ViewConfigPanelComponent_Conditional_30_For_10_Conditional_17_Template(
74
74
  } }
75
75
  function ViewConfigPanelComponent_Conditional_30_For_10_Template(rf, ctx) { if (rf & 1) {
76
76
  const _r3 = i0.ɵɵgetCurrentView();
77
- i0.ɵɵtemplate(0, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_0_Template, 1, 0, "div", 37);
77
+ i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_0_Template, 1, 0, "div", 37);
78
78
  i0.ɵɵelementStart(1, "div", 38);
79
79
  i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_30_For_10_Template_div_dragstart_1_listener($event) { const column_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDragStart($event, column_r4)); })("dragover", function ViewConfigPanelComponent_Conditional_30_For_10_Template_div_dragover_1_listener($event) { const column_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDragOver($event, column_r4)); })("dragleave", function ViewConfigPanelComponent_Conditional_30_For_10_Template_div_dragleave_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDragLeave($event)); })("drop", function ViewConfigPanelComponent_Conditional_30_For_10_Template_div_drop_1_listener($event) { const column_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDrop($event, column_r4)); })("dragend", function ViewConfigPanelComponent_Conditional_30_For_10_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onDragEnd($event)); });
80
80
  i0.ɵɵelementStart(2, "div", 39);
@@ -82,7 +82,8 @@ function ViewConfigPanelComponent_Conditional_30_For_10_Template(rf, ctx) { if (
82
82
  i0.ɵɵelementEnd();
83
83
  i0.ɵɵelementStart(4, "span", 41);
84
84
  i0.ɵɵtext(5);
85
- i0.ɵɵtemplate(6, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_6_Template, 1, 2, "i", 42)(7, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_7_Template, 1, 0, "i", 43);
85
+ i0.ɵɵconditionalCreate(6, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_6_Template, 1, 2, "i", 42);
86
+ i0.ɵɵconditionalCreate(7, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_7_Template, 1, 0, "i", 43);
86
87
  i0.ɵɵelementEnd();
87
88
  i0.ɵɵelementStart(8, "div", 44)(9, "button", 45);
88
89
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_For_10_Template_button_click_9_listener() { const column_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openFormatEditor(column_r4)); });
@@ -100,7 +101,7 @@ function ViewConfigPanelComponent_Conditional_30_For_10_Template(rf, ctx) { if (
100
101
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_30_For_10_Template_button_click_15_listener() { const column_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleColumnVisibility(column_r4)); });
101
102
  i0.ɵɵelement(16, "i", 33);
102
103
  i0.ɵɵelementEnd()()();
103
- i0.ɵɵtemplate(17, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_17_Template, 1, 0, "div", 37);
104
+ i0.ɵɵconditionalCreate(17, ViewConfigPanelComponent_Conditional_30_For_10_Conditional_17_Template, 1, 0, "div", 37);
104
105
  } if (rf & 2) {
105
106
  const column_r4 = ctx.$implicit;
106
107
  const ɵ$index_92_r5 = ctx.$index;
@@ -172,7 +173,7 @@ function ViewConfigPanelComponent_Conditional_30_Template(rf, ctx) { if (rf & 1)
172
173
  i0.ɵɵelementEnd()();
173
174
  i0.ɵɵelementStart(8, "div", 31);
174
175
  i0.ɵɵrepeaterCreate(9, ViewConfigPanelComponent_Conditional_30_For_10_Template, 18, 11, null, null, _forTrack0);
175
- i0.ɵɵtemplate(11, ViewConfigPanelComponent_Conditional_30_Conditional_11_Template, 4, 0, "div", 32);
176
+ i0.ɵɵconditionalCreate(11, ViewConfigPanelComponent_Conditional_30_Conditional_11_Template, 4, 0, "div", 32);
176
177
  i0.ɵɵelementEnd()();
177
178
  i0.ɵɵelementStart(12, "div", 27)(13, "div", 28);
178
179
  i0.ɵɵelement(14, "i", 33);
@@ -182,10 +183,10 @@ function ViewConfigPanelComponent_Conditional_30_Template(rf, ctx) { if (rf & 1)
182
183
  i0.ɵɵelementStart(17, "span", 30);
183
184
  i0.ɵɵtext(18);
184
185
  i0.ɵɵelementEnd()();
185
- i0.ɵɵtemplate(19, ViewConfigPanelComponent_Conditional_30_Conditional_19_Template, 3, 1, "div", 34);
186
+ i0.ɵɵconditionalCreate(19, ViewConfigPanelComponent_Conditional_30_Conditional_19_Template, 3, 1, "div", 34);
186
187
  i0.ɵɵelementStart(20, "div", 35);
187
188
  i0.ɵɵrepeaterCreate(21, ViewConfigPanelComponent_Conditional_30_For_22_Template, 5, 1, "div", 36, _forTrack0);
188
- i0.ɵɵtemplate(23, ViewConfigPanelComponent_Conditional_30_Conditional_23_Template, 4, 0, "div", 32);
189
+ i0.ɵɵconditionalCreate(23, ViewConfigPanelComponent_Conditional_30_Conditional_23_Template, 4, 0, "div", 32);
189
190
  i0.ɵɵelementEnd()()();
190
191
  } if (rf & 2) {
191
192
  const ctx_r1 = i0.ɵɵnextContext();
@@ -216,7 +217,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_16_Template(rf, ctx
216
217
  } if (rf & 2) {
217
218
  const ctx_r1 = i0.ɵɵnextContext(2);
218
219
  i0.ɵɵadvance(2);
219
- i0.ɵɵtextInterpolate1("Original: ", ctx_r1.formatEditingColumn.displayName, "");
220
+ i0.ɵɵtextInterpolate1("Original: ", ctx_r1.formatEditingColumn.displayName);
220
221
  } }
221
222
  function ViewConfigPanelComponent_Conditional_31_For_26_Template(rf, ctx) { if (rf & 1) {
222
223
  i0.ɵɵelementStart(0, "div", 105);
@@ -272,7 +273,7 @@ function ViewConfigPanelComponent_Conditional_31_Conditional_49_Template(rf, ctx
272
273
  i0.ɵɵelementStart(8, "input", 107);
273
274
  i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_31_Conditional_49_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.formatEditingColumn.format.decimals, $event) || (ctx_r1.formatEditingColumn.format.decimals = $event); return i0.ɵɵresetView($event); });
274
275
  i0.ɵɵelementEnd()();
275
- i0.ɵɵtemplate(9, ViewConfigPanelComponent_Conditional_31_Conditional_49_Conditional_9_Template, 16, 1, "div", 65);
276
+ i0.ɵɵconditionalCreate(9, ViewConfigPanelComponent_Conditional_31_Conditional_49_Conditional_9_Template, 16, 1, "div", 65);
276
277
  i0.ɵɵelementStart(10, "div", 65)(11, "label");
277
278
  i0.ɵɵtext(12, "Thousands Separator");
278
279
  i0.ɵɵelementEnd();
@@ -385,7 +386,7 @@ function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1)
385
386
  i0.ɵɵelementStart(15, "input", 66);
386
387
  i0.ɵɵlistener("input", function ViewConfigPanelComponent_Conditional_31_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateUserDisplayName($event.target.value)); });
387
388
  i0.ɵɵelementEnd()();
388
- i0.ɵɵtemplate(16, ViewConfigPanelComponent_Conditional_31_Conditional_16_Template, 5, 1, "div", 67);
389
+ i0.ɵɵconditionalCreate(16, ViewConfigPanelComponent_Conditional_31_Conditional_16_Template, 5, 1, "div", 67);
389
390
  i0.ɵɵelementEnd();
390
391
  i0.ɵɵelementStart(17, "div", 68)(18, "div", 69);
391
392
  i0.ɵɵelement(19, "i", 29);
@@ -428,7 +429,9 @@ function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1)
428
429
  i0.ɵɵelementStart(47, "option", 82);
429
430
  i0.ɵɵtext(48, "Boolean");
430
431
  i0.ɵɵelementEnd()()();
431
- i0.ɵɵtemplate(49, ViewConfigPanelComponent_Conditional_31_Conditional_49_Template, 14, 3, "div", 62)(50, ViewConfigPanelComponent_Conditional_31_Conditional_50_Template, 21, 1, "div", 62)(51, ViewConfigPanelComponent_Conditional_31_Conditional_51_Template, 23, 3, "div", 62);
432
+ i0.ɵɵconditionalCreate(49, ViewConfigPanelComponent_Conditional_31_Conditional_49_Template, 14, 3, "div", 62);
433
+ i0.ɵɵconditionalCreate(50, ViewConfigPanelComponent_Conditional_31_Conditional_50_Template, 21, 1, "div", 62);
434
+ i0.ɵɵconditionalCreate(51, ViewConfigPanelComponent_Conditional_31_Conditional_51_Template, 23, 3, "div", 62);
432
435
  i0.ɵɵelementStart(52, "div", 62)(53, "div", 63);
433
436
  i0.ɵɵelement(54, "i", 83);
434
437
  i0.ɵɵelementStart(55, "span");
@@ -512,7 +515,7 @@ function ViewConfigPanelComponent_Conditional_31_Template(rf, ctx) { if (rf & 1)
512
515
  } if (rf & 2) {
513
516
  const ctx_r1 = i0.ɵɵnextContext();
514
517
  i0.ɵɵadvance(6);
515
- i0.ɵɵtextInterpolate1("Format: ", ctx_r1.formatEditingColumn.userDisplayName || ctx_r1.formatEditingColumn.displayName, "");
518
+ i0.ɵɵtextInterpolate1("Format: ", ctx_r1.formatEditingColumn.userDisplayName || ctx_r1.formatEditingColumn.displayName);
516
519
  i0.ɵɵadvance(9);
517
520
  i0.ɵɵproperty("value", ctx_r1.formatEditingColumn.userDisplayName || "")("placeholder", ctx_r1.formatEditingColumn.displayName);
518
521
  i0.ɵɵadvance();
@@ -576,7 +579,7 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional
576
579
  } }
577
580
  function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template(rf, ctx) { if (rf & 1) {
578
581
  const _r17 = i0.ɵɵgetCurrentView();
579
- i0.ɵɵtemplate(0, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_0_Template, 1, 0, "div", 134);
582
+ i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_0_Template, 1, 0, "div", 134);
580
583
  i0.ɵɵelementStart(1, "div", 135);
581
584
  i0.ɵɵlistener("dragstart", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_div_dragstart_1_listener($event) { const sortItem_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSortDragStart($event, sortItem_r18)); })("dragover", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_div_dragover_1_listener($event) { const sortItem_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSortDragOver($event, sortItem_r18)); })("dragleave", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_div_dragleave_1_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSortDragLeave($event)); })("drop", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_div_drop_1_listener($event) { const sortItem_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSortDrop($event, sortItem_r18)); })("dragend", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSortDragEnd($event)); });
582
585
  i0.ɵɵelementStart(2, "div", 136);
@@ -602,7 +605,7 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template(rf
602
605
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template_button_click_14_listener() { const sortItem_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.removeSortLevel(sortItem_r18)); });
603
606
  i0.ɵɵelement(15, "i", 8);
604
607
  i0.ɵɵelementEnd()();
605
- i0.ɵɵtemplate(16, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_16_Template, 1, 0, "div", 134);
608
+ i0.ɵɵconditionalCreate(16, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Conditional_16_Template, 1, 0, "div", 134);
606
609
  } if (rf & 2) {
607
610
  const sortItem_r18 = ctx.$implicit;
608
611
  const ɵ$index_521_r20 = ctx.$index;
@@ -639,7 +642,7 @@ function ViewConfigPanelComponent_Conditional_32_Conditional_9_Template(rf, ctx)
639
642
  i0.ɵɵelementStart(0, "div", 132);
640
643
  i0.ɵɵrepeaterCreate(1, ViewConfigPanelComponent_Conditional_32_Conditional_9_For_2_Template, 17, 16, null, null, i0.ɵɵrepeaterTrackByIndex);
641
644
  i0.ɵɵelementEnd();
642
- i0.ɵɵtemplate(3, ViewConfigPanelComponent_Conditional_32_Conditional_9_Conditional_3_Template, 4, 0, "div", 133);
645
+ i0.ɵɵconditionalCreate(3, ViewConfigPanelComponent_Conditional_32_Conditional_9_Conditional_3_Template, 4, 0, "div", 133);
643
646
  } if (rf & 2) {
644
647
  const ctx_r1 = i0.ɵɵnextContext(2);
645
648
  i0.ɵɵadvance();
@@ -668,7 +671,7 @@ function ViewConfigPanelComponent_Conditional_32_Template(rf, ctx) { if (rf & 1)
668
671
  i0.ɵɵelementStart(7, "span");
669
672
  i0.ɵɵtext(8, "Add Sort Level");
670
673
  i0.ɵɵelementEnd()();
671
- i0.ɵɵtemplate(9, ViewConfigPanelComponent_Conditional_32_Conditional_9_Template, 4, 1)(10, ViewConfigPanelComponent_Conditional_32_Conditional_10_Template, 6, 0, "div", 131);
674
+ i0.ɵɵconditionalCreate(9, ViewConfigPanelComponent_Conditional_32_Conditional_9_Template, 4, 1)(10, ViewConfigPanelComponent_Conditional_32_Conditional_10_Template, 6, 0, "div", 131);
672
675
  i0.ɵɵelementEnd()();
673
676
  } if (rf & 2) {
674
677
  const ctx_r1 = i0.ɵɵnextContext();
@@ -702,7 +705,7 @@ function ViewConfigPanelComponent_Conditional_33_Conditional_20_Template(rf, ctx
702
705
  i0.ɵɵelementStart(4, "textarea", 159);
703
706
  i0.ɵɵtwoWayListener("ngModelChange", function ViewConfigPanelComponent_Conditional_33_Conditional_20_Template_textarea_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.smartFilterPrompt, $event) || (ctx_r1.smartFilterPrompt = $event); return i0.ɵɵresetView($event); });
704
707
  i0.ɵɵelementEnd()();
705
- i0.ɵɵtemplate(5, ViewConfigPanelComponent_Conditional_33_Conditional_20_Conditional_5_Template, 4, 1, "div", 160);
708
+ i0.ɵɵconditionalCreate(5, ViewConfigPanelComponent_Conditional_33_Conditional_20_Conditional_5_Template, 4, 1, "div", 160);
706
709
  i0.ɵɵelementStart(6, "div", 161)(7, "div", 162);
707
710
  i0.ɵɵelement(8, "i", 163);
708
711
  i0.ɵɵelementStart(9, "span");
@@ -779,10 +782,10 @@ function ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_7_Te
779
782
  function ViewConfigPanelComponent_Conditional_33_Conditional_21_Template(rf, ctx) { if (rf & 1) {
780
783
  const _r23 = i0.ɵɵgetCurrentView();
781
784
  i0.ɵɵelementStart(0, "div", 156)(1, "div", 172)(2, "div", 173)(3, "div", 174);
782
- i0.ɵɵtemplate(4, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_4_Template, 4, 2)(5, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_5_Template, 2, 0, "span", 175);
785
+ i0.ɵɵconditionalCreate(4, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_4_Template, 4, 2)(5, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_5_Template, 2, 0, "span", 175);
783
786
  i0.ɵɵelementEnd();
784
787
  i0.ɵɵelementStart(6, "div", 176);
785
- i0.ɵɵtemplate(7, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_7_Template, 3, 0, "button", 177);
788
+ i0.ɵɵconditionalCreate(7, ViewConfigPanelComponent_Conditional_33_Conditional_21_Conditional_7_Template, 3, 0, "button", 177);
786
789
  i0.ɵɵelementStart(8, "button", 178);
787
790
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_33_Conditional_21_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openFilterDialog()); });
788
791
  i0.ɵɵelement(9, "i", 179);
@@ -817,7 +820,7 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
817
820
  i0.ɵɵelementStart(8, "span", 153);
818
821
  i0.ɵɵtext(9, "Use AI to filter with natural language");
819
822
  i0.ɵɵelementEnd()();
820
- i0.ɵɵtemplate(10, ViewConfigPanelComponent_Conditional_33_Conditional_10_Template, 1, 0, "i", 154);
823
+ i0.ɵɵconditionalCreate(10, ViewConfigPanelComponent_Conditional_33_Conditional_10_Template, 1, 0, "i", 154);
821
824
  i0.ɵɵelementEnd();
822
825
  i0.ɵɵelementStart(11, "button", 148);
823
826
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_33_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setFilterMode("traditional")); });
@@ -830,9 +833,10 @@ function ViewConfigPanelComponent_Conditional_33_Template(rf, ctx) { if (rf & 1)
830
833
  i0.ɵɵelementStart(17, "span", 153);
831
834
  i0.ɵɵtext(18, "Build filters with field/operator/value");
832
835
  i0.ɵɵelementEnd()();
833
- i0.ɵɵtemplate(19, ViewConfigPanelComponent_Conditional_33_Conditional_19_Template, 1, 0, "i", 154);
836
+ i0.ɵɵconditionalCreate(19, ViewConfigPanelComponent_Conditional_33_Conditional_19_Template, 1, 0, "i", 154);
834
837
  i0.ɵɵelementEnd()();
835
- i0.ɵɵtemplate(20, ViewConfigPanelComponent_Conditional_33_Conditional_20_Template, 28, 7, "div", 155)(21, ViewConfigPanelComponent_Conditional_33_Conditional_21_Template, 15, 4, "div", 156);
838
+ i0.ɵɵconditionalCreate(20, ViewConfigPanelComponent_Conditional_33_Conditional_20_Template, 28, 7, "div", 155);
839
+ i0.ɵɵconditionalCreate(21, ViewConfigPanelComponent_Conditional_33_Conditional_21_Template, 15, 4, "div", 156);
836
840
  i0.ɵɵelementEnd();
837
841
  } if (rf & 2) {
838
842
  const ctx_r1 = i0.ɵɵnextContext();
@@ -868,7 +872,7 @@ function ViewConfigPanelComponent_Conditional_34_Conditional_9_For_2_Template(rf
868
872
  i0.ɵɵelement(8, "i");
869
873
  i0.ɵɵtext(9);
870
874
  i0.ɵɵelementEnd();
871
- i0.ɵɵtemplate(10, ViewConfigPanelComponent_Conditional_34_Conditional_9_For_2_Conditional_10_Template, 2, 0, "span", 202);
875
+ i0.ɵɵconditionalCreate(10, ViewConfigPanelComponent_Conditional_34_Conditional_9_For_2_Conditional_10_Template, 2, 0, "span", 202);
872
876
  i0.ɵɵelementEnd()();
873
877
  i0.ɵɵelementStart(11, "div", 203)(12, "button", 204);
874
878
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_34_Conditional_9_For_2_Template_button_click_12_listener() { const agg_r27 = i0.ɵɵrestoreView(_r26).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.moveAggregateUp(agg_r27)); });
@@ -938,9 +942,9 @@ function ViewConfigPanelComponent_Conditional_34_Conditional_9_Template(rf, ctx)
938
942
  i0.ɵɵadvance();
939
943
  i0.ɵɵrepeater(ctx_r1.aggregates);
940
944
  i0.ɵɵadvance(6);
941
- i0.ɵɵtextInterpolate2("", ctx_r1.cardAggregates.length, " card", ctx_r1.cardAggregates.length !== 1 ? "s" : "", "");
945
+ i0.ɵɵtextInterpolate2("", ctx_r1.cardAggregates.length, " card", ctx_r1.cardAggregates.length !== 1 ? "s" : "");
942
946
  i0.ɵɵadvance(4);
943
- i0.ɵɵtextInterpolate2("", ctx_r1.columnAggregates.length, " column footer", ctx_r1.columnAggregates.length !== 1 ? "s" : "", "");
947
+ i0.ɵɵtextInterpolate2("", ctx_r1.columnAggregates.length, " column footer", ctx_r1.columnAggregates.length !== 1 ? "s" : "");
944
948
  } }
945
949
  function ViewConfigPanelComponent_Conditional_34_Conditional_10_Template(rf, ctx) { if (rf & 1) {
946
950
  i0.ɵɵelementStart(0, "div", 188);
@@ -963,7 +967,7 @@ function ViewConfigPanelComponent_Conditional_34_Template(rf, ctx) { if (rf & 1)
963
967
  i0.ɵɵelementStart(7, "span");
964
968
  i0.ɵɵtext(8, "Add Aggregate");
965
969
  i0.ɵɵelementEnd()();
966
- i0.ɵɵtemplate(9, ViewConfigPanelComponent_Conditional_34_Conditional_9_Template, 12, 4)(10, ViewConfigPanelComponent_Conditional_34_Conditional_10_Template, 6, 0, "div", 188);
970
+ i0.ɵɵconditionalCreate(9, ViewConfigPanelComponent_Conditional_34_Conditional_9_Template, 12, 4)(10, ViewConfigPanelComponent_Conditional_34_Conditional_10_Template, 6, 0, "div", 188);
967
971
  i0.ɵɵelementStart(11, "div", 189);
968
972
  i0.ɵɵelement(12, "i", 52);
969
973
  i0.ɵɵelementStart(13, "span");
@@ -1023,7 +1027,7 @@ function ViewConfigPanelComponent_Conditional_35_Template(rf, ctx) { if (rf & 1)
1023
1027
  i0.ɵɵelementStart(24, "small");
1024
1028
  i0.ɵɵtext(25, "Allow other users to use this view");
1025
1029
  i0.ɵɵelementEnd()()()();
1026
- i0.ɵɵtemplate(26, ViewConfigPanelComponent_Conditional_35_Conditional_26_Template, 9, 0, "div", 220);
1030
+ i0.ɵɵconditionalCreate(26, ViewConfigPanelComponent_Conditional_35_Conditional_26_Template, 9, 0, "div", 220);
1027
1031
  i0.ɵɵelementEnd();
1028
1032
  } if (rf & 2) {
1029
1033
  const ctx_r1 = i0.ɵɵnextContext();
@@ -1049,7 +1053,7 @@ function ViewConfigPanelComponent_Conditional_38_Template(rf, ctx) { if (rf & 1)
1049
1053
  const _r31 = i0.ɵɵgetCurrentView();
1050
1054
  i0.ɵɵelementStart(0, "button", 223);
1051
1055
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_38_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSave()); });
1052
- i0.ɵɵtemplate(1, ViewConfigPanelComponent_Conditional_38_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_38_Conditional_2_Template, 1, 0, "i", 225);
1056
+ i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_38_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_38_Conditional_2_Template, 1, 0, "i", 225);
1053
1057
  i0.ɵɵtext(3);
1054
1058
  i0.ɵɵelementEnd();
1055
1059
  } if (rf & 2) {
@@ -1076,12 +1080,12 @@ function ViewConfigPanelComponent_Conditional_39_Template(rf, ctx) { if (rf & 1)
1076
1080
  const _r32 = i0.ɵɵgetCurrentView();
1077
1081
  i0.ɵɵelementStart(0, "button", 223);
1078
1082
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_39_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSaveDefaults()); });
1079
- i0.ɵɵtemplate(1, ViewConfigPanelComponent_Conditional_39_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_39_Conditional_2_Template, 1, 0, "i", 225);
1083
+ i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_39_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_39_Conditional_2_Template, 1, 0, "i", 225);
1080
1084
  i0.ɵɵtext(3);
1081
1085
  i0.ɵɵelementEnd();
1082
1086
  i0.ɵɵelementStart(4, "button", 226);
1083
1087
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_39_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSaveAsNew()); });
1084
- i0.ɵɵtemplate(5, ViewConfigPanelComponent_Conditional_39_Conditional_5_Template, 1, 0, "i", 224)(6, ViewConfigPanelComponent_Conditional_39_Conditional_6_Template, 1, 0, "i", 56);
1088
+ i0.ɵɵconditionalCreate(5, ViewConfigPanelComponent_Conditional_39_Conditional_5_Template, 1, 0, "i", 224)(6, ViewConfigPanelComponent_Conditional_39_Conditional_6_Template, 1, 0, "i", 56);
1085
1089
  i0.ɵɵtext(7);
1086
1090
  i0.ɵɵelementEnd();
1087
1091
  } if (rf & 2) {
@@ -1108,7 +1112,7 @@ function ViewConfigPanelComponent_Conditional_40_Template(rf, ctx) { if (rf & 1)
1108
1112
  const _r33 = i0.ɵɵgetCurrentView();
1109
1113
  i0.ɵɵelementStart(0, "button", 226);
1110
1114
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Conditional_40_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSaveAsNew()); });
1111
- i0.ɵɵtemplate(1, ViewConfigPanelComponent_Conditional_40_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_40_Conditional_2_Template, 1, 0, "i", 56);
1115
+ i0.ɵɵconditionalCreate(1, ViewConfigPanelComponent_Conditional_40_Conditional_1_Template, 1, 0, "i", 224)(2, ViewConfigPanelComponent_Conditional_40_Conditional_2_Template, 1, 0, "i", 56);
1112
1116
  i0.ɵɵtext(3, " Save As New ");
1113
1117
  i0.ɵɵelementEnd();
1114
1118
  } if (rf & 2) {
@@ -2557,9 +2561,9 @@ export class ViewConfigPanelComponent {
2557
2561
  }
2558
2562
  static ɵfac = function ViewConfigPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ViewConfigPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
2559
2563
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewConfigPanelComponent, selectors: [["mj-view-config-panel"]], hostBindings: function ViewConfigPanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
2560
- i0.ɵɵlistener("keydown.escape", function ViewConfigPanelComponent_keydown_escape_HostBindingHandler() { return ctx.handleEscape(); }, false, i0.ɵɵresolveDocument);
2561
- } }, inputs: { entity: "entity", viewEntity: "viewEntity", isOpen: "isOpen", currentGridState: "currentGridState", sampleData: "sampleData", externalFilterState: "externalFilterState", isSaving: "isSaving" }, outputs: { close: "close", save: "save", saveDefaults: "saveDefaults", delete: "delete", openFilterDialogRequest: "openFilterDialogRequest" }, features: [i0.ɵɵNgOnChangesFeature], decls: 44, vars: 44, 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", 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, "fa-solid", "fa-cog"], [1, "panel-content"], [1, "tab-content"], [1, "format-editor"], [1, "panel-footer"], [1, "footer-left"], [1, "footer-btn", "save-btn", "primary", 3, "disabled"], [1, "footer-btn", "save-as-btn", 3, "disabled"], [1, "footer-btn", "cancel-btn", 3, "click"], [3, "Close", "Save", "Entity", "Aggregate", "IsOpen"], [1, "panel-backdrop", 3, "click"], [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", 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"], ["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"], [1, "footer-btn", "save-as-btn", 3, "click", "disabled"]], template: function ViewConfigPanelComponent_Template(rf, ctx) { if (rf & 1) {
2562
- i0.ɵɵtemplate(0, ViewConfigPanelComponent_Conditional_0_Template, 1, 0, "div", 0);
2564
+ i0.ɵɵlistener("keydown.escape", function ViewConfigPanelComponent_keydown_escape_HostBindingHandler() { return ctx.handleEscape(); }, i0.ɵɵresolveDocument);
2565
+ } }, inputs: { entity: "entity", viewEntity: "viewEntity", isOpen: "isOpen", currentGridState: "currentGridState", sampleData: "sampleData", externalFilterState: "externalFilterState", isSaving: "isSaving" }, outputs: { close: "close", save: "save", saveDefaults: "saveDefaults", delete: "delete", openFilterDialogRequest: "openFilterDialogRequest" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 44, vars: 44, 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", 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, "fa-solid", "fa-cog"], [1, "panel-content"], [1, "tab-content"], [1, "format-editor"], [1, "panel-footer"], [1, "footer-left"], [1, "footer-btn", "save-btn", "primary", 3, "disabled"], [1, "footer-btn", "save-as-btn", 3, "disabled"], [1, "footer-btn", "cancel-btn", 3, "click"], [3, "Close", "Save", "Entity", "Aggregate", "IsOpen"], [1, "panel-backdrop", 3, "click"], [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", 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"], ["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"], [1, "footer-btn", "save-as-btn", 3, "click", "disabled"]], template: function ViewConfigPanelComponent_Template(rf, ctx) { if (rf & 1) {
2566
+ i0.ɵɵconditionalCreate(0, ViewConfigPanelComponent_Conditional_0_Template, 1, 0, "div", 0);
2563
2567
  i0.ɵɵelementStart(1, "div", 1)(2, "div", 2);
2564
2568
  i0.ɵɵlistener("mousedown", function ViewConfigPanelComponent_Template_div_mousedown_2_listener($event) { return ctx.onResizeStart($event); });
2565
2569
  i0.ɵɵelement(3, "div", 3);
@@ -2576,33 +2580,42 @@ export class ViewConfigPanelComponent {
2576
2580
  i0.ɵɵelementStart(11, "div", 9)(12, "button", 10);
2577
2581
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_12_listener() { return ctx.setActiveTab("columns"); });
2578
2582
  i0.ɵɵelement(13, "i", 11);
2579
- i0.ɵɵtemplate(14, ViewConfigPanelComponent_Conditional_14_Template, 2, 0, "span");
2583
+ i0.ɵɵconditionalCreate(14, ViewConfigPanelComponent_Conditional_14_Template, 2, 0, "span");
2580
2584
  i0.ɵɵelementEnd();
2581
2585
  i0.ɵɵelementStart(15, "button", 10);
2582
2586
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_15_listener() { return ctx.setActiveTab("sorting"); });
2583
2587
  i0.ɵɵelement(16, "i", 12);
2584
- i0.ɵɵtemplate(17, ViewConfigPanelComponent_Conditional_17_Template, 2, 0, "span")(18, ViewConfigPanelComponent_Conditional_18_Template, 2, 1, "span", 13);
2588
+ i0.ɵɵconditionalCreate(17, ViewConfigPanelComponent_Conditional_17_Template, 2, 0, "span");
2589
+ i0.ɵɵconditionalCreate(18, ViewConfigPanelComponent_Conditional_18_Template, 2, 1, "span", 13);
2585
2590
  i0.ɵɵelementEnd();
2586
2591
  i0.ɵɵelementStart(19, "button", 10);
2587
2592
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_19_listener() { return ctx.setActiveTab("filters"); });
2588
2593
  i0.ɵɵelement(20, "i", 14);
2589
- i0.ɵɵtemplate(21, ViewConfigPanelComponent_Conditional_21_Template, 2, 0, "span");
2594
+ i0.ɵɵconditionalCreate(21, ViewConfigPanelComponent_Conditional_21_Template, 2, 0, "span");
2590
2595
  i0.ɵɵelementEnd();
2591
2596
  i0.ɵɵelementStart(22, "button", 10);
2592
2597
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_22_listener() { return ctx.setActiveTab("aggregates"); });
2593
2598
  i0.ɵɵelement(23, "i", 15);
2594
- i0.ɵɵtemplate(24, ViewConfigPanelComponent_Conditional_24_Template, 2, 0, "span")(25, ViewConfigPanelComponent_Conditional_25_Template, 2, 1, "span", 13);
2599
+ i0.ɵɵconditionalCreate(24, ViewConfigPanelComponent_Conditional_24_Template, 2, 0, "span");
2600
+ i0.ɵɵconditionalCreate(25, ViewConfigPanelComponent_Conditional_25_Template, 2, 1, "span", 13);
2595
2601
  i0.ɵɵelementEnd();
2596
2602
  i0.ɵɵelementStart(26, "button", 10);
2597
2603
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_26_listener() { return ctx.setActiveTab("settings"); });
2598
2604
  i0.ɵɵelement(27, "i", 16);
2599
- i0.ɵɵtemplate(28, ViewConfigPanelComponent_Conditional_28_Template, 2, 0, "span");
2605
+ i0.ɵɵconditionalCreate(28, ViewConfigPanelComponent_Conditional_28_Template, 2, 0, "span");
2600
2606
  i0.ɵɵelementEnd()();
2601
2607
  i0.ɵɵelementStart(29, "div", 17);
2602
- i0.ɵɵtemplate(30, ViewConfigPanelComponent_Conditional_30_Template, 24, 5, "div", 18)(31, ViewConfigPanelComponent_Conditional_31_Template, 108, 41, "div", 19)(32, ViewConfigPanelComponent_Conditional_32_Template, 11, 2, "div", 18)(33, ViewConfigPanelComponent_Conditional_33_Template, 22, 10, "div", 18)(34, ViewConfigPanelComponent_Conditional_34_Template, 15, 2, "div", 18)(35, ViewConfigPanelComponent_Conditional_35_Template, 27, 7, "div", 18);
2608
+ i0.ɵɵconditionalCreate(30, ViewConfigPanelComponent_Conditional_30_Template, 24, 5, "div", 18);
2609
+ i0.ɵɵconditionalCreate(31, ViewConfigPanelComponent_Conditional_31_Template, 108, 41, "div", 19);
2610
+ i0.ɵɵconditionalCreate(32, ViewConfigPanelComponent_Conditional_32_Template, 11, 2, "div", 18);
2611
+ i0.ɵɵconditionalCreate(33, ViewConfigPanelComponent_Conditional_33_Template, 22, 10, "div", 18);
2612
+ i0.ɵɵconditionalCreate(34, ViewConfigPanelComponent_Conditional_34_Template, 15, 2, "div", 18);
2613
+ i0.ɵɵconditionalCreate(35, ViewConfigPanelComponent_Conditional_35_Template, 27, 7, "div", 18);
2603
2614
  i0.ɵɵelementEnd();
2604
2615
  i0.ɵɵelementStart(36, "div", 20)(37, "div", 21);
2605
- i0.ɵɵtemplate(38, ViewConfigPanelComponent_Conditional_38_Template, 4, 3, "button", 22)(39, ViewConfigPanelComponent_Conditional_39_Template, 8, 6)(40, ViewConfigPanelComponent_Conditional_40_Template, 4, 2, "button", 23);
2616
+ i0.ɵɵconditionalCreate(38, ViewConfigPanelComponent_Conditional_38_Template, 4, 3, "button", 22);
2617
+ i0.ɵɵconditionalCreate(39, ViewConfigPanelComponent_Conditional_39_Template, 8, 6);
2618
+ i0.ɵɵconditionalCreate(40, ViewConfigPanelComponent_Conditional_40_Template, 4, 2, "button", 23);
2606
2619
  i0.ɵɵelementEnd();
2607
2620
  i0.ɵɵelementStart(41, "button", 24);
2608
2621
  i0.ɵɵlistener("click", function ViewConfigPanelComponent_Template_button_click_41_listener() { return ctx.onClose(); });
@@ -2673,7 +2686,7 @@ export class ViewConfigPanelComponent {
2673
2686
  }
2674
2687
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewConfigPanelComponent, [{
2675
2688
  type: Component,
2676
- args: [{ 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\">\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 <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 </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\">\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 placeholder=\"Enter view name...\"\n [(ngModel)]=\"viewName\"\n [disabled]=\"!canEdit\"\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 <!-- 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 || !viewName\">\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) {\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 <!-- Save As New - creates a named view -->\n <button\n class=\"footer-btn save-as-btn\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving || !viewName\">\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 ? 'Creating...' : 'Save As New' }}\n </button>\n }\n @if (viewEntity && canEdit) {\n <!-- Save As New for existing view -->\n <button\n class=\"footer-btn save-as-btn\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving\">\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 Save As New\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", 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: 1000;\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: white;\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\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: linear-gradient(90deg, rgba(25, 118, 210, 0.1) 0%, transparent 100%);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: #cbd5e1;\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: #1976d2;\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 #e0e0e0;\n background: #fafafa;\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: #333;\n}\n\n.header-title i {\n color: #1976d2;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\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 color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 2px solid transparent;\n}\n\n.tab-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n.tab-btn.active {\n color: #1976d2;\n border-bottom-color: #1976d2;\n background: transparent;\n}\n\n.tab-btn i {\n font-size: 12px;\n}\n\n.tab-badge {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: 4px;\n}\n\n/* Icon-only mode for narrow panels */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n gap: 4px;\n}\n\n.tab-nav.icon-only .tab-btn i {\n font-size: 14px;\n}\n\n.tab-nav.icon-only .tab-badge {\n margin-left: 0;\n padding: 2px 4px;\n font-size: 9px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow: hidden;\n padding: 16px 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.tab-content {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 24px;\n}\n\n.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: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.column-count {\n margin-left: auto;\n background: #e3f2fd;\n color: #1976d2;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n}\n\n/* Sort Configuration */\n.sort-config {\n display: flex;\n gap: 8px;\n}\n\n.sort-field-select {\n flex: 1;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-direction-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 6px;\n padding: 2px;\n}\n\n.direction-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover {\n color: #333;\n}\n\n.direction-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* ========================================\n MULTI-SORT CONFIGURATION\n ======================================== */\n\n.add-sort-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-sort-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-sort-btn i {\n font-size: 12px;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n/* Sort Item */\n.sort-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.sort-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n border-color: #1976d2;\n}\n\n.sort-item.drop-target {\n border-color: #1976d2;\n}\n\n/* Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n font-size: 12px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n flex-shrink: 0;\n}\n\n/* Drag Handle */\n.sort-drag-handle {\n color: #bdbdbd;\n cursor: grab;\n padding: 4px;\n transition: color 0.15s ease;\n flex-shrink: 0;\n}\n\n.sort-drag-handle:hover {\n color: #757575;\n}\n\n.sort-item.dragging .sort-drag-handle {\n cursor: grabbing;\n color: #1976d2;\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n min-width: 120px;\n padding: 8px 10px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 13px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-field-dropdown:disabled {\n background: #f5f5f5;\n color: #999;\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: 4px;\n cursor: pointer;\n color: #bdbdbd;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: sortDropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes sortDropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\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: #f5f7fa;\n border-radius: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.sort-hint i {\n color: #1976d2;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Sorting Section Styles */\n.sorting-section {\n padding-top: 0;\n}\n\n.sorting-header {\n margin-bottom: 16px;\n}\n\n.sorting-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Sort Empty State */\n.sort-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.sort-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.sort-empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Column Lists */\n.column-list {\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n background: #fafafa;\n}\n\n.column-list.visible-columns {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.column-list.hidden-columns {\n flex: 1;\n min-height: 100px;\n overflow-y: auto;\n}\n\n/* Hidden columns section should expand to fill available space */\n.config-section:last-child {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n margin-bottom: 0;\n}\n\n.column-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.1s ease;\n position: relative;\n}\n\n.column-item:last-child {\n border-bottom: none;\n}\n\n.column-item:hover {\n background: #f5f7fa;\n}\n\n.column-item.hidden {\n background: #fafafa;\n}\n\n.column-item.hidden:hover {\n background: #f0f0f0;\n}\n\n/* ========================================\n DRAG & DROP INDICATOR STYLES\n ======================================== */\n\n/* Drop indicator line element - shows where the column will be placed */\n.drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: dropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes dropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n/* Highlight the column being dragged */\n.column-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n}\n\n/* Visual feedback during drag over */\n.column-item.drag-over {\n background: #f5f7fa;\n}\n\n.drag-handle {\n cursor: grab;\n color: #999;\n padding: 4px;\n transition: color 0.15s ease;\n}\n\n.drag-handle:hover {\n color: #666;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n color: #1976d2;\n}\n\n.column-name {\n flex: 1;\n font-size: 14px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.column-name .format-indicator {\n font-size: 10px;\n color: #1976d2;\n opacity: 0.7;\n}\n\n.column-name .alias-indicator {\n font-size: 10px;\n color: #7b1fa2;\n opacity: 0.8;\n}\n\n.column-actions {\n display: flex;\n gap: 4px;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: #ffebee;\n color: #c62828;\n}\n\n.action-btn.show-btn:hover {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.action-btn.format-btn:hover {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.action-btn.format-btn.has-format {\n color: #1976d2;\n background: #e3f2fd;\n}\n\n.empty-list {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: #999;\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n}\n\n/* ========================================\n COLUMN FORMAT EDITOR SUB-PANEL\n ======================================== */\n\n.format-editor-panel {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: white;\n z-index: 100;\n display: flex;\n flex-direction: column;\n animation: slideInFromRight 0.2s ease;\n}\n\n@keyframes slideInFromRight {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.format-back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-header-title {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.format-header-title span:first-child {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.format-header-title span:last-child {\n font-size: 12px;\n color: #666;\n}\n\n.format-editor-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Format Preview Section */\n.format-preview-section {\n margin-bottom: 24px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-header i {\n color: #3b82f6;\n}\n\n.preview-samples {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.preview-sample {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.preview-label {\n font-size: 12px;\n color: #94a3b8;\n min-width: 60px;\n}\n\n.preview-value {\n flex: 1;\n font-size: 14px;\n font-family: 'SF Mono', 'Monaco', monospace;\n color: #1e293b;\n}\n\n/* Format Type Selection */\n.format-type-section {\n margin-bottom: 24px;\n}\n\n.format-type-section .section-label {\n display: block;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-type-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n}\n\n.format-type-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 12px 8px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-type-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.format-type-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.format-type-btn i {\n font-size: 18px;\n color: #64748b;\n}\n\n.format-type-btn.active i {\n color: #3b82f6;\n}\n\n.format-type-btn span {\n font-size: 11px;\n font-weight: 500;\n color: #64748b;\n}\n\n.format-type-btn.active span {\n color: #1d4ed8;\n}\n\n/* Format Options Section */\n.format-options-section {\n margin-bottom: 24px;\n}\n\n.format-options-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-option-group {\n margin-bottom: 16px;\n}\n\n.format-option-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.format-option-group input,\n.format-option-group select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.format-option-group input:focus,\n.format-option-group select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-option-row {\n display: flex;\n gap: 12px;\n}\n\n.format-option-row .format-option-group {\n flex: 1;\n}\n\n.format-checkbox {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n.format-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.format-checkbox span {\n font-size: 14px;\n color: #333;\n}\n\n/* Alignment Options */\n.alignment-options {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 10px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #3b82f6;\n}\n\n.align-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #3b82f6;\n}\n\n/* Style Section */\n.style-section {\n margin-bottom: 24px;\n}\n\n.style-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.style-toggle-group {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-toggle-btn {\n width: 40px;\n height: 40px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-toggle-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-toggle-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.style-toggle-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.style-toggle-btn.active i {\n color: #3b82f6;\n}\n\n.color-picker-row {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.color-picker-group {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.color-picker-group label {\n font-size: 13px;\n color: #64748b;\n min-width: 80px;\n}\n\n.color-picker-group input[type=\"color\"] {\n width: 40px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.color-clear-btn {\n width: 32px;\n height: 32px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.color-clear-btn:hover {\n background: #f5f5f5;\n color: #666;\n}\n\n/* Format Editor Footer */\n.format-editor-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-footer-left {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.format-footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.format-footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.format-footer-btn.danger {\n color: #c62828;\n border-color: #c62828;\n}\n\n.format-footer-btn.danger:hover:not(:disabled) {\n background: #c62828;\n color: white;\n}\n\n/* Filter Summary Container */\n.filter-summary-container {\n padding: 4px 0;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: #f5f7fa;\n border-radius: 8px;\n border: 1px solid #e8e8e8;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n min-width: 20px;\n text-align: center;\n}\n\n.summary-text {\n font-size: 14px;\n color: #333;\n}\n\n.summary-text.no-filters {\n color: #999;\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: 4px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn i {\n font-size: 11px;\n}\n\n.summary-btn.clear-btn {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.summary-btn.clear-btn:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.summary-btn.edit-btn {\n background: #1976d2;\n color: white;\n}\n\n.summary-btn.edit-btn:hover:not(:disabled) {\n background: #1565c0;\n}\n\n/* ========================================\n FILTER MODE SELECTOR\n ======================================== */\n\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: 14px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.filter-mode-btn.active {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.filter-mode-btn .mode-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: #f3f4f6;\n color: #6b7280;\n font-size: 16px;\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: #3b82f6;\n color: white;\n}\n\n.filter-mode-btn .mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-mode-btn .mode-title {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.filter-mode-btn .mode-subtitle {\n font-size: 12px;\n color: #6b7280;\n}\n\n.filter-mode-btn.active .mode-title {\n color: #1d4ed8;\n}\n\n.filter-mode-btn .mode-check {\n color: #3b82f6;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n/* ========================================\n SMART FILTER SECTION\n ======================================== */\n\n.smart-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 12px;\n margin-bottom: 16px;\n}\n\n.smart-filter-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border-radius: 10px;\n color: white;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.smart-filter-input-container .smart-filter-textarea {\n flex: 1;\n border: none;\n background: white;\n border-radius: 8px;\n padding: 12px;\n font-size: 14px;\n line-height: 1.5;\n resize: none;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea::placeholder {\n color: #9ca3af;\n}\n\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n background: #e3f2fd;\n border-radius: 6px;\n margin-bottom: 12px;\n font-size: 13px;\n color: #1565c0;\n}\n\n.smart-filter-explanation i {\n color: #1976d2;\n font-size: 14px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 16px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.examples-header i {\n color: #f59e0b;\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\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 color: #9ca3af;\n}\n\n.example-chip:hover:not(:disabled) i {\n color: #3b82f6;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.smart-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* ========================================\n TRADITIONAL FILTER SECTION\n ======================================== */\n\n.traditional-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.traditional-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n margin-top: 12px;\n}\n\n.traditional-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n.summary-btn.edit-btn.primary {\n background: #3b82f6;\n color: white;\n border-color: #3b82f6;\n}\n\n.summary-btn.edit-btn.primary:hover:not(:disabled) {\n background: #2563eb;\n border-color: #2563eb;\n}\n\n/* Form Elements */\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: #333;\n}\n\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.form-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.form-input:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 14px;\n color: #333;\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: #666;\n}\n\n/* Danger Zone */\n.danger-zone {\n padding-top: 16px;\n border-top: 1px solid #ffcdd2;\n}\n\n.danger-zone .section-header {\n color: #c62828;\n}\n\n.danger-zone .section-header i {\n color: #c62828;\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #c62828;\n background: transparent;\n border-radius: 6px;\n color: #c62828;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: #c62828;\n color: white;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.footer-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n FORMAT EDITOR INLINE STYLES\n ======================================== */\n\n.format-editor {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n.format-editor .format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0 16px 0;\n border-bottom: 1px solid #e0e0e0;\n margin-bottom: 16px;\n}\n\n.format-editor .back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.format-editor .back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-editor .format-editor-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n/* Preview Table */\n.format-editor .preview-table {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 12px;\n}\n\n.format-editor .preview-header-cell {\n padding: 10px 14px;\n background: #f1f5f9;\n border-radius: 6px;\n font-weight: 600;\n font-size: 13px;\n color: #333;\n}\n\n.format-editor .preview-cell {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 4px;\n font-size: 14px;\n color: #333;\n}\n\n/* Format Section */\n.format-section {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.format-section:last-child {\n border-bottom: none;\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: #333;\n}\n\n.format-section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n/* Format Row */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.format-row:last-child {\n margin-bottom: 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: #555;\n flex-shrink: 0;\n}\n\n/* Format Inputs */\n.format-select {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n min-width: 120px;\n}\n\n.format-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input {\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n}\n\n.format-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input.small {\n width: 80px;\n}\n\n/* Alias Info Row */\n.format-row.alias-info {\n justify-content: flex-start;\n gap: 8px;\n}\n\n.format-row.alias-info .muted-text {\n color: #888;\n font-size: 12px;\n}\n\n.clear-alias-btn {\n width: 20px;\n height: 20px;\n border: none;\n background: #f0f0f0;\n border-radius: 50%;\n color: #888;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n background: #e0e0e0;\n color: #c62828;\n}\n\n/* Color Input */\n.color-input {\n width: 50px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n background: white;\n}\n\n.color-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n width: 40px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.align-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #1976d2;\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 36px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.style-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.style-btn.active i {\n color: #1976d2;\n}\n\n/* Collapsible Format Sections */\n.format-section-collapsible {\n margin-bottom: 12px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.format-section-collapsible summary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n background: #f8fafc;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n list-style: none;\n}\n\n.format-section-collapsible summary::-webkit-details-marker {\n display: none;\n}\n\n.format-section-collapsible summary::before {\n content: '\\f054';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n color: #999;\n transition: transform 0.2s ease;\n}\n\n.format-section-collapsible[open] summary::before {\n transform: rotate(90deg);\n}\n\n.format-section-collapsible summary i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.format-section-collapsible summary span {\n flex: 1;\n}\n\n.format-section-content {\n padding: 14px;\n background: white;\n border-top: 1px solid #e0e0e0;\n}\n\n/* Format Actions */\n.format-actions {\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: #fff5f5;\n border-color: #f87171;\n color: #dc2626;\n}\n\n.clear-format-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n AGGREGATES TAB STYLES\n ======================================== */\n\n.aggregates-section {\n padding-top: 0;\n}\n\n.aggregates-header {\n margin-bottom: 16px;\n}\n\n.aggregates-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Add Aggregate Button */\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-aggregate-btn i {\n font-size: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n/* Aggregate Item */\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.aggregate-item.disabled {\n opacity: 0.6;\n background: #f5f5f5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n border-radius: 8px;\n color: #1976d2;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.aggregate-item.disabled .agg-icon {\n background: #f0f0f0;\n color: #999;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 2px;\n}\n\n.aggregate-item.disabled .agg-label {\n color: #888;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #888;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.agg-type i {\n font-size: 10px;\n}\n\n.agg-smart-badge {\n display: flex;\n align-items: center;\n padding: 2px 6px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-radius: 4px;\n color: #3b82f6;\n font-size: 10px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.agg-action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\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: #2e7d32;\n}\n\n.agg-action-btn.toggle-btn:not(.enabled) {\n color: #bdbdbd;\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 12px 14px;\n background: #f5f7fa;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.summary-item i {\n color: #1976d2;\n font-size: 11px;\n}\n\n/* Aggregates Empty State */\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.aggregates-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Aggregates Tip */\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.aggregates-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .config-panel {\n width: 100% !important;\n max-width: 100vw !important;\n }\n\n /* Hide resize handle on mobile - panel is full width */\n .resize-handle {\n display: none;\n }\n\n .tab-btn span {\n display: none;\n }\n\n .tab-btn {\n padding: 14px;\n }\n\n .tab-btn i {\n font-size: 16px;\n }\n\n .format-type-grid {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n/* Medium screens - limit max resize width */\n@media (min-width: 769px) and (max-width: 1200px) {\n .config-panel {\n max-width: min(600px, 80vw);\n }\n}\n"] }]
2689
+ 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\">\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 <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 </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\">\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 placeholder=\"Enter view name...\"\n [(ngModel)]=\"viewName\"\n [disabled]=\"!canEdit\"\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 <!-- 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 || !viewName\">\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) {\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 <!-- Save As New - creates a named view -->\n <button\n class=\"footer-btn save-as-btn\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving || !viewName\">\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 ? 'Creating...' : 'Save As New' }}\n </button>\n }\n @if (viewEntity && canEdit) {\n <!-- Save As New for existing view -->\n <button\n class=\"footer-btn save-as-btn\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving\">\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 Save As New\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", 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: 1000;\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: white;\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\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: linear-gradient(90deg, rgba(25, 118, 210, 0.1) 0%, transparent 100%);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: #cbd5e1;\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: #1976d2;\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 #e0e0e0;\n background: #fafafa;\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: #333;\n}\n\n.header-title i {\n color: #1976d2;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\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 color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 2px solid transparent;\n}\n\n.tab-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n.tab-btn.active {\n color: #1976d2;\n border-bottom-color: #1976d2;\n background: transparent;\n}\n\n.tab-btn i {\n font-size: 12px;\n}\n\n.tab-badge {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: 4px;\n}\n\n/* Icon-only mode for narrow panels */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n gap: 4px;\n}\n\n.tab-nav.icon-only .tab-btn i {\n font-size: 14px;\n}\n\n.tab-nav.icon-only .tab-badge {\n margin-left: 0;\n padding: 2px 4px;\n font-size: 9px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow: hidden;\n padding: 16px 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.tab-content {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 24px;\n}\n\n.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: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.column-count {\n margin-left: auto;\n background: #e3f2fd;\n color: #1976d2;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n}\n\n/* Sort Configuration */\n.sort-config {\n display: flex;\n gap: 8px;\n}\n\n.sort-field-select {\n flex: 1;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-direction-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 6px;\n padding: 2px;\n}\n\n.direction-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover {\n color: #333;\n}\n\n.direction-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* ========================================\n MULTI-SORT CONFIGURATION\n ======================================== */\n\n.add-sort-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-sort-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-sort-btn i {\n font-size: 12px;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n/* Sort Item */\n.sort-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.sort-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n border-color: #1976d2;\n}\n\n.sort-item.drop-target {\n border-color: #1976d2;\n}\n\n/* Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n font-size: 12px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n flex-shrink: 0;\n}\n\n/* Drag Handle */\n.sort-drag-handle {\n color: #bdbdbd;\n cursor: grab;\n padding: 4px;\n transition: color 0.15s ease;\n flex-shrink: 0;\n}\n\n.sort-drag-handle:hover {\n color: #757575;\n}\n\n.sort-item.dragging .sort-drag-handle {\n cursor: grabbing;\n color: #1976d2;\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n min-width: 120px;\n padding: 8px 10px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 13px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-field-dropdown:disabled {\n background: #f5f5f5;\n color: #999;\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: 4px;\n cursor: pointer;\n color: #bdbdbd;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: sortDropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes sortDropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\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: #f5f7fa;\n border-radius: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.sort-hint i {\n color: #1976d2;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Sorting Section Styles */\n.sorting-section {\n padding-top: 0;\n}\n\n.sorting-header {\n margin-bottom: 16px;\n}\n\n.sorting-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Sort Empty State */\n.sort-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.sort-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.sort-empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Column Lists */\n.column-list {\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n background: #fafafa;\n}\n\n.column-list.visible-columns {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.column-list.hidden-columns {\n flex: 1;\n min-height: 100px;\n overflow-y: auto;\n}\n\n/* Hidden columns section should expand to fill available space */\n.config-section:last-child {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n margin-bottom: 0;\n}\n\n.column-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.1s ease;\n position: relative;\n}\n\n.column-item:last-child {\n border-bottom: none;\n}\n\n.column-item:hover {\n background: #f5f7fa;\n}\n\n.column-item.hidden {\n background: #fafafa;\n}\n\n.column-item.hidden:hover {\n background: #f0f0f0;\n}\n\n/* ========================================\n DRAG & DROP INDICATOR STYLES\n ======================================== */\n\n/* Drop indicator line element - shows where the column will be placed */\n.drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: dropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes dropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n/* Highlight the column being dragged */\n.column-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n}\n\n/* Visual feedback during drag over */\n.column-item.drag-over {\n background: #f5f7fa;\n}\n\n.drag-handle {\n cursor: grab;\n color: #999;\n padding: 4px;\n transition: color 0.15s ease;\n}\n\n.drag-handle:hover {\n color: #666;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n color: #1976d2;\n}\n\n.column-name {\n flex: 1;\n font-size: 14px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.column-name .format-indicator {\n font-size: 10px;\n color: #1976d2;\n opacity: 0.7;\n}\n\n.column-name .alias-indicator {\n font-size: 10px;\n color: #7b1fa2;\n opacity: 0.8;\n}\n\n.column-actions {\n display: flex;\n gap: 4px;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: #ffebee;\n color: #c62828;\n}\n\n.action-btn.show-btn:hover {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.action-btn.format-btn:hover {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.action-btn.format-btn.has-format {\n color: #1976d2;\n background: #e3f2fd;\n}\n\n.empty-list {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: #999;\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n}\n\n/* ========================================\n COLUMN FORMAT EDITOR SUB-PANEL\n ======================================== */\n\n.format-editor-panel {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: white;\n z-index: 100;\n display: flex;\n flex-direction: column;\n animation: slideInFromRight 0.2s ease;\n}\n\n@keyframes slideInFromRight {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.format-back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-header-title {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.format-header-title span:first-child {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.format-header-title span:last-child {\n font-size: 12px;\n color: #666;\n}\n\n.format-editor-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Format Preview Section */\n.format-preview-section {\n margin-bottom: 24px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-header i {\n color: #3b82f6;\n}\n\n.preview-samples {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.preview-sample {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.preview-label {\n font-size: 12px;\n color: #94a3b8;\n min-width: 60px;\n}\n\n.preview-value {\n flex: 1;\n font-size: 14px;\n font-family: 'SF Mono', 'Monaco', monospace;\n color: #1e293b;\n}\n\n/* Format Type Selection */\n.format-type-section {\n margin-bottom: 24px;\n}\n\n.format-type-section .section-label {\n display: block;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-type-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n}\n\n.format-type-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 12px 8px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-type-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.format-type-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.format-type-btn i {\n font-size: 18px;\n color: #64748b;\n}\n\n.format-type-btn.active i {\n color: #3b82f6;\n}\n\n.format-type-btn span {\n font-size: 11px;\n font-weight: 500;\n color: #64748b;\n}\n\n.format-type-btn.active span {\n color: #1d4ed8;\n}\n\n/* Format Options Section */\n.format-options-section {\n margin-bottom: 24px;\n}\n\n.format-options-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-option-group {\n margin-bottom: 16px;\n}\n\n.format-option-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.format-option-group input,\n.format-option-group select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.format-option-group input:focus,\n.format-option-group select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-option-row {\n display: flex;\n gap: 12px;\n}\n\n.format-option-row .format-option-group {\n flex: 1;\n}\n\n.format-checkbox {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n.format-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.format-checkbox span {\n font-size: 14px;\n color: #333;\n}\n\n/* Alignment Options */\n.alignment-options {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 10px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #3b82f6;\n}\n\n.align-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #3b82f6;\n}\n\n/* Style Section */\n.style-section {\n margin-bottom: 24px;\n}\n\n.style-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.style-toggle-group {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-toggle-btn {\n width: 40px;\n height: 40px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-toggle-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-toggle-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.style-toggle-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.style-toggle-btn.active i {\n color: #3b82f6;\n}\n\n.color-picker-row {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.color-picker-group {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.color-picker-group label {\n font-size: 13px;\n color: #64748b;\n min-width: 80px;\n}\n\n.color-picker-group input[type=\"color\"] {\n width: 40px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.color-clear-btn {\n width: 32px;\n height: 32px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.color-clear-btn:hover {\n background: #f5f5f5;\n color: #666;\n}\n\n/* Format Editor Footer */\n.format-editor-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-footer-left {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.format-footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.format-footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.format-footer-btn.danger {\n color: #c62828;\n border-color: #c62828;\n}\n\n.format-footer-btn.danger:hover:not(:disabled) {\n background: #c62828;\n color: white;\n}\n\n/* Filter Summary Container */\n.filter-summary-container {\n padding: 4px 0;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: #f5f7fa;\n border-radius: 8px;\n border: 1px solid #e8e8e8;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n min-width: 20px;\n text-align: center;\n}\n\n.summary-text {\n font-size: 14px;\n color: #333;\n}\n\n.summary-text.no-filters {\n color: #999;\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: 4px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn i {\n font-size: 11px;\n}\n\n.summary-btn.clear-btn {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.summary-btn.clear-btn:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.summary-btn.edit-btn {\n background: #1976d2;\n color: white;\n}\n\n.summary-btn.edit-btn:hover:not(:disabled) {\n background: #1565c0;\n}\n\n/* ========================================\n FILTER MODE SELECTOR\n ======================================== */\n\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: 14px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.filter-mode-btn.active {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.filter-mode-btn .mode-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: #f3f4f6;\n color: #6b7280;\n font-size: 16px;\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: #3b82f6;\n color: white;\n}\n\n.filter-mode-btn .mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-mode-btn .mode-title {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.filter-mode-btn .mode-subtitle {\n font-size: 12px;\n color: #6b7280;\n}\n\n.filter-mode-btn.active .mode-title {\n color: #1d4ed8;\n}\n\n.filter-mode-btn .mode-check {\n color: #3b82f6;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n/* ========================================\n SMART FILTER SECTION\n ======================================== */\n\n.smart-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 12px;\n margin-bottom: 16px;\n}\n\n.smart-filter-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border-radius: 10px;\n color: white;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.smart-filter-input-container .smart-filter-textarea {\n flex: 1;\n border: none;\n background: white;\n border-radius: 8px;\n padding: 12px;\n font-size: 14px;\n line-height: 1.5;\n resize: none;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea::placeholder {\n color: #9ca3af;\n}\n\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n background: #e3f2fd;\n border-radius: 6px;\n margin-bottom: 12px;\n font-size: 13px;\n color: #1565c0;\n}\n\n.smart-filter-explanation i {\n color: #1976d2;\n font-size: 14px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 16px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.examples-header i {\n color: #f59e0b;\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\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 color: #9ca3af;\n}\n\n.example-chip:hover:not(:disabled) i {\n color: #3b82f6;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.smart-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* ========================================\n TRADITIONAL FILTER SECTION\n ======================================== */\n\n.traditional-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.traditional-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n margin-top: 12px;\n}\n\n.traditional-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n.summary-btn.edit-btn.primary {\n background: #3b82f6;\n color: white;\n border-color: #3b82f6;\n}\n\n.summary-btn.edit-btn.primary:hover:not(:disabled) {\n background: #2563eb;\n border-color: #2563eb;\n}\n\n/* Form Elements */\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: #333;\n}\n\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.form-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.form-input:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 14px;\n color: #333;\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: #666;\n}\n\n/* Danger Zone */\n.danger-zone {\n padding-top: 16px;\n border-top: 1px solid #ffcdd2;\n}\n\n.danger-zone .section-header {\n color: #c62828;\n}\n\n.danger-zone .section-header i {\n color: #c62828;\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #c62828;\n background: transparent;\n border-radius: 6px;\n color: #c62828;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: #c62828;\n color: white;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.footer-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n FORMAT EDITOR INLINE STYLES\n ======================================== */\n\n.format-editor {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n.format-editor .format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0 16px 0;\n border-bottom: 1px solid #e0e0e0;\n margin-bottom: 16px;\n}\n\n.format-editor .back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.format-editor .back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-editor .format-editor-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n/* Preview Table */\n.format-editor .preview-table {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 12px;\n}\n\n.format-editor .preview-header-cell {\n padding: 10px 14px;\n background: #f1f5f9;\n border-radius: 6px;\n font-weight: 600;\n font-size: 13px;\n color: #333;\n}\n\n.format-editor .preview-cell {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 4px;\n font-size: 14px;\n color: #333;\n}\n\n/* Format Section */\n.format-section {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.format-section:last-child {\n border-bottom: none;\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: #333;\n}\n\n.format-section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n/* Format Row */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.format-row:last-child {\n margin-bottom: 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: #555;\n flex-shrink: 0;\n}\n\n/* Format Inputs */\n.format-select {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n min-width: 120px;\n}\n\n.format-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input {\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n}\n\n.format-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input.small {\n width: 80px;\n}\n\n/* Alias Info Row */\n.format-row.alias-info {\n justify-content: flex-start;\n gap: 8px;\n}\n\n.format-row.alias-info .muted-text {\n color: #888;\n font-size: 12px;\n}\n\n.clear-alias-btn {\n width: 20px;\n height: 20px;\n border: none;\n background: #f0f0f0;\n border-radius: 50%;\n color: #888;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n background: #e0e0e0;\n color: #c62828;\n}\n\n/* Color Input */\n.color-input {\n width: 50px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n background: white;\n}\n\n.color-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n width: 40px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.align-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #1976d2;\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 36px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.style-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.style-btn.active i {\n color: #1976d2;\n}\n\n/* Collapsible Format Sections */\n.format-section-collapsible {\n margin-bottom: 12px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.format-section-collapsible summary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n background: #f8fafc;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n list-style: none;\n}\n\n.format-section-collapsible summary::-webkit-details-marker {\n display: none;\n}\n\n.format-section-collapsible summary::before {\n content: '\\f054';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n color: #999;\n transition: transform 0.2s ease;\n}\n\n.format-section-collapsible[open] summary::before {\n transform: rotate(90deg);\n}\n\n.format-section-collapsible summary i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.format-section-collapsible summary span {\n flex: 1;\n}\n\n.format-section-content {\n padding: 14px;\n background: white;\n border-top: 1px solid #e0e0e0;\n}\n\n/* Format Actions */\n.format-actions {\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: #fff5f5;\n border-color: #f87171;\n color: #dc2626;\n}\n\n.clear-format-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n AGGREGATES TAB STYLES\n ======================================== */\n\n.aggregates-section {\n padding-top: 0;\n}\n\n.aggregates-header {\n margin-bottom: 16px;\n}\n\n.aggregates-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Add Aggregate Button */\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-aggregate-btn i {\n font-size: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n/* Aggregate Item */\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.aggregate-item.disabled {\n opacity: 0.6;\n background: #f5f5f5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n border-radius: 8px;\n color: #1976d2;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.aggregate-item.disabled .agg-icon {\n background: #f0f0f0;\n color: #999;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 2px;\n}\n\n.aggregate-item.disabled .agg-label {\n color: #888;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #888;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.agg-type i {\n font-size: 10px;\n}\n\n.agg-smart-badge {\n display: flex;\n align-items: center;\n padding: 2px 6px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-radius: 4px;\n color: #3b82f6;\n font-size: 10px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.agg-action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\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: #2e7d32;\n}\n\n.agg-action-btn.toggle-btn:not(.enabled) {\n color: #bdbdbd;\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 12px 14px;\n background: #f5f7fa;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.summary-item i {\n color: #1976d2;\n font-size: 11px;\n}\n\n/* Aggregates Empty State */\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.aggregates-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Aggregates Tip */\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.aggregates-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .config-panel {\n width: 100% !important;\n max-width: 100vw !important;\n }\n\n /* Hide resize handle on mobile - panel is full width */\n .resize-handle {\n display: none;\n }\n\n .tab-btn span {\n display: none;\n }\n\n .tab-btn {\n padding: 14px;\n }\n\n .tab-btn i {\n font-size: 16px;\n }\n\n .format-type-grid {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n/* Medium screens - limit max resize width */\n@media (min-width: 769px) and (max-width: 1200px) {\n .config-panel {\n max-width: min(600px, 80vw);\n }\n}\n"] }]
2677
2690
  }], () => [{ type: i0.ChangeDetectorRef }], { entity: [{
2678
2691
  type: Input
2679
2692
  }], viewEntity: [{
@@ -2702,5 +2715,5 @@ export class ViewConfigPanelComponent {
2702
2715
  type: HostListener,
2703
2716
  args: ['document:keydown.escape']
2704
2717
  }] }); })();
2705
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ViewConfigPanelComponent, { className: "ViewConfigPanelComponent", filePath: "src/lib/view-config-panel/view-config-panel.component.ts", lineNumber: 88 }); })();
2718
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ViewConfigPanelComponent, { className: "ViewConfigPanelComponent", filePath: "src/lib/view-config-panel/view-config-panel.component.ts", lineNumber: 89 }); })();
2706
2719
  //# sourceMappingURL=view-config-panel.component.js.map