@memberjunction/ng-dashboards 5.7.0 → 5.9.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 (79) hide show
  1. package/dist/AI/components/models/model-management.component.d.ts +2 -0
  2. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  3. package/dist/AI/components/models/model-management.component.js +44 -2
  4. package/dist/AI/components/models/model-management.component.js.map +1 -1
  5. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  6. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +5 -2
  7. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  8. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  9. package/dist/Home/home-dashboard.component.js +10 -7
  10. package/dist/Home/home-dashboard.component.js.map +1 -1
  11. package/dist/Integration/components/activity/activity.component.d.ts +96 -0
  12. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -0
  13. package/dist/Integration/components/activity/activity.component.js +961 -0
  14. package/dist/Integration/components/activity/activity.component.js.map +1 -0
  15. package/dist/Integration/components/connections/connections.component.d.ts +194 -0
  16. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -0
  17. package/dist/Integration/components/connections/connections.component.js +2368 -0
  18. package/dist/Integration/components/connections/connections.component.js.map +1 -0
  19. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts +241 -0
  20. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -0
  21. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +2373 -0
  22. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -0
  23. package/dist/Integration/components/overview/overview.component.d.ts +60 -0
  24. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -0
  25. package/dist/Integration/components/overview/overview.component.js +628 -0
  26. package/dist/Integration/components/overview/overview.component.js.map +1 -0
  27. package/dist/Integration/components/pipelines/pipelines.component.d.ts +203 -0
  28. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -0
  29. package/dist/Integration/components/pipelines/pipelines.component.js +2057 -0
  30. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -0
  31. package/dist/Integration/components/schedules/schedules.component.d.ts +110 -0
  32. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -0
  33. package/dist/Integration/components/schedules/schedules.component.js +842 -0
  34. package/dist/Integration/components/schedules/schedules.component.js.map +1 -0
  35. package/dist/Integration/components/visual-editor/visual-editor.component.d.ts +141 -0
  36. package/dist/Integration/components/visual-editor/visual-editor.component.d.ts.map +1 -0
  37. package/dist/Integration/components/visual-editor/visual-editor.component.js +1538 -0
  38. package/dist/Integration/components/visual-editor/visual-editor.component.js.map +1 -0
  39. package/dist/Integration/components/widgets/integration-card.component.d.ts +22 -0
  40. package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -0
  41. package/dist/Integration/components/widgets/integration-card.component.js +262 -0
  42. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -0
  43. package/dist/Integration/components/widgets/run-history-panel.component.d.ts +29 -0
  44. package/dist/Integration/components/widgets/run-history-panel.component.d.ts.map +1 -0
  45. package/dist/Integration/components/widgets/run-history-panel.component.js +399 -0
  46. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -0
  47. package/dist/Integration/index.d.ts +11 -0
  48. package/dist/Integration/index.d.ts.map +1 -0
  49. package/dist/Integration/index.js +20 -0
  50. package/dist/Integration/index.js.map +1 -0
  51. package/dist/Integration/integration.module.d.ts +26 -0
  52. package/dist/Integration/integration.module.d.ts.map +1 -0
  53. package/dist/Integration/integration.module.js +107 -0
  54. package/dist/Integration/integration.module.js.map +1 -0
  55. package/dist/Integration/services/integration-data.service.d.ts +268 -0
  56. package/dist/Integration/services/integration-data.service.d.ts.map +1 -0
  57. package/dist/Integration/services/integration-data.service.js +697 -0
  58. package/dist/Integration/services/integration-data.service.js.map +1 -0
  59. package/dist/QueryBrowser/query-browser-resource.component.d.ts +27 -4
  60. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  61. package/dist/QueryBrowser/query-browser-resource.component.js +338 -144
  62. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  63. package/dist/__tests__/integration-data-service.test.d.ts +2 -0
  64. package/dist/__tests__/integration-data-service.test.d.ts.map +1 -0
  65. package/dist/__tests__/integration-data-service.test.js +131 -0
  66. package/dist/__tests__/integration-data-service.test.js.map +1 -0
  67. package/dist/__tests__/mapping-validation.test.d.ts +2 -0
  68. package/dist/__tests__/mapping-validation.test.d.ts.map +1 -0
  69. package/dist/__tests__/mapping-validation.test.js +170 -0
  70. package/dist/__tests__/mapping-validation.test.js.map +1 -0
  71. package/dist/module.d.ts +2 -1
  72. package/dist/module.d.ts.map +1 -1
  73. package/dist/module.js +17 -6
  74. package/dist/module.js.map +1 -1
  75. package/dist/public-api.d.ts +2 -1
  76. package/dist/public-api.d.ts.map +1 -1
  77. package/dist/public-api.js +3 -1
  78. package/dist/public-api.js.map +1 -1
  79. package/package.json +42 -39
@@ -27,21 +27,52 @@ function QueryBrowserResourceComponent_Conditional_20_Template(rf, ctx) { if (rf
27
27
  i0.ɵɵelement(1, "i", 29);
28
28
  i0.ɵɵelementEnd();
29
29
  } }
30
- function QueryBrowserResourceComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
31
- i0.ɵɵelementStart(0, "div", 20);
32
- i0.ɵɵelement(1, "mj-loading", 30);
30
+ function QueryBrowserResourceComponent_For_23_Conditional_0_Template(rf, ctx) { if (rf & 1) {
31
+ const _r4 = i0.ɵɵgetCurrentView();
32
+ i0.ɵɵelementStart(0, "button", 31);
33
+ i0.ɵɵlistener("click", function QueryBrowserResourceComponent_For_23_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const status_r5 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleStatusFilter(status_r5)); });
34
+ i0.ɵɵelement(1, "i", 32);
35
+ i0.ɵɵelementStart(2, "span");
36
+ i0.ɵɵtext(3);
33
37
  i0.ɵɵelementEnd();
38
+ i0.ɵɵelementStart(4, "span", 33);
39
+ i0.ɵɵtext(5);
40
+ i0.ɵɵelementEnd()();
41
+ } if (rf & 2) {
42
+ const status_r5 = i0.ɵɵnextContext().$implicit;
43
+ const ctx_r2 = i0.ɵɵnextContext();
44
+ i0.ɵɵstyleProp("--chip-color", ctx_r2.getStatusColor(status_r5));
45
+ i0.ɵɵclassProp("active", ctx_r2.StatusFilters[status_r5]);
46
+ i0.ɵɵproperty("title", (ctx_r2.StatusFilters[status_r5] ? "Hide" : "Show") + " " + status_r5 + " queries");
47
+ i0.ɵɵadvance();
48
+ i0.ɵɵclassMap(ctx_r2.getStatusIcon(status_r5));
49
+ i0.ɵɵadvance(2);
50
+ i0.ɵɵtextInterpolate(status_r5);
51
+ i0.ɵɵadvance(2);
52
+ i0.ɵɵtextInterpolate(ctx_r2.getStatusCount(status_r5));
53
+ } }
54
+ function QueryBrowserResourceComponent_For_23_Template(rf, ctx) { if (rf & 1) {
55
+ i0.ɵɵconditionalCreate(0, QueryBrowserResourceComponent_For_23_Conditional_0_Template, 6, 9, "button", 30);
56
+ } if (rf & 2) {
57
+ const status_r5 = ctx.$implicit;
58
+ const ctx_r2 = i0.ɵɵnextContext();
59
+ i0.ɵɵconditional(ctx_r2.getStatusCount(status_r5) > 0 ? 0 : -1);
34
60
  } }
35
- function QueryBrowserResourceComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
61
+ function QueryBrowserResourceComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
36
62
  i0.ɵɵelementStart(0, "div", 21);
37
- i0.ɵɵelement(1, "i", 31);
63
+ i0.ɵɵelement(1, "mj-loading", 34);
64
+ i0.ɵɵelementEnd();
65
+ } }
66
+ function QueryBrowserResourceComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
67
+ i0.ɵɵelementStart(0, "div", 22);
68
+ i0.ɵɵelement(1, "i", 35);
38
69
  i0.ɵɵelementStart(2, "p");
39
70
  i0.ɵɵtext(3, "No queries available");
40
71
  i0.ɵɵelementEnd()();
41
72
  } }
42
- function QueryBrowserResourceComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
43
- i0.ɵɵelementStart(0, "div", 21);
44
- i0.ɵɵelement(1, "i", 32);
73
+ function QueryBrowserResourceComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵelementStart(0, "div", 22);
75
+ i0.ɵɵelement(1, "i", 36);
45
76
  i0.ɵɵelementStart(2, "p");
46
77
  i0.ɵɵtext(3);
47
78
  i0.ɵɵelementEnd()();
@@ -50,144 +81,198 @@ function QueryBrowserResourceComponent_Conditional_24_Template(rf, ctx) { if (rf
50
81
  i0.ɵɵadvance(3);
51
82
  i0.ɵɵtextInterpolate1("No queries match \"", ctx_r2.searchText, "\"");
52
83
  } }
53
- function QueryBrowserResourceComponent_Conditional_25_For_2_ng_container_0_Template(rf, ctx) { if (rf & 1) {
84
+ function QueryBrowserResourceComponent_Conditional_28_For_2_ng_container_0_Template(rf, ctx) { if (rf & 1) {
54
85
  i0.ɵɵelementContainer(0);
55
86
  } }
56
- function QueryBrowserResourceComponent_Conditional_25_For_2_Template(rf, ctx) { if (rf & 1) {
57
- i0.ɵɵtemplate(0, QueryBrowserResourceComponent_Conditional_25_For_2_ng_container_0_Template, 1, 0, "ng-container", 33);
87
+ function QueryBrowserResourceComponent_Conditional_28_For_2_Template(rf, ctx) { if (rf & 1) {
88
+ i0.ɵɵtemplate(0, QueryBrowserResourceComponent_Conditional_28_For_2_ng_container_0_Template, 1, 0, "ng-container", 37);
58
89
  } if (rf & 2) {
59
- const node_r4 = ctx.$implicit;
90
+ const node_r6 = ctx.$implicit;
60
91
  i0.ɵɵnextContext(2);
61
- const categoryNode_r5 = i0.ɵɵreference(32);
62
- i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r5)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, node_r4));
92
+ const categoryNode_r7 = i0.ɵɵreference(35);
93
+ i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r7)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, node_r6));
63
94
  } }
64
- function QueryBrowserResourceComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
65
- i0.ɵɵelementStart(0, "div", 22);
66
- i0.ɵɵrepeaterCreate(1, QueryBrowserResourceComponent_Conditional_25_For_2_Template, 1, 4, "ng-container", null, i0.ɵɵcomponentInstance().trackByCategory, true);
95
+ function QueryBrowserResourceComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
96
+ i0.ɵɵelementStart(0, "div", 23);
97
+ i0.ɵɵrepeaterCreate(1, QueryBrowserResourceComponent_Conditional_28_For_2_Template, 1, 4, "ng-container", null, i0.ɵɵcomponentInstance().trackByCategory, true);
67
98
  i0.ɵɵelementEnd();
68
99
  } if (rf & 2) {
69
100
  const ctx_r2 = i0.ɵɵnextContext();
70
101
  i0.ɵɵadvance();
71
102
  i0.ɵɵrepeater(ctx_r2.categoryTree);
72
103
  } }
73
- function QueryBrowserResourceComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
74
- i0.ɵɵelementStart(0, "div", 26);
75
- i0.ɵɵelement(1, "i", 34);
76
- i0.ɵɵelementStart(2, "p", 35);
104
+ function QueryBrowserResourceComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
105
+ i0.ɵɵelementStart(0, "div", 27);
106
+ i0.ɵɵelement(1, "i", 38);
107
+ i0.ɵɵelementStart(2, "p", 39);
77
108
  i0.ɵɵtext(3, "Select a query from the list");
78
109
  i0.ɵɵelementEnd();
79
- i0.ɵɵelementStart(4, "p", 36);
110
+ i0.ɵɵelementStart(4, "p", 40);
80
111
  i0.ɵɵtext(5, "Click on a query to view and run it");
81
112
  i0.ɵɵelementEnd()();
82
113
  } }
83
- function QueryBrowserResourceComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
84
- const _r6 = i0.ɵɵgetCurrentView();
85
- i0.ɵɵelementStart(0, "mj-query-viewer", 37);
86
- i0.ɵɵlistener("EntityLinkClick", function QueryBrowserResourceComponent_Conditional_30_Template_mj_query_viewer_EntityLinkClick_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEntityLinkClick($event)); })("RowDoubleClick", function QueryBrowserResourceComponent_Conditional_30_Template_mj_query_viewer_RowDoubleClick_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRowDoubleClick($event)); })("OpenQueryRecord", function QueryBrowserResourceComponent_Conditional_30_Template_mj_query_viewer_OpenQueryRecord_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenQueryRecord($event)); });
114
+ function QueryBrowserResourceComponent_Conditional_33_Conditional_5_Template(rf, ctx) { if (rf & 1) {
115
+ i0.ɵɵelementStart(0, "span", 47);
116
+ i0.ɵɵelement(1, "i", 32);
117
+ i0.ɵɵtext(2);
118
+ i0.ɵɵelementEnd();
119
+ } if (rf & 2) {
120
+ const ctx_r2 = i0.ɵɵnextContext(2);
121
+ i0.ɵɵstyleProp("background", ctx_r2.getStatusColor(ctx_r2.selectedQuery.Status));
122
+ i0.ɵɵadvance();
123
+ i0.ɵɵclassMap(ctx_r2.getStatusIcon(ctx_r2.selectedQuery.Status));
124
+ i0.ɵɵadvance();
125
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.selectedQuery.Status, " ");
126
+ } }
127
+ function QueryBrowserResourceComponent_Conditional_33_Conditional_6_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵelementStart(0, "span", 48);
129
+ i0.ɵɵelement(1, "i", 49);
130
+ i0.ɵɵtext(2, " Approved ");
131
+ i0.ɵɵelementEnd();
132
+ } if (rf & 2) {
133
+ const ctx_r2 = i0.ɵɵnextContext(2);
134
+ i0.ɵɵstyleProp("background", ctx_r2.getStatusColor("Approved"));
135
+ } }
136
+ function QueryBrowserResourceComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
137
+ const _r8 = i0.ɵɵgetCurrentView();
138
+ i0.ɵɵelementStart(0, "div", 41)(1, "div", 42);
139
+ i0.ɵɵelement(2, "i", 43);
140
+ i0.ɵɵelementStart(3, "span");
141
+ i0.ɵɵtext(4);
142
+ i0.ɵɵelementEnd()();
143
+ i0.ɵɵconditionalCreate(5, QueryBrowserResourceComponent_Conditional_33_Conditional_5_Template, 3, 5, "span", 44)(6, QueryBrowserResourceComponent_Conditional_33_Conditional_6_Template, 3, 2, "span", 45);
144
+ i0.ɵɵelementEnd();
145
+ i0.ɵɵelementStart(7, "mj-query-viewer", 46);
146
+ i0.ɵɵlistener("EntityLinkClick", function QueryBrowserResourceComponent_Conditional_33_Template_mj_query_viewer_EntityLinkClick_7_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEntityLinkClick($event)); })("RowDoubleClick", function QueryBrowserResourceComponent_Conditional_33_Template_mj_query_viewer_RowDoubleClick_7_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRowDoubleClick($event)); })("OpenQueryRecord", function QueryBrowserResourceComponent_Conditional_33_Template_mj_query_viewer_OpenQueryRecord_7_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenQueryRecord($event)); });
87
147
  i0.ɵɵelementEnd();
88
148
  } if (rf & 2) {
89
149
  const ctx_r2 = i0.ɵɵnextContext();
150
+ i0.ɵɵadvance(4);
151
+ i0.ɵɵtextInterpolate(ctx_r2.selectedQuery.Name);
152
+ i0.ɵɵadvance();
153
+ i0.ɵɵconditional(ctx_r2.selectedQuery.Status !== "Approved" ? 5 : 6);
154
+ i0.ɵɵadvance(2);
90
155
  i0.ɵɵproperty("QueryId", ctx_r2.selectedQuery.ID)("AutoRun", true)("SelectionMode", "multiple");
91
156
  } }
92
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
93
- i0.ɵɵelementStart(0, "span", 51);
157
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
158
+ i0.ɵɵelementStart(0, "span", 64);
94
159
  i0.ɵɵtext(1);
95
160
  i0.ɵɵelementEnd();
96
161
  } if (rf & 2) {
97
- const query_r10 = i0.ɵɵnextContext().$implicit;
162
+ const query_r12 = i0.ɵɵnextContext().$implicit;
98
163
  i0.ɵɵadvance();
99
- i0.ɵɵtextInterpolate(query_r10.Description);
164
+ i0.ɵɵtextInterpolate(query_r12.Description);
100
165
  } }
101
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
102
- i0.ɵɵelement(0, "i", 52);
166
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
167
+ i0.ɵɵelement(0, "i", 65);
103
168
  } }
104
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
105
- const _r9 = i0.ɵɵgetCurrentView();
106
- i0.ɵɵelementStart(0, "div", 47);
107
- i0.ɵɵlistener("click", function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Template_div_click_0_listener($event) { const query_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.selectQuery(query_r10, $event)); });
108
- i0.ɵɵelement(1, "i", 48);
109
- i0.ɵɵelementStart(2, "div", 49)(3, "span", 50);
110
- i0.ɵɵtext(4);
169
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
170
+ i0.ɵɵelementStart(0, "span", 67);
171
+ i0.ɵɵtext(1);
111
172
  i0.ɵɵelementEnd();
112
- i0.ɵɵconditionalCreate(5, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Conditional_5_Template, 2, 1, "span", 51);
173
+ } if (rf & 2) {
174
+ const query_r12 = i0.ɵɵnextContext().$implicit;
175
+ const ctx_r2 = i0.ɵɵnextContext(4);
176
+ i0.ɵɵstyleProp("background", ctx_r2.getStatusColor(query_r12.Status));
177
+ i0.ɵɵproperty("title", query_r12.Status);
178
+ i0.ɵɵadvance();
179
+ i0.ɵɵtextInterpolate1(" ", query_r12.Status, " ");
180
+ } }
181
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
182
+ const _r11 = i0.ɵɵgetCurrentView();
183
+ i0.ɵɵelementStart(0, "div", 59);
184
+ i0.ɵɵlistener("click", function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Template_div_click_0_listener($event) { const query_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.selectQuery(query_r12, $event)); });
185
+ i0.ɵɵelement(1, "span", 60)(2, "i", 61);
186
+ i0.ɵɵelementStart(3, "div", 62)(4, "span", 63);
187
+ i0.ɵɵtext(5);
113
188
  i0.ɵɵelementEnd();
114
- i0.ɵɵconditionalCreate(6, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Conditional_6_Template, 1, 0, "i", 52);
189
+ i0.ɵɵconditionalCreate(6, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_6_Template, 2, 1, "span", 64);
190
+ i0.ɵɵelementEnd();
191
+ i0.ɵɵconditionalCreate(7, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_7_Template, 1, 0, "i", 65);
192
+ i0.ɵɵconditionalCreate(8, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Conditional_8_Template, 2, 4, "span", 66);
115
193
  i0.ɵɵelementEnd();
116
194
  } if (rf & 2) {
117
- const query_r10 = ctx.$implicit;
195
+ const query_r12 = ctx.$implicit;
118
196
  const ctx_r2 = i0.ɵɵnextContext(4);
119
- i0.ɵɵclassProp("selected", ctx_r2.IsQuerySelected(query_r10))("hidden", !ctx_r2.isQueryVisible(query_r10));
120
- i0.ɵɵadvance(4);
121
- i0.ɵɵtextInterpolate(query_r10.Name);
197
+ i0.ɵɵclassProp("selected", ctx_r2.IsQuerySelected(query_r12))("hidden", !ctx_r2.isQueryVisible(query_r12));
122
198
  i0.ɵɵadvance();
123
- i0.ɵɵconditional(query_r10.Description ? 5 : -1);
199
+ i0.ɵɵstyleProp("background", ctx_r2.getStatusColor(query_r12.Status));
200
+ i0.ɵɵproperty("title", query_r12.Status);
201
+ i0.ɵɵadvance(2);
202
+ i0.ɵɵproperty("title", query_r12.Description || query_r12.Name);
203
+ i0.ɵɵadvance(2);
204
+ i0.ɵɵtextInterpolate(query_r12.Name);
205
+ i0.ɵɵadvance();
206
+ i0.ɵɵconditional(query_r12.Description ? 6 : -1);
124
207
  i0.ɵɵadvance();
125
- i0.ɵɵconditional(query_r10.UsesTemplate ? 6 : -1);
208
+ i0.ɵɵconditional(query_r12.UsesTemplate ? 7 : -1);
209
+ i0.ɵɵadvance();
210
+ i0.ɵɵconditional(query_r12.Status !== "Approved" ? 8 : -1);
126
211
  } }
127
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵelementStart(0, "div", 45);
129
- i0.ɵɵrepeaterCreate(1, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_For_2_Template, 7, 7, "div", 46, i0.ɵɵcomponentInstance().trackByQuery, true);
212
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_Template(rf, ctx) { if (rf & 1) {
213
+ i0.ɵɵelementStart(0, "div", 57);
214
+ i0.ɵɵrepeaterCreate(1, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_For_2_Template, 9, 12, "div", 58, i0.ɵɵcomponentInstance().trackByQuery, true);
130
215
  i0.ɵɵelementEnd();
131
216
  } if (rf & 2) {
132
- const node_r8 = i0.ɵɵnextContext(2).node;
217
+ const node_r10 = i0.ɵɵnextContext(2).node;
133
218
  i0.ɵɵadvance();
134
- i0.ɵɵrepeater(node_r8.queries);
219
+ i0.ɵɵrepeater(node_r10.queries);
135
220
  } }
136
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_For_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
221
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_For_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
137
222
  i0.ɵɵelementContainer(0);
138
223
  } }
139
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
140
- i0.ɵɵtemplate(0, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_For_1_ng_container_0_Template, 1, 0, "ng-container", 33);
224
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
225
+ i0.ɵɵtemplate(0, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_For_1_ng_container_0_Template, 1, 0, "ng-container", 37);
141
226
  } if (rf & 2) {
142
- const child_r11 = ctx.$implicit;
227
+ const child_r13 = ctx.$implicit;
143
228
  i0.ɵɵnextContext(4);
144
- const categoryNode_r5 = i0.ɵɵreference(32);
145
- i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r5)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r11));
229
+ const categoryNode_r7 = i0.ɵɵreference(35);
230
+ i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r7)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r13));
146
231
  } }
147
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
148
- i0.ɵɵrepeaterCreate(0, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_For_1_Template, 1, 4, "ng-container", null, i0.ɵɵcomponentInstance().trackByCategory, true);
232
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
233
+ i0.ɵɵrepeaterCreate(0, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_For_1_Template, 1, 4, "ng-container", null, i0.ɵɵcomponentInstance().trackByCategory, true);
149
234
  } if (rf & 2) {
150
- const node_r8 = i0.ɵɵnextContext(2).node;
151
- i0.ɵɵrepeater(node_r8.children);
235
+ const node_r10 = i0.ɵɵnextContext(2).node;
236
+ i0.ɵɵrepeater(node_r10.children);
152
237
  } }
153
- function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Template(rf, ctx) { if (rf & 1) {
154
- const _r7 = i0.ɵɵgetCurrentView();
155
- i0.ɵɵelementStart(0, "div", 39)(1, "div", 40);
156
- i0.ɵɵlistener("click", function QueryBrowserResourceComponent_ng_template_31_Conditional_0_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r7); const node_r8 = i0.ɵɵnextContext().node; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleExpand(node_r8)); });
157
- i0.ɵɵelement(2, "i", 41)(3, "i", 42);
158
- i0.ɵɵelementStart(4, "span", 43);
238
+ function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Template(rf, ctx) { if (rf & 1) {
239
+ const _r9 = i0.ɵɵgetCurrentView();
240
+ i0.ɵɵelementStart(0, "div", 51)(1, "div", 52);
241
+ i0.ɵɵlistener("click", function QueryBrowserResourceComponent_ng_template_34_Conditional_0_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r9); const node_r10 = i0.ɵɵnextContext().node; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleExpand(node_r10)); });
242
+ i0.ɵɵelement(2, "i", 53)(3, "i", 54);
243
+ i0.ɵɵelementStart(4, "span", 55);
159
244
  i0.ɵɵtext(5);
160
245
  i0.ɵɵelementEnd();
161
- i0.ɵɵelementStart(6, "span", 44);
246
+ i0.ɵɵelementStart(6, "span", 56);
162
247
  i0.ɵɵtext(7);
163
248
  i0.ɵɵelementEnd()();
164
- i0.ɵɵconditionalCreate(8, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_8_Template, 3, 0, "div", 45);
165
- i0.ɵɵconditionalCreate(9, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Conditional_9_Template, 2, 0);
249
+ i0.ɵɵconditionalCreate(8, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_8_Template, 3, 0, "div", 57);
250
+ i0.ɵɵconditionalCreate(9, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Conditional_9_Template, 2, 0);
166
251
  i0.ɵɵelementEnd();
167
252
  } if (rf & 2) {
168
- const node_r8 = i0.ɵɵnextContext().node;
253
+ const node_r10 = i0.ɵɵnextContext().node;
169
254
  const ctx_r2 = i0.ɵɵnextContext();
170
- i0.ɵɵstyleProp("padding-left", node_r8.level * 16 + 8, "px");
171
- i0.ɵɵclassProp("expanded", node_r8.expanded);
255
+ i0.ɵɵstyleProp("padding-left", node_r10.level * 16 + 8, "px");
256
+ i0.ɵɵclassProp("expanded", node_r10.expanded);
172
257
  i0.ɵɵadvance(2);
173
- i0.ɵɵclassProp("fa-chevron-down", node_r8.expanded)("fa-chevron-right", !node_r8.expanded);
258
+ i0.ɵɵclassProp("fa-chevron-down", node_r10.expanded)("fa-chevron-right", !node_r10.expanded);
174
259
  i0.ɵɵadvance();
175
- i0.ɵɵclassProp("fa-folder-open", node_r8.expanded);
260
+ i0.ɵɵclassProp("fa-folder-open", node_r10.expanded);
176
261
  i0.ɵɵadvance(2);
177
- i0.ɵɵtextInterpolate(node_r8.category.Name);
262
+ i0.ɵɵtextInterpolate(node_r10.category.Name);
178
263
  i0.ɵɵadvance(2);
179
- i0.ɵɵtextInterpolate1("(", ctx_r2.getNodeQueryCount(node_r8), ")");
264
+ i0.ɵɵtextInterpolate1("(", ctx_r2.getNodeQueryCount(node_r10), ")");
180
265
  i0.ɵɵadvance();
181
- i0.ɵɵconditional(node_r8.expanded ? 8 : -1);
266
+ i0.ɵɵconditional(node_r10.expanded ? 8 : -1);
182
267
  i0.ɵɵadvance();
183
- i0.ɵɵconditional(node_r8.expanded ? 9 : -1);
268
+ i0.ɵɵconditional(node_r10.expanded ? 9 : -1);
184
269
  } }
185
- function QueryBrowserResourceComponent_ng_template_31_Template(rf, ctx) { if (rf & 1) {
186
- i0.ɵɵconditionalCreate(0, QueryBrowserResourceComponent_ng_template_31_Conditional_0_Template, 10, 14, "div", 38);
270
+ function QueryBrowserResourceComponent_ng_template_34_Template(rf, ctx) { if (rf & 1) {
271
+ i0.ɵɵconditionalCreate(0, QueryBrowserResourceComponent_ng_template_34_Conditional_0_Template, 10, 14, "div", 50);
187
272
  } if (rf & 2) {
188
- const node_r8 = ctx.node;
273
+ const node_r10 = ctx.node;
189
274
  const ctx_r2 = i0.ɵɵnextContext();
190
- i0.ɵɵconditional(ctx_r2.hasVisibleContent(node_r8) ? 0 : -1);
275
+ i0.ɵɵconditional(ctx_r2.hasVisibleContent(node_r10) ? 0 : -1);
191
276
  } }
192
277
  /**
193
278
  * A resource component for browsing and executing stored queries.
@@ -205,18 +290,32 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
205
290
  elementRef;
206
291
  zone;
207
292
  static SETTINGS_KEY = 'QueryBrowser/panelWidth';
293
+ static STATUS_FILTERS_KEY = 'QueryBrowser/statusFilters';
294
+ static EXPANDED_STATE_KEY = 'QueryBrowser/expandedCategories';
208
295
  static DEFAULT_PANEL_WIDTH = 320;
209
296
  static MIN_PANEL_WIDTH = 200;
210
297
  static MAX_PANEL_WIDTH = 600;
211
298
  isLoading = true;
212
299
  categories = [];
213
300
  categoryTree = [];
301
+ /** All queries the user has permission to run */
214
302
  queries = [];
215
303
  filteredQueries = [];
216
304
  selectedQuery = null;
217
305
  searchText = '';
218
306
  PanelWidth = QueryBrowserResourceComponent_1.DEFAULT_PANEL_WIDTH;
219
307
  IsResizing = false;
308
+ /** Status filter toggles — which statuses to show in the tree */
309
+ StatusFilters = {
310
+ 'Approved': true,
311
+ 'Pending': true,
312
+ 'Rejected': false,
313
+ 'Expired': false
314
+ };
315
+ /** Ordered list of all possible statuses for the filter bar */
316
+ AllStatuses = ['Approved', 'Pending', 'Rejected', 'Expired'];
317
+ /** Tracks expanded state by category ID — persisted across sessions */
318
+ expandedState = new Map();
220
319
  metadata = new Metadata();
221
320
  destroy$ = new Subject();
222
321
  dataLoaded = false;
@@ -235,6 +334,8 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
235
334
  }
236
335
  ngOnInit() {
237
336
  this.loadSavedPanelWidth();
337
+ this.loadSavedStatusFilters();
338
+ this.loadSavedExpandedState();
238
339
  this.loadData();
239
340
  // Subscribe to router NavigationEnd events for back/forward button support
240
341
  this.router.events
@@ -272,10 +373,10 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
272
373
  if (forceRefresh) {
273
374
  await this.metadata.Refresh();
274
375
  }
275
- // Load from metadata
376
+ // Load all queries the user has permission to run (regardless of status)
276
377
  this.categories = this.metadata.QueryCategories || [];
277
- this.queries = (this.metadata.Queries || []).filter(q => q.Status === 'Approved' && q.UserCanRun(this.metadata.CurrentUser));
278
- this.filteredQueries = [...this.queries];
378
+ this.queries = (this.metadata.Queries || []).filter(q => q.UserCanRun(this.metadata.CurrentUser));
379
+ this.applyFilters();
279
380
  this.buildCategoryTree();
280
381
  // Mark data as loaded and apply any query params for deep linking
281
382
  this.dataLoaded = true;
@@ -302,14 +403,16 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
302
403
  }
303
404
  buildCategoryTree() {
304
405
  const categoryMap = new Map();
305
- // Create nodes for all categories
406
+ // Use filtered queries (status + search filters applied)
407
+ const visibleQueries = this.filteredQueries;
408
+ // Create nodes for all categories, restoring expanded state
306
409
  for (const category of this.categories) {
307
- const queriesInCategory = this.queries.filter(q => UUIDsEqual(q.CategoryID, category.ID));
410
+ const queriesInCategory = visibleQueries.filter(q => UUIDsEqual(q.CategoryID, category.ID));
308
411
  categoryMap.set(category.ID, {
309
412
  category,
310
413
  children: [],
311
414
  queries: queriesInCategory,
312
- expanded: true,
415
+ expanded: this.expandedState.get(category.ID) ?? false,
313
416
  level: 0
314
417
  });
315
418
  }
@@ -332,7 +435,7 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
332
435
  }
333
436
  }
334
437
  // Add uncategorized queries to a virtual root
335
- const uncategorizedQueries = this.queries.filter(q => !q.CategoryID);
438
+ const uncategorizedQueries = visibleQueries.filter(q => !q.CategoryID);
336
439
  if (uncategorizedQueries.length > 0) {
337
440
  const uncategorizedCategory = new QueryCategoryInfo({
338
441
  ID: '__uncategorized__',
@@ -343,7 +446,7 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
343
446
  category: uncategorizedCategory,
344
447
  children: [],
345
448
  queries: uncategorizedQueries,
346
- expanded: true,
449
+ expanded: this.expandedState.get('__uncategorized__') ?? false,
347
450
  level: 0
348
451
  });
349
452
  }
@@ -363,16 +466,9 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
363
466
  // ========================================
364
467
  onSearchChange(value) {
365
468
  this.searchText = value;
366
- if (!value.trim()) {
367
- this.filteredQueries = [...this.queries];
368
- }
369
- else {
370
- const searchLower = value.toLowerCase();
371
- this.filteredQueries = this.queries.filter(q => q.Name.toLowerCase().includes(searchLower) ||
372
- q.Description?.toLowerCase().includes(searchLower) ||
373
- q.Category?.toLowerCase().includes(searchLower));
374
- }
375
- // Expand all categories when searching
469
+ this.applyFilters();
470
+ this.buildCategoryTree();
471
+ // Expand all categories when searching so results are visible
376
472
  if (value) {
377
473
  this.expandAll();
378
474
  }
@@ -380,10 +476,106 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
380
476
  }
381
477
  clearSearch() {
382
478
  this.searchText = '';
383
- this.filteredQueries = [...this.queries];
479
+ this.applyFilters();
480
+ this.buildCategoryTree();
384
481
  this.cdr.markForCheck();
385
482
  }
386
483
  // ========================================
484
+ // Status Filters
485
+ // ========================================
486
+ /** Toggle a status filter on/off and rebuild the tree */
487
+ toggleStatusFilter(status) {
488
+ this.StatusFilters[status] = !this.StatusFilters[status];
489
+ this.applyFilters();
490
+ this.buildCategoryTree();
491
+ this.saveStatusFilters();
492
+ this.cdr.markForCheck();
493
+ }
494
+ /** Get the count of queries with a given status */
495
+ getStatusCount(status) {
496
+ return this.queries.filter(q => q.Status === status).length;
497
+ }
498
+ /** Get the CSS color for a query status */
499
+ getStatusColor(status) {
500
+ switch (status) {
501
+ case 'Approved': return '#28a745';
502
+ case 'Pending': return '#f59e0b';
503
+ case 'Rejected': return '#dc3545';
504
+ case 'Expired': return '#6c757d';
505
+ default: return '#6c757d';
506
+ }
507
+ }
508
+ /** Get the Font Awesome icon for a query status */
509
+ getStatusIcon(status) {
510
+ switch (status) {
511
+ case 'Approved': return 'fa-check-circle';
512
+ case 'Pending': return 'fa-clock';
513
+ case 'Rejected': return 'fa-times-circle';
514
+ case 'Expired': return 'fa-archive';
515
+ default: return 'fa-question-circle';
516
+ }
517
+ }
518
+ /** Apply both status and search filters to produce filteredQueries */
519
+ applyFilters() {
520
+ // First filter by status
521
+ let result = this.queries.filter(q => this.StatusFilters[q.Status] === true);
522
+ // Then filter by search text
523
+ if (this.searchText.trim()) {
524
+ const searchLower = this.searchText.toLowerCase();
525
+ result = result.filter(q => q.Name.toLowerCase().includes(searchLower) ||
526
+ q.Description?.toLowerCase().includes(searchLower) ||
527
+ q.Category?.toLowerCase().includes(searchLower));
528
+ }
529
+ this.filteredQueries = result;
530
+ }
531
+ /** Load saved status filter preferences */
532
+ loadSavedStatusFilters() {
533
+ const saved = UserInfoEngine.Instance.GetSetting(QueryBrowserResourceComponent_1.STATUS_FILTERS_KEY);
534
+ if (saved) {
535
+ try {
536
+ const parsed = JSON.parse(saved);
537
+ // Merge saved values onto defaults (preserves any new statuses added later)
538
+ for (const key of Object.keys(this.StatusFilters)) {
539
+ if (typeof parsed[key] === 'boolean') {
540
+ this.StatusFilters[key] = parsed[key];
541
+ }
542
+ }
543
+ }
544
+ catch {
545
+ // Ignore invalid JSON, keep defaults
546
+ }
547
+ }
548
+ }
549
+ /** Save status filter preferences with debouncing */
550
+ saveStatusFilters() {
551
+ UserInfoEngine.Instance.SetSettingDebounced(QueryBrowserResourceComponent_1.STATUS_FILTERS_KEY, JSON.stringify(this.StatusFilters));
552
+ }
553
+ /** Load saved expanded/collapsed state for category nodes */
554
+ loadSavedExpandedState() {
555
+ const saved = UserInfoEngine.Instance.GetSetting(QueryBrowserResourceComponent_1.EXPANDED_STATE_KEY);
556
+ if (saved) {
557
+ try {
558
+ const parsed = JSON.parse(saved);
559
+ for (const [key, value] of Object.entries(parsed)) {
560
+ if (typeof value === 'boolean') {
561
+ this.expandedState.set(key, value);
562
+ }
563
+ }
564
+ }
565
+ catch {
566
+ // Ignore invalid JSON, start fresh
567
+ }
568
+ }
569
+ }
570
+ /** Save expanded/collapsed state with debouncing */
571
+ saveExpandedState() {
572
+ const obj = {};
573
+ for (const [key, value] of this.expandedState.entries()) {
574
+ obj[key] = value;
575
+ }
576
+ UserInfoEngine.Instance.SetSettingDebounced(QueryBrowserResourceComponent_1.EXPANDED_STATE_KEY, JSON.stringify(obj));
577
+ }
578
+ // ========================================
387
579
  // Tree Navigation
388
580
  // ========================================
389
581
  toggleExpand(node, event) {
@@ -391,26 +583,32 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
391
583
  event.stopPropagation();
392
584
  }
393
585
  node.expanded = !node.expanded;
586
+ this.expandedState.set(node.category.ID, node.expanded);
587
+ this.saveExpandedState();
394
588
  this.cdr.markForCheck();
395
589
  }
396
590
  expandAll() {
397
591
  const expand = (nodes) => {
398
592
  for (const node of nodes) {
399
593
  node.expanded = true;
594
+ this.expandedState.set(node.category.ID, true);
400
595
  expand(node.children);
401
596
  }
402
597
  };
403
598
  expand(this.categoryTree);
599
+ this.saveExpandedState();
404
600
  this.cdr.markForCheck();
405
601
  }
406
602
  collapseAll() {
407
603
  const collapse = (nodes) => {
408
604
  for (const node of nodes) {
409
605
  node.expanded = false;
606
+ this.expandedState.set(node.category.ID, false);
410
607
  collapse(node.children);
411
608
  }
412
609
  };
413
610
  collapse(this.categoryTree);
611
+ this.saveExpandedState();
414
612
  this.cdr.markForCheck();
415
613
  }
416
614
  selectQuery(query, event) {
@@ -440,9 +638,12 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
440
638
  // Query Viewer Events
441
639
  // ========================================
442
640
  onEntityLinkClick(event) {
443
- // Open the entity record using navigation service
444
- // Convert the recordId string to a CompositeKey (assumes single-field primary key)
445
- const compositeKey = CompositeKey.FromID(event.recordId);
641
+ // Look up the entity's actual primary key field name from metadata
642
+ const md = new Metadata();
643
+ const entity = md.Entities.find(e => e.Name === event.entityName);
644
+ const pkField = entity?.FirstPrimaryKey;
645
+ const pkFieldName = pkField?.Name || 'ID';
646
+ const compositeKey = new CompositeKey([{ FieldName: pkFieldName, Value: event.recordId }]);
446
647
  this.navigationService.OpenEntityRecord(event.entityName, compositeKey);
447
648
  }
448
649
  onRowDoubleClick(event) {
@@ -574,36 +775,24 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
574
775
  expandCategoryForQuery(query) {
575
776
  if (!query.CategoryID)
576
777
  return;
577
- const expandCategory = (nodes, targetCategoryId) => {
778
+ const expandToTarget = (nodes, targetCategoryId) => {
578
779
  for (const node of nodes) {
579
780
  if (UUIDsEqual(node.category.ID, targetCategoryId)) {
580
781
  node.expanded = true;
782
+ this.expandedState.set(node.category.ID, true);
581
783
  return true;
582
784
  }
583
- if (this.expandCategoryForQueryRecursive(node.children, targetCategoryId)) {
785
+ if (expandToTarget(node.children, targetCategoryId)) {
584
786
  node.expanded = true;
787
+ this.expandedState.set(node.category.ID, true);
585
788
  return true;
586
789
  }
587
790
  }
588
791
  return false;
589
792
  };
590
- expandCategory(this.categoryTree, query.CategoryID);
591
- }
592
- /**
593
- * Helper for recursive category expansion
594
- */
595
- expandCategoryForQueryRecursive(nodes, targetCategoryId) {
596
- for (const node of nodes) {
597
- if (UUIDsEqual(node.category.ID, targetCategoryId)) {
598
- node.expanded = true;
599
- return true;
600
- }
601
- if (node.children.length > 0 && this.expandCategoryForQueryRecursive(node.children, targetCategoryId)) {
602
- node.expanded = true;
603
- return true;
604
- }
793
+ if (expandToTarget(this.categoryTree, query.CategoryID)) {
794
+ this.saveExpandedState();
605
795
  }
606
- return false;
607
796
  }
608
797
  // ========================================
609
798
  // Panel Resize
@@ -659,7 +848,7 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
659
848
  return UUIDsEqual(this.selectedQuery?.ID, query.ID);
660
849
  }
661
850
  static ɵfac = function QueryBrowserResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || QueryBrowserResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
662
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryBrowserResourceComponent, selectors: [["mj-query-browser-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 33, vars: 15, consts: [["categoryNode", ""], [1, "query-browser-container"], [1, "query-tree-panel"], [1, "tree-header"], [1, "header-title"], [1, "fa-solid", "fa-database"], [1, "query-count"], [1, "header-actions"], ["title", "Expand all", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-folder-open"], ["title", "Collapse all", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-folder"], ["title", "Refresh", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "tree-search"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search queries...", 1, "search-input", 3, "input", "value"], [1, "clear-btn"], [1, "tree-content"], [1, "loading-state"], [1, "empty-state"], [1, "category-tree"], [1, "resize-handle", 3, "mousedown"], [1, "resize-handle-grip"], [1, "query-viewer-panel"], [1, "no-selection"], [3, "QueryId", "AutoRun", "SelectionMode"], [1, "clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["text", "Loading queries..."], [1, "fa-solid", "fa-database", "empty-icon"], [1, "fa-solid", "fa-search", "empty-icon"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "fa-solid", "fa-hand-pointer", "no-selection-icon"], [1, "no-selection-message"], [1, "no-selection-hint"], [3, "EntityLinkClick", "RowDoubleClick", "OpenQueryRecord", "QueryId", "AutoRun", "SelectionMode"], [1, "category-item", 3, "expanded", "padding-left"], [1, "category-item"], [1, "category-header", 3, "click"], [1, "fa-solid", "expand-icon"], [1, "fa-solid", "fa-folder", "category-icon"], [1, "category-name"], [1, "category-count"], [1, "category-queries"], [1, "query-item", 3, "selected", "hidden"], [1, "query-item", 3, "click"], [1, "fa-solid", "fa-file-code", "query-icon"], [1, "query-info"], [1, "query-name"], [1, "query-description"], ["title", "Has parameters", 1, "fa-solid", "fa-sliders", "param-icon"]], template: function QueryBrowserResourceComponent_Template(rf, ctx) { if (rf & 1) {
851
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryBrowserResourceComponent, selectors: [["mj-query-browser-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 36, vars: 15, consts: [["categoryNode", ""], [1, "query-browser-container"], [1, "query-tree-panel"], [1, "tree-header"], [1, "header-title"], [1, "fa-solid", "fa-database"], [1, "query-count"], [1, "header-actions"], ["title", "Expand all", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-folder-open"], ["title", "Collapse all", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-folder"], ["title", "Refresh", 1, "icon-btn", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "tree-search"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search queries...", 1, "search-input", 3, "input", "value"], [1, "clear-btn"], [1, "status-filter-bar"], [1, "tree-content"], [1, "loading-state"], [1, "empty-state"], [1, "category-tree"], [1, "resize-handle", 3, "mousedown"], [1, "resize-handle-grip"], [1, "query-viewer-panel"], [1, "no-selection"], [1, "clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "status-filter-chip", 3, "active", "--chip-color", "title"], [1, "status-filter-chip", 3, "click", "title"], [1, "fa-solid"], [1, "chip-count"], ["text", "Loading queries..."], [1, "fa-solid", "fa-database", "empty-icon"], [1, "fa-solid", "fa-search", "empty-icon"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "fa-solid", "fa-hand-pointer", "no-selection-icon"], [1, "no-selection-message"], [1, "no-selection-hint"], [1, "query-viewer-header"], [1, "query-viewer-title"], [1, "fa-solid", "fa-file-code"], [1, "query-viewer-status-pill", 3, "background"], [1, "query-viewer-status-pill", "approved", 3, "background"], [3, "EntityLinkClick", "RowDoubleClick", "OpenQueryRecord", "QueryId", "AutoRun", "SelectionMode"], [1, "query-viewer-status-pill"], [1, "query-viewer-status-pill", "approved"], [1, "fa-solid", "fa-check-circle"], [1, "category-item", 3, "expanded", "padding-left"], [1, "category-item"], [1, "category-header", 3, "click"], [1, "fa-solid", "expand-icon"], [1, "fa-solid", "fa-folder", "category-icon"], [1, "category-name"], [1, "category-count"], [1, "category-queries"], [1, "query-item", 3, "selected", "hidden"], [1, "query-item", 3, "click"], [1, "status-dot", 3, "title"], [1, "fa-solid", "fa-file-code", "query-icon"], [1, "query-info", 3, "title"], [1, "query-name"], [1, "query-description"], ["title", "Has parameters", 1, "fa-solid", "fa-sliders", "param-icon"], [1, "query-status-badge", 3, "background", "title"], [1, "query-status-badge", 3, "title"]], template: function QueryBrowserResourceComponent_Template(rf, ctx) { if (rf & 1) {
663
852
  const _r1 = i0.ɵɵgetCurrentView();
664
853
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div", 4);
665
854
  i0.ɵɵelement(4, "i", 5);
@@ -689,20 +878,23 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
689
878
  i0.ɵɵconditionalCreate(20, QueryBrowserResourceComponent_Conditional_20_Template, 2, 0, "button", 18);
690
879
  i0.ɵɵelementEnd()();
691
880
  i0.ɵɵelementStart(21, "div", 19);
692
- i0.ɵɵconditionalCreate(22, QueryBrowserResourceComponent_Conditional_22_Template, 2, 0, "div", 20);
693
- i0.ɵɵconditionalCreate(23, QueryBrowserResourceComponent_Conditional_23_Template, 4, 0, "div", 21);
694
- i0.ɵɵconditionalCreate(24, QueryBrowserResourceComponent_Conditional_24_Template, 4, 1, "div", 21);
695
- i0.ɵɵconditionalCreate(25, QueryBrowserResourceComponent_Conditional_25_Template, 3, 0, "div", 22);
881
+ i0.ɵɵrepeaterCreate(22, QueryBrowserResourceComponent_For_23_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
882
+ i0.ɵɵelementEnd();
883
+ i0.ɵɵelementStart(24, "div", 20);
884
+ i0.ɵɵconditionalCreate(25, QueryBrowserResourceComponent_Conditional_25_Template, 2, 0, "div", 21);
885
+ i0.ɵɵconditionalCreate(26, QueryBrowserResourceComponent_Conditional_26_Template, 4, 0, "div", 22);
886
+ i0.ɵɵconditionalCreate(27, QueryBrowserResourceComponent_Conditional_27_Template, 4, 1, "div", 22);
887
+ i0.ɵɵconditionalCreate(28, QueryBrowserResourceComponent_Conditional_28_Template, 3, 0, "div", 23);
696
888
  i0.ɵɵelementEnd()();
697
- i0.ɵɵelementStart(26, "div", 23);
698
- i0.ɵɵlistener("mousedown", function QueryBrowserResourceComponent_Template_div_mousedown_26_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onResizeStart($event)); });
699
- i0.ɵɵelement(27, "div", 24);
889
+ i0.ɵɵelementStart(29, "div", 24);
890
+ i0.ɵɵlistener("mousedown", function QueryBrowserResourceComponent_Template_div_mousedown_29_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onResizeStart($event)); });
891
+ i0.ɵɵelement(30, "div", 25);
700
892
  i0.ɵɵelementEnd();
701
- i0.ɵɵelementStart(28, "div", 25);
702
- i0.ɵɵconditionalCreate(29, QueryBrowserResourceComponent_Conditional_29_Template, 6, 0, "div", 26);
703
- i0.ɵɵconditionalCreate(30, QueryBrowserResourceComponent_Conditional_30_Template, 1, 3, "mj-query-viewer", 27);
893
+ i0.ɵɵelementStart(31, "div", 26);
894
+ i0.ɵɵconditionalCreate(32, QueryBrowserResourceComponent_Conditional_32_Template, 6, 0, "div", 27);
895
+ i0.ɵɵconditionalCreate(33, QueryBrowserResourceComponent_Conditional_33_Template, 8, 5);
704
896
  i0.ɵɵelementEnd()();
705
- i0.ɵɵtemplate(31, QueryBrowserResourceComponent_ng_template_31_Template, 1, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
897
+ i0.ɵɵtemplate(34, QueryBrowserResourceComponent_ng_template_34_Template, 1, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
706
898
  } if (rf & 2) {
707
899
  i0.ɵɵclassProp("resizing", ctx.IsResizing);
708
900
  i0.ɵɵadvance();
@@ -714,20 +906,22 @@ let QueryBrowserResourceComponent = class QueryBrowserResourceComponent extends
714
906
  i0.ɵɵadvance();
715
907
  i0.ɵɵconditional(ctx.searchText ? 20 : -1);
716
908
  i0.ɵɵadvance(2);
717
- i0.ɵɵconditional(ctx.isLoading ? 22 : -1);
909
+ i0.ɵɵrepeater(ctx.AllStatuses);
910
+ i0.ɵɵadvance(3);
911
+ i0.ɵɵconditional(ctx.isLoading ? 25 : -1);
718
912
  i0.ɵɵadvance();
719
- i0.ɵɵconditional(!ctx.isLoading && ctx.queries.length === 0 ? 23 : -1);
913
+ i0.ɵɵconditional(!ctx.isLoading && ctx.queries.length === 0 ? 26 : -1);
720
914
  i0.ɵɵadvance();
721
- i0.ɵɵconditional(!ctx.isLoading && ctx.searchText && ctx.filteredQueries.length === 0 ? 24 : -1);
915
+ i0.ɵɵconditional(!ctx.isLoading && ctx.searchText && ctx.filteredQueries.length === 0 ? 27 : -1);
722
916
  i0.ɵɵadvance();
723
- i0.ɵɵconditional(!ctx.isLoading && ctx.queries.length > 0 ? 25 : -1);
917
+ i0.ɵɵconditional(!ctx.isLoading && ctx.queries.length > 0 ? 28 : -1);
724
918
  i0.ɵɵadvance();
725
919
  i0.ɵɵclassProp("active", ctx.IsResizing);
726
920
  i0.ɵɵadvance(3);
727
- i0.ɵɵconditional(!ctx.selectedQuery ? 29 : -1);
921
+ i0.ɵɵconditional(!ctx.selectedQuery ? 32 : -1);
728
922
  i0.ɵɵadvance();
729
- i0.ɵɵconditional(ctx.selectedQuery ? 30 : -1);
730
- } }, dependencies: [i3.NgTemplateOutlet, i4.LoadingComponent, i5.QueryViewerComponent], styles: ["\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.query-browser-container[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: #f5f5f5;\n}\n\n\n\n.query-tree-panel[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #fff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n \n\n}\n\n\n\n.tree-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.query-count[_ngcontent-%COMP%] {\n font-weight: 400;\n opacity: 0.8;\n font-size: 13px;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.tree-search[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n width: 100%;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: #fff;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: #5c6bc0;\n box-shadow: 0 0 0 3px rgba(92, 107, 192, 0.15);\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: #888;\n margin-left: 10px;\n font-size: 14px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n padding: 8px 10px;\n font-size: 14px;\n background: transparent;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: #999;\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n margin-right: 4px;\n border-radius: 4px;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover {\n color: #333;\n background: #f0f0f0;\n}\n\n\n\n.tree-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%], \n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 36px;\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: #666;\n font-size: 14px;\n}\n\n\n\n.category-tree[_ngcontent-%COMP%] {\n padding: 0 4px;\n}\n\n.category-item[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.category-header[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #888;\n width: 12px;\n text-align: center;\n}\n\n.category-icon[_ngcontent-%COMP%] {\n color: #f9a825;\n font-size: 14px;\n}\n\n.category-name[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n color: #333;\n font-size: 13px;\n}\n\n.category-count[_ngcontent-%COMP%] {\n color: #888;\n font-size: 12px;\n}\n\n\n\n.category-queries[_ngcontent-%COMP%] {\n margin-left: 28px;\n}\n\n.query-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n margin: 2px 0;\n}\n\n.query-item[_ngcontent-%COMP%]:hover {\n background: #f0f7ff;\n}\n\n.query-item.selected[_ngcontent-%COMP%] {\n background: #e3f2fd;\n border-left: 3px solid #2196f3;\n margin-left: -3px;\n}\n\n.query-item.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.query-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n font-size: 14px;\n margin-top: 2px;\n}\n\n.query-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.query-name[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.param-icon[_ngcontent-%COMP%] {\n color: #f9a825;\n font-size: 12px;\n margin-top: 2px;\n}\n\n.query-details-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n color: #999;\n cursor: pointer;\n border-radius: 4px;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.query-item[_ngcontent-%COMP%]:hover .query-details-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.query-details-btn[_ngcontent-%COMP%]:hover {\n background: rgba(92, 107, 192, 0.15);\n color: #5c6bc0;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 6px;\n cursor: col-resize;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease;\n position: relative;\n z-index: 10;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover, \n.resize-handle.active[_ngcontent-%COMP%] {\n background: rgba(92, 107, 192, 0.15);\n}\n\n.resize-handle-grip[_ngcontent-%COMP%] {\n width: 2px;\n height: 32px;\n border-radius: 1px;\n background: #ccc;\n transition: background 0.15s ease;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover .resize-handle-grip[_ngcontent-%COMP%], \n.resize-handle.active[_ngcontent-%COMP%] .resize-handle-grip[_ngcontent-%COMP%] {\n background: #5c6bc0;\n}\n\n\n\n.query-browser-container.resizing[_ngcontent-%COMP%] {\n cursor: col-resize;\n user-select: none;\n}\n\n.query-browser-container.resizing[_ngcontent-%COMP%] *[_ngcontent-%COMP%] {\n pointer-events: none;\n}\n\n.query-browser-container.resizing[_ngcontent-%COMP%] .resize-handle[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n\n\n.query-viewer-panel[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n font-size: 64px;\n color: #ddd;\n margin-bottom: 20px;\n}\n\n.no-selection-message[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #666;\n margin: 0 0 8px 0;\n}\n\n.no-selection-hint[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #999;\n margin: 0;\n}\n\n\n\nmj-query-viewer[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}\n\n\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f1f1f1;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n\n\n\n@media (max-width: 768px) {\n .query-browser-container[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .query-tree-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n height: 40%;\n border-right: none;\n border-bottom: 1px solid #e0e0e0;\n }\n\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .query-viewer-panel[_ngcontent-%COMP%] {\n height: 60%;\n }\n}"], changeDetection: 0 });
923
+ i0.ɵɵconditional(ctx.selectedQuery ? 33 : -1);
924
+ } }, dependencies: [i3.NgTemplateOutlet, i4.LoadingComponent, i5.QueryViewerComponent], styles: ["\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.query-browser-container[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: #f5f5f5;\n}\n\n\n\n.query-tree-panel[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #fff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n \n\n}\n\n\n\n.tree-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.query-count[_ngcontent-%COMP%] {\n font-weight: 400;\n opacity: 0.8;\n font-size: 13px;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.tree-search[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n width: 100%;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: #fff;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: #5c6bc0;\n box-shadow: 0 0 0 3px rgba(92, 107, 192, 0.15);\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: #888;\n margin-left: 10px;\n font-size: 14px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n padding: 8px 10px;\n font-size: 14px;\n background: transparent;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: #999;\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n margin-right: 4px;\n border-radius: 4px;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover {\n color: #333;\n background: #f0f0f0;\n}\n\n\n\n.status-filter-bar[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n}\n\n.status-filter-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #ddd;\n border-radius: 12px;\n background: #fff;\n color: #888;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n line-height: 1.2;\n}\n\n.status-filter-chip[_ngcontent-%COMP%]:hover {\n border-color: var(--chip-color, #888);\n color: var(--chip-color, #888);\n}\n\n.status-filter-chip.active[_ngcontent-%COMP%] {\n background: var(--chip-color, #888);\n border-color: var(--chip-color, #888);\n color: #fff;\n}\n\n.status-filter-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.chip-count[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 10px;\n opacity: 0.85;\n}\n\n\n\n.status-dot[_ngcontent-%COMP%] {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 4px;\n}\n\n\n\n.query-status-badge[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #fff;\n padding: 1px 6px;\n border-radius: 8px;\n flex-shrink: 0;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-top: 2px;\n}\n\n\n\n.tree-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%], \n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 36px;\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: #666;\n font-size: 14px;\n}\n\n\n\n.category-tree[_ngcontent-%COMP%] {\n padding: 0 4px;\n}\n\n.category-item[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.category-header[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #888;\n width: 12px;\n text-align: center;\n}\n\n.category-icon[_ngcontent-%COMP%] {\n color: #f9a825;\n font-size: 14px;\n}\n\n.category-name[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n color: #333;\n font-size: 13px;\n}\n\n.category-count[_ngcontent-%COMP%] {\n color: #888;\n font-size: 12px;\n}\n\n\n\n.category-queries[_ngcontent-%COMP%] {\n margin-left: 28px;\n}\n\n.query-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n margin: 2px 0;\n}\n\n.query-item[_ngcontent-%COMP%]:hover {\n background: #f0f7ff;\n}\n\n.query-item.selected[_ngcontent-%COMP%] {\n background: #e3f2fd;\n border-left: 3px solid #2196f3;\n margin-left: -3px;\n}\n\n.query-item.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.query-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n font-size: 14px;\n margin-top: 2px;\n}\n\n.query-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.query-name[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.param-icon[_ngcontent-%COMP%] {\n color: #f9a825;\n font-size: 12px;\n margin-top: 2px;\n}\n\n.query-details-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n color: #999;\n cursor: pointer;\n border-radius: 4px;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.query-item[_ngcontent-%COMP%]:hover .query-details-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.query-details-btn[_ngcontent-%COMP%]:hover {\n background: rgba(92, 107, 192, 0.15);\n color: #5c6bc0;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 6px;\n cursor: col-resize;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease;\n position: relative;\n z-index: 10;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover, \n.resize-handle.active[_ngcontent-%COMP%] {\n background: rgba(92, 107, 192, 0.15);\n}\n\n.resize-handle-grip[_ngcontent-%COMP%] {\n width: 2px;\n height: 32px;\n border-radius: 1px;\n background: #ccc;\n transition: background 0.15s ease;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover .resize-handle-grip[_ngcontent-%COMP%], \n.resize-handle.active[_ngcontent-%COMP%] .resize-handle-grip[_ngcontent-%COMP%] {\n background: #5c6bc0;\n}\n\n\n\n.query-browser-container.resizing[_ngcontent-%COMP%] {\n cursor: col-resize;\n user-select: none;\n}\n\n.query-browser-container.resizing[_ngcontent-%COMP%] *[_ngcontent-%COMP%] {\n pointer-events: none;\n}\n\n.query-browser-container.resizing[_ngcontent-%COMP%] .resize-handle[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n\n\n.query-viewer-panel[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n font-size: 64px;\n color: #ddd;\n margin-bottom: 20px;\n}\n\n.no-selection-message[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #666;\n margin: 0 0 8px 0;\n}\n\n.no-selection-hint[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #999;\n margin: 0;\n}\n\n\n\n.query-viewer-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.query-viewer-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 15px;\n font-weight: 600;\n color: #333;\n min-width: 0;\n overflow: hidden;\n}\n\n.query-viewer-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #5c6bc0;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.query-viewer-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-viewer-status-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n flex-shrink: 0;\n}\n\n.query-viewer-status-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.query-viewer-status-pill.approved[_ngcontent-%COMP%] {\n opacity: 0.7;\n}\n\n\n\nmj-query-viewer[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}\n\n\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f1f1f1;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.tree-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n\n\n\n@media (max-width: 768px) {\n .query-browser-container[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .query-tree-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n height: 40%;\n border-right: none;\n border-bottom: 1px solid #e0e0e0;\n }\n\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .query-viewer-panel[_ngcontent-%COMP%] {\n height: 60%;\n }\n}"], changeDetection: 0 });
731
925
  };
732
926
  QueryBrowserResourceComponent = QueryBrowserResourceComponent_1 = __decorate([
733
927
  RegisterClass(BaseResourceComponent, 'QueryBrowserResource')
@@ -735,7 +929,7 @@ QueryBrowserResourceComponent = QueryBrowserResourceComponent_1 = __decorate([
735
929
  export { QueryBrowserResourceComponent };
736
930
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(QueryBrowserResourceComponent, [{
737
931
  type: Component,
738
- args: [{ standalone: false, selector: 'mj-query-browser-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Query Browser Resource -->\n<div class=\"query-browser-container\" [class.resizing]=\"IsResizing\">\n <!-- Left Panel: Query Tree -->\n <div class=\"query-tree-panel\" [style.width.px]=\"PanelWidth\">\n <!-- Header -->\n <div class=\"tree-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-database\"></i>\n <span>Queries</span>\n <span class=\"query-count\">({{ getTotalQueryCount() }})</span>\n </div>\n <div class=\"header-actions\">\n <button class=\"icon-btn\" (click)=\"expandAll()\" title=\"Expand all\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </button>\n <button class=\"icon-btn\" (click)=\"collapseAll()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-folder\"></i>\n </button>\n <button class=\"icon-btn\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"tree-search\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n [value]=\"searchText\"\n placeholder=\"Search queries...\"\n (input)=\"onSearchChange($any($event.target).value)\">\n @if (searchText) {\n <button class=\"clear-btn\" (click)=\"clearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n\n <!-- Tree Content -->\n <div class=\"tree-content\">\n <!-- Loading -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading queries...\"></mj-loading>\n </div>\n }\n\n <!-- Empty -->\n @if (!isLoading && queries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-icon\"></i>\n <p>No queries available</p>\n </div>\n }\n\n <!-- No results -->\n @if (!isLoading && searchText && filteredQueries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search empty-icon\"></i>\n <p>No queries match \"{{ searchText }}\"</p>\n </div>\n }\n\n <!-- Category Tree -->\n @if (!isLoading && queries.length > 0) {\n <div class=\"category-tree\">\n @for (node of categoryTree; track trackByCategory($index, node)) {\n <ng-container *ngTemplateOutlet=\"categoryNode; context: { node: node }\"></ng-container>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n [class.active]=\"IsResizing\"\n (mousedown)=\"onResizeStart($event)\">\n <div class=\"resize-handle-grip\"></div>\n </div>\n\n <!-- Right Panel: Query Viewer -->\n <div class=\"query-viewer-panel\">\n <!-- No query selected -->\n @if (!selectedQuery) {\n <div class=\"no-selection\">\n <i class=\"fa-solid fa-hand-pointer no-selection-icon\"></i>\n <p class=\"no-selection-message\">Select a query from the list</p>\n <p class=\"no-selection-hint\">Click on a query to view and run it</p>\n </div>\n }\n\n <!-- Query Viewer -->\n @if (selectedQuery) {\n <mj-query-viewer\n [QueryId]=\"selectedQuery.ID\"\n [AutoRun]=\"true\"\n [SelectionMode]=\"'multiple'\"\n (EntityLinkClick)=\"onEntityLinkClick($event)\"\n (RowDoubleClick)=\"onRowDoubleClick($event)\"\n (OpenQueryRecord)=\"onOpenQueryRecord($event)\">\n </mj-query-viewer>\n }\n </div>\n</div>\n\n<!-- Category Node Template -->\n<ng-template #categoryNode let-node=\"node\">\n @if (hasVisibleContent(node)) {\n <div class=\"category-item\"\n [class.expanded]=\"node.expanded\"\n [style.padding-left.px]=\"node.level * 16 + 8\">\n <div class=\"category-header\" (click)=\"toggleExpand(node)\">\n <i class=\"fa-solid expand-icon\"\n [class.fa-chevron-down]=\"node.expanded\"\n [class.fa-chevron-right]=\"!node.expanded\"></i>\n <i class=\"fa-solid fa-folder category-icon\"\n [class.fa-folder-open]=\"node.expanded\"></i>\n <span class=\"category-name\">{{ node.category.Name }}</span>\n <span class=\"category-count\">({{ getNodeQueryCount(node) }})</span>\n </div>\n <!-- Queries in this category -->\n @if (node.expanded) {\n <div class=\"category-queries\">\n @for (query of node.queries; track trackByQuery($index, query)) {\n <div class=\"query-item\"\n [class.selected]=\"IsQuerySelected(query)\"\n [class.hidden]=\"!isQueryVisible(query)\"\n (click)=\"selectQuery(query, $event)\">\n <i class=\"fa-solid fa-file-code query-icon\"></i>\n <div class=\"query-info\">\n <span class=\"query-name\">{{ query.Name }}</span>\n @if (query.Description) {\n <span class=\"query-description\">{{ query.Description }}</span>\n }\n </div>\n @if (query.UsesTemplate) {\n <i class=\"fa-solid fa-sliders param-icon\" title=\"Has parameters\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Child categories -->\n @if (node.expanded) {\n @for (child of node.children; track trackByCategory($index, child)) {\n <ng-container *ngTemplateOutlet=\"categoryNode; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n</ng-template>\n", styles: ["/* Query Browser Resource Styles */\n\n:host {\n display: block;\n height: 100%;\n}\n\n.query-browser-container {\n display: flex;\n height: 100%;\n background: #f5f5f5;\n}\n\n/* Left Panel: Query Tree */\n.query-tree-panel {\n flex-shrink: 0;\n background: #fff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n /* Width controlled by [style.width.px] binding */\n}\n\n/* Tree Header */\n.tree-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.header-title i {\n font-size: 16px;\n}\n\n.query-count {\n font-weight: 400;\n opacity: 0.8;\n font-size: 13px;\n}\n\n.header-actions {\n display: flex;\n gap: 4px;\n}\n\n.icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.icon-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Tree Search */\n.tree-search {\n padding: 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n width: 100%;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: #fff;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.search-input-wrapper:focus-within {\n border-color: #5c6bc0;\n box-shadow: 0 0 0 3px rgba(92, 107, 192, 0.15);\n}\n\n.search-icon {\n color: #888;\n margin-left: 10px;\n font-size: 14px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n padding: 8px 10px;\n font-size: 14px;\n background: transparent;\n}\n\n.search-input::placeholder {\n color: #999;\n}\n\n.clear-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n margin-right: 4px;\n border-radius: 4px;\n}\n\n.clear-btn:hover {\n color: #333;\n background: #f0f0f0;\n}\n\n/* Tree Content */\n.tree-content {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n}\n\n/* Loading & Empty States */\n.loading-state,\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 36px;\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.empty-state p {\n margin: 0;\n color: #666;\n font-size: 14px;\n}\n\n/* Category Tree */\n.category-tree {\n padding: 0 4px;\n}\n\n.category-item {\n margin-bottom: 2px;\n}\n\n.category-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.category-header:hover {\n background: #f0f0f0;\n}\n\n.expand-icon {\n font-size: 10px;\n color: #888;\n width: 12px;\n text-align: center;\n}\n\n.category-icon {\n color: #f9a825;\n font-size: 14px;\n}\n\n.category-name {\n flex: 1;\n font-weight: 500;\n color: #333;\n font-size: 13px;\n}\n\n.category-count {\n color: #888;\n font-size: 12px;\n}\n\n/* Query Items */\n.category-queries {\n margin-left: 28px;\n}\n\n.query-item {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n margin: 2px 0;\n}\n\n.query-item:hover {\n background: #f0f7ff;\n}\n\n.query-item.selected {\n background: #e3f2fd;\n border-left: 3px solid #2196f3;\n margin-left: -3px;\n}\n\n.query-item.hidden {\n display: none;\n}\n\n.query-icon {\n color: #5c6bc0;\n font-size: 14px;\n margin-top: 2px;\n}\n\n.query-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.query-name {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-description {\n font-size: 11px;\n color: #888;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.param-icon {\n color: #f9a825;\n font-size: 12px;\n margin-top: 2px;\n}\n\n.query-details-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n color: #999;\n cursor: pointer;\n border-radius: 4px;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.query-item:hover .query-details-btn {\n opacity: 1;\n}\n\n.query-details-btn:hover {\n background: rgba(92, 107, 192, 0.15);\n color: #5c6bc0;\n}\n\n/* Resize Handle */\n.resize-handle {\n flex-shrink: 0;\n width: 6px;\n cursor: col-resize;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease;\n position: relative;\n z-index: 10;\n}\n\n.resize-handle:hover,\n.resize-handle.active {\n background: rgba(92, 107, 192, 0.15);\n}\n\n.resize-handle-grip {\n width: 2px;\n height: 32px;\n border-radius: 1px;\n background: #ccc;\n transition: background 0.15s ease;\n}\n\n.resize-handle:hover .resize-handle-grip,\n.resize-handle.active .resize-handle-grip {\n background: #5c6bc0;\n}\n\n/* Prevent text selection and set cursor during resize */\n.query-browser-container.resizing {\n cursor: col-resize;\n user-select: none;\n}\n\n.query-browser-container.resizing * {\n pointer-events: none;\n}\n\n.query-browser-container.resizing .resize-handle {\n pointer-events: auto;\n}\n\n/* Right Panel: Query Viewer */\n.query-viewer-panel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n/* No Selection State */\n.no-selection {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px;\n}\n\n.no-selection-icon {\n font-size: 64px;\n color: #ddd;\n margin-bottom: 20px;\n}\n\n.no-selection-message {\n font-size: 18px;\n color: #666;\n margin: 0 0 8px 0;\n}\n\n.no-selection-hint {\n font-size: 14px;\n color: #999;\n margin: 0;\n}\n\n/* Query Viewer fills remaining space */\nmj-query-viewer {\n flex: 1;\n min-height: 0;\n}\n\n/* Scrollbar styling */\n.tree-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.tree-content::-webkit-scrollbar-track {\n background: #f1f1f1;\n}\n\n.tree-content::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.tree-content::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .query-browser-container {\n flex-direction: column;\n }\n\n .query-tree-panel {\n width: 100% !important;\n height: 40%;\n border-right: none;\n border-bottom: 1px solid #e0e0e0;\n }\n\n .resize-handle {\n display: none;\n }\n\n .query-viewer-panel {\n height: 60%;\n }\n}\n"] }]
932
+ args: [{ standalone: false, selector: 'mj-query-browser-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Query Browser Resource -->\n<div class=\"query-browser-container\" [class.resizing]=\"IsResizing\">\n <!-- Left Panel: Query Tree -->\n <div class=\"query-tree-panel\" [style.width.px]=\"PanelWidth\">\n <!-- Header -->\n <div class=\"tree-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-database\"></i>\n <span>Queries</span>\n <span class=\"query-count\">({{ getTotalQueryCount() }})</span>\n </div>\n <div class=\"header-actions\">\n <button class=\"icon-btn\" (click)=\"expandAll()\" title=\"Expand all\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </button>\n <button class=\"icon-btn\" (click)=\"collapseAll()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-folder\"></i>\n </button>\n <button class=\"icon-btn\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"tree-search\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n [value]=\"searchText\"\n placeholder=\"Search queries...\"\n (input)=\"onSearchChange($any($event.target).value)\">\n @if (searchText) {\n <button class=\"clear-btn\" (click)=\"clearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n\n <!-- Status Filters -->\n <div class=\"status-filter-bar\">\n @for (status of AllStatuses; track status) {\n @if (getStatusCount(status) > 0) {\n <button class=\"status-filter-chip\"\n [class.active]=\"StatusFilters[status]\"\n [style.--chip-color]=\"getStatusColor(status)\"\n (click)=\"toggleStatusFilter(status)\"\n [title]=\"(StatusFilters[status] ? 'Hide' : 'Show') + ' ' + status + ' queries'\">\n <i class=\"fa-solid\" [class]=\"getStatusIcon(status)\"></i>\n <span>{{ status }}</span>\n <span class=\"chip-count\">{{ getStatusCount(status) }}</span>\n </button>\n }\n }\n </div>\n\n <!-- Tree Content -->\n <div class=\"tree-content\">\n <!-- Loading -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading queries...\"></mj-loading>\n </div>\n }\n\n <!-- Empty -->\n @if (!isLoading && queries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-icon\"></i>\n <p>No queries available</p>\n </div>\n }\n\n <!-- No results -->\n @if (!isLoading && searchText && filteredQueries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search empty-icon\"></i>\n <p>No queries match \"{{ searchText }}\"</p>\n </div>\n }\n\n <!-- Category Tree -->\n @if (!isLoading && queries.length > 0) {\n <div class=\"category-tree\">\n @for (node of categoryTree; track trackByCategory($index, node)) {\n <ng-container *ngTemplateOutlet=\"categoryNode; context: { node: node }\"></ng-container>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n [class.active]=\"IsResizing\"\n (mousedown)=\"onResizeStart($event)\">\n <div class=\"resize-handle-grip\"></div>\n </div>\n\n <!-- Right Panel: Query Viewer -->\n <div class=\"query-viewer-panel\">\n <!-- No query selected -->\n @if (!selectedQuery) {\n <div class=\"no-selection\">\n <i class=\"fa-solid fa-hand-pointer no-selection-icon\"></i>\n <p class=\"no-selection-message\">Select a query from the list</p>\n <p class=\"no-selection-hint\">Click on a query to view and run it</p>\n </div>\n }\n\n <!-- Query Viewer -->\n @if (selectedQuery) {\n <!-- Query Header with Status -->\n <div class=\"query-viewer-header\">\n <div class=\"query-viewer-title\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>{{ selectedQuery.Name }}</span>\n </div>\n @if (selectedQuery.Status !== 'Approved') {\n <span class=\"query-viewer-status-pill\"\n [style.background]=\"getStatusColor(selectedQuery.Status)\">\n <i class=\"fa-solid\" [class]=\"getStatusIcon(selectedQuery.Status)\"></i>\n {{ selectedQuery.Status }}\n </span>\n } @else {\n <span class=\"query-viewer-status-pill approved\"\n [style.background]=\"getStatusColor('Approved')\">\n <i class=\"fa-solid fa-check-circle\"></i>\n Approved\n </span>\n }\n </div>\n <mj-query-viewer\n [QueryId]=\"selectedQuery.ID\"\n [AutoRun]=\"true\"\n [SelectionMode]=\"'multiple'\"\n (EntityLinkClick)=\"onEntityLinkClick($event)\"\n (RowDoubleClick)=\"onRowDoubleClick($event)\"\n (OpenQueryRecord)=\"onOpenQueryRecord($event)\">\n </mj-query-viewer>\n }\n </div>\n</div>\n\n<!-- Category Node Template -->\n<ng-template #categoryNode let-node=\"node\">\n @if (hasVisibleContent(node)) {\n <div class=\"category-item\"\n [class.expanded]=\"node.expanded\"\n [style.padding-left.px]=\"node.level * 16 + 8\">\n <div class=\"category-header\" (click)=\"toggleExpand(node)\">\n <i class=\"fa-solid expand-icon\"\n [class.fa-chevron-down]=\"node.expanded\"\n [class.fa-chevron-right]=\"!node.expanded\"></i>\n <i class=\"fa-solid fa-folder category-icon\"\n [class.fa-folder-open]=\"node.expanded\"></i>\n <span class=\"category-name\">{{ node.category.Name }}</span>\n <span class=\"category-count\">({{ getNodeQueryCount(node) }})</span>\n </div>\n <!-- Queries in this category -->\n @if (node.expanded) {\n <div class=\"category-queries\">\n @for (query of node.queries; track trackByQuery($index, query)) {\n <div class=\"query-item\"\n [class.selected]=\"IsQuerySelected(query)\"\n [class.hidden]=\"!isQueryVisible(query)\"\n (click)=\"selectQuery(query, $event)\">\n <span class=\"status-dot\"\n [style.background]=\"getStatusColor(query.Status)\"\n [title]=\"query.Status\"></span>\n <i class=\"fa-solid fa-file-code query-icon\"></i>\n <div class=\"query-info\" [title]=\"query.Description || query.Name\">\n <span class=\"query-name\">{{ query.Name }}</span>\n @if (query.Description) {\n <span class=\"query-description\">{{ query.Description }}</span>\n }\n </div>\n @if (query.UsesTemplate) {\n <i class=\"fa-solid fa-sliders param-icon\" title=\"Has parameters\"></i>\n }\n @if (query.Status !== 'Approved') {\n <span class=\"query-status-badge\"\n [style.background]=\"getStatusColor(query.Status)\"\n [title]=\"query.Status\">\n {{ query.Status }}\n </span>\n }\n </div>\n }\n </div>\n }\n <!-- Child categories -->\n @if (node.expanded) {\n @for (child of node.children; track trackByCategory($index, child)) {\n <ng-container *ngTemplateOutlet=\"categoryNode; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n</ng-template>\n", styles: ["/* Query Browser Resource Styles */\n\n:host {\n display: block;\n height: 100%;\n}\n\n.query-browser-container {\n display: flex;\n height: 100%;\n background: #f5f5f5;\n}\n\n/* Left Panel: Query Tree */\n.query-tree-panel {\n flex-shrink: 0;\n background: #fff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n /* Width controlled by [style.width.px] binding */\n}\n\n/* Tree Header */\n.tree-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.header-title i {\n font-size: 16px;\n}\n\n.query-count {\n font-weight: 400;\n opacity: 0.8;\n font-size: 13px;\n}\n\n.header-actions {\n display: flex;\n gap: 4px;\n}\n\n.icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.icon-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Tree Search */\n.tree-search {\n padding: 12px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n width: 100%;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: #fff;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.search-input-wrapper:focus-within {\n border-color: #5c6bc0;\n box-shadow: 0 0 0 3px rgba(92, 107, 192, 0.15);\n}\n\n.search-icon {\n color: #888;\n margin-left: 10px;\n font-size: 14px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n padding: 8px 10px;\n font-size: 14px;\n background: transparent;\n}\n\n.search-input::placeholder {\n color: #999;\n}\n\n.clear-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n margin-right: 4px;\n border-radius: 4px;\n}\n\n.clear-btn:hover {\n color: #333;\n background: #f0f0f0;\n}\n\n/* Status Filter Bar */\n.status-filter-bar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 12px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n}\n\n.status-filter-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid #ddd;\n border-radius: 12px;\n background: #fff;\n color: #888;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n line-height: 1.2;\n}\n\n.status-filter-chip:hover {\n border-color: var(--chip-color, #888);\n color: var(--chip-color, #888);\n}\n\n.status-filter-chip.active {\n background: var(--chip-color, #888);\n border-color: var(--chip-color, #888);\n color: #fff;\n}\n\n.status-filter-chip i {\n font-size: 10px;\n}\n\n.chip-count {\n font-weight: 600;\n font-size: 10px;\n opacity: 0.85;\n}\n\n/* Status Dot on Query Items */\n.status-dot {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 4px;\n}\n\n/* Status Badge on Non-Approved Queries */\n.query-status-badge {\n font-size: 9px;\n color: #fff;\n padding: 1px 6px;\n border-radius: 8px;\n flex-shrink: 0;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-top: 2px;\n}\n\n/* Tree Content */\n.tree-content {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n}\n\n/* Loading & Empty States */\n.loading-state,\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 36px;\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.empty-state p {\n margin: 0;\n color: #666;\n font-size: 14px;\n}\n\n/* Category Tree */\n.category-tree {\n padding: 0 4px;\n}\n\n.category-item {\n margin-bottom: 2px;\n}\n\n.category-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.category-header:hover {\n background: #f0f0f0;\n}\n\n.expand-icon {\n font-size: 10px;\n color: #888;\n width: 12px;\n text-align: center;\n}\n\n.category-icon {\n color: #f9a825;\n font-size: 14px;\n}\n\n.category-name {\n flex: 1;\n font-weight: 500;\n color: #333;\n font-size: 13px;\n}\n\n.category-count {\n color: #888;\n font-size: 12px;\n}\n\n/* Query Items */\n.category-queries {\n margin-left: 28px;\n}\n\n.query-item {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s ease;\n margin: 2px 0;\n}\n\n.query-item:hover {\n background: #f0f7ff;\n}\n\n.query-item.selected {\n background: #e3f2fd;\n border-left: 3px solid #2196f3;\n margin-left: -3px;\n}\n\n.query-item.hidden {\n display: none;\n}\n\n.query-icon {\n color: #5c6bc0;\n font-size: 14px;\n margin-top: 2px;\n}\n\n.query-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.query-name {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-description {\n font-size: 11px;\n color: #888;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.param-icon {\n color: #f9a825;\n font-size: 12px;\n margin-top: 2px;\n}\n\n.query-details-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n color: #999;\n cursor: pointer;\n border-radius: 4px;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.query-item:hover .query-details-btn {\n opacity: 1;\n}\n\n.query-details-btn:hover {\n background: rgba(92, 107, 192, 0.15);\n color: #5c6bc0;\n}\n\n/* Resize Handle */\n.resize-handle {\n flex-shrink: 0;\n width: 6px;\n cursor: col-resize;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease;\n position: relative;\n z-index: 10;\n}\n\n.resize-handle:hover,\n.resize-handle.active {\n background: rgba(92, 107, 192, 0.15);\n}\n\n.resize-handle-grip {\n width: 2px;\n height: 32px;\n border-radius: 1px;\n background: #ccc;\n transition: background 0.15s ease;\n}\n\n.resize-handle:hover .resize-handle-grip,\n.resize-handle.active .resize-handle-grip {\n background: #5c6bc0;\n}\n\n/* Prevent text selection and set cursor during resize */\n.query-browser-container.resizing {\n cursor: col-resize;\n user-select: none;\n}\n\n.query-browser-container.resizing * {\n pointer-events: none;\n}\n\n.query-browser-container.resizing .resize-handle {\n pointer-events: auto;\n}\n\n/* Right Panel: Query Viewer */\n.query-viewer-panel {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n/* No Selection State */\n.no-selection {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px;\n}\n\n.no-selection-icon {\n font-size: 64px;\n color: #ddd;\n margin-bottom: 20px;\n}\n\n.no-selection-message {\n font-size: 18px;\n color: #666;\n margin: 0 0 8px 0;\n}\n\n.no-selection-hint {\n font-size: 14px;\n color: #999;\n margin: 0;\n}\n\n/* Query Viewer Header */\n.query-viewer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.query-viewer-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 15px;\n font-weight: 600;\n color: #333;\n min-width: 0;\n overflow: hidden;\n}\n\n.query-viewer-title i {\n color: #5c6bc0;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.query-viewer-title span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-viewer-status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n flex-shrink: 0;\n}\n\n.query-viewer-status-pill i {\n font-size: 12px;\n}\n\n.query-viewer-status-pill.approved {\n opacity: 0.7;\n}\n\n/* Query Viewer fills remaining space */\nmj-query-viewer {\n flex: 1;\n min-height: 0;\n}\n\n/* Scrollbar styling */\n.tree-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.tree-content::-webkit-scrollbar-track {\n background: #f1f1f1;\n}\n\n.tree-content::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.tree-content::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .query-browser-container {\n flex-direction: column;\n }\n\n .query-tree-panel {\n width: 100% !important;\n height: 40%;\n border-right: none;\n border-bottom: 1px solid #e0e0e0;\n }\n\n .resize-handle {\n display: none;\n }\n\n .query-viewer-panel {\n height: 60%;\n }\n}\n"] }]
739
933
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }, { type: i2.Router }, { type: i0.ElementRef }, { type: i0.NgZone }], null); })();
740
934
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(QueryBrowserResourceComponent, { className: "QueryBrowserResourceComponent", filePath: "src/QueryBrowser/query-browser-resource.component.ts", lineNumber: 40 }); })();
741
935
  //# sourceMappingURL=query-browser-resource.component.js.map