@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.
- package/dist/AI/components/models/model-management.component.d.ts +2 -0
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +44 -2
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +5 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +10 -7
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts +96 -0
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -0
- package/dist/Integration/components/activity/activity.component.js +961 -0
- package/dist/Integration/components/activity/activity.component.js.map +1 -0
- package/dist/Integration/components/connections/connections.component.d.ts +194 -0
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -0
- package/dist/Integration/components/connections/connections.component.js +2368 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -0
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts +241 -0
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -0
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +2373 -0
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -0
- package/dist/Integration/components/overview/overview.component.d.ts +60 -0
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -0
- package/dist/Integration/components/overview/overview.component.js +628 -0
- package/dist/Integration/components/overview/overview.component.js.map +1 -0
- package/dist/Integration/components/pipelines/pipelines.component.d.ts +203 -0
- package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -0
- package/dist/Integration/components/pipelines/pipelines.component.js +2057 -0
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts +110 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -0
- package/dist/Integration/components/schedules/schedules.component.js +842 -0
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -0
- package/dist/Integration/components/visual-editor/visual-editor.component.d.ts +141 -0
- package/dist/Integration/components/visual-editor/visual-editor.component.d.ts.map +1 -0
- package/dist/Integration/components/visual-editor/visual-editor.component.js +1538 -0
- package/dist/Integration/components/visual-editor/visual-editor.component.js.map +1 -0
- package/dist/Integration/components/widgets/integration-card.component.d.ts +22 -0
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -0
- package/dist/Integration/components/widgets/integration-card.component.js +262 -0
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -0
- package/dist/Integration/components/widgets/run-history-panel.component.d.ts +29 -0
- package/dist/Integration/components/widgets/run-history-panel.component.d.ts.map +1 -0
- package/dist/Integration/components/widgets/run-history-panel.component.js +399 -0
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -0
- package/dist/Integration/index.d.ts +11 -0
- package/dist/Integration/index.d.ts.map +1 -0
- package/dist/Integration/index.js +20 -0
- package/dist/Integration/index.js.map +1 -0
- package/dist/Integration/integration.module.d.ts +26 -0
- package/dist/Integration/integration.module.d.ts.map +1 -0
- package/dist/Integration/integration.module.js +107 -0
- package/dist/Integration/integration.module.js.map +1 -0
- package/dist/Integration/services/integration-data.service.d.ts +268 -0
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -0
- package/dist/Integration/services/integration-data.service.js +697 -0
- package/dist/Integration/services/integration-data.service.js.map +1 -0
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +27 -4
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +338 -144
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.d.ts +2 -0
- package/dist/__tests__/integration-data-service.test.d.ts.map +1 -0
- package/dist/__tests__/integration-data-service.test.js +131 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -0
- package/dist/__tests__/mapping-validation.test.d.ts +2 -0
- package/dist/__tests__/mapping-validation.test.d.ts.map +1 -0
- package/dist/__tests__/mapping-validation.test.js +170 -0
- package/dist/__tests__/mapping-validation.test.js.map +1 -0
- package/dist/module.d.ts +2 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +17 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +2 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -1
- package/dist/public-api.js.map +1 -1
- 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
|
|
31
|
-
i0.ɵɵ
|
|
32
|
-
i0.ɵɵ
|
|
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
|
|
61
|
+
function QueryBrowserResourceComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
36
62
|
i0.ɵɵelementStart(0, "div", 21);
|
|
37
|
-
i0.ɵɵelement(1, "
|
|
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
|
|
43
|
-
i0.ɵɵelementStart(0, "div",
|
|
44
|
-
i0.ɵɵelement(1, "i",
|
|
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
|
|
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
|
|
57
|
-
i0.ɵɵtemplate(0,
|
|
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
|
|
90
|
+
const node_r6 = ctx.$implicit;
|
|
60
91
|
i0.ɵɵnextContext(2);
|
|
61
|
-
const
|
|
62
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
92
|
+
const categoryNode_r7 = i0.ɵɵreference(35);
|
|
93
|
+
i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r7)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, node_r6));
|
|
63
94
|
} }
|
|
64
|
-
function
|
|
65
|
-
i0.ɵɵelementStart(0, "div",
|
|
66
|
-
i0.ɵɵrepeaterCreate(1,
|
|
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
|
|
74
|
-
i0.ɵɵelementStart(0, "div",
|
|
75
|
-
i0.ɵɵelement(1, "i",
|
|
76
|
-
i0.ɵɵelementStart(2, "p",
|
|
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",
|
|
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
|
|
84
|
-
|
|
85
|
-
i0.ɵɵ
|
|
86
|
-
i0.ɵɵ
|
|
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
|
|
93
|
-
i0.ɵɵelementStart(0, "span",
|
|
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
|
|
162
|
+
const query_r12 = i0.ɵɵnextContext().$implicit;
|
|
98
163
|
i0.ɵɵadvance();
|
|
99
|
-
i0.ɵɵtextInterpolate(
|
|
164
|
+
i0.ɵɵtextInterpolate(query_r12.Description);
|
|
100
165
|
} }
|
|
101
|
-
function
|
|
102
|
-
i0.ɵɵelement(0, "i",
|
|
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
|
|
105
|
-
|
|
106
|
-
i0.ɵɵ
|
|
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
|
-
|
|
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,
|
|
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
|
|
195
|
+
const query_r12 = ctx.$implicit;
|
|
118
196
|
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
119
|
-
i0.ɵɵclassProp("selected", ctx_r2.IsQuerySelected(
|
|
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.ɵɵ
|
|
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(
|
|
208
|
+
i0.ɵɵconditional(query_r12.UsesTemplate ? 7 : -1);
|
|
209
|
+
i0.ɵɵadvance();
|
|
210
|
+
i0.ɵɵconditional(query_r12.Status !== "Approved" ? 8 : -1);
|
|
126
211
|
} }
|
|
127
|
-
function
|
|
128
|
-
i0.ɵɵelementStart(0, "div",
|
|
129
|
-
i0.ɵɵrepeaterCreate(1,
|
|
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
|
|
217
|
+
const node_r10 = i0.ɵɵnextContext(2).node;
|
|
133
218
|
i0.ɵɵadvance();
|
|
134
|
-
i0.ɵɵrepeater(
|
|
219
|
+
i0.ɵɵrepeater(node_r10.queries);
|
|
135
220
|
} }
|
|
136
|
-
function
|
|
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
|
|
140
|
-
i0.ɵɵtemplate(0,
|
|
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
|
|
227
|
+
const child_r13 = ctx.$implicit;
|
|
143
228
|
i0.ɵɵnextContext(4);
|
|
144
|
-
const
|
|
145
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
229
|
+
const categoryNode_r7 = i0.ɵɵreference(35);
|
|
230
|
+
i0.ɵɵproperty("ngTemplateOutlet", categoryNode_r7)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r13));
|
|
146
231
|
} }
|
|
147
|
-
function
|
|
148
|
-
i0.ɵɵrepeaterCreate(0,
|
|
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
|
|
151
|
-
i0.ɵɵrepeater(
|
|
235
|
+
const node_r10 = i0.ɵɵnextContext(2).node;
|
|
236
|
+
i0.ɵɵrepeater(node_r10.children);
|
|
152
237
|
} }
|
|
153
|
-
function
|
|
154
|
-
const
|
|
155
|
-
i0.ɵɵelementStart(0, "div",
|
|
156
|
-
i0.ɵɵlistener("click", function
|
|
157
|
-
i0.ɵɵelement(2, "i",
|
|
158
|
-
i0.ɵɵelementStart(4, "span",
|
|
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",
|
|
246
|
+
i0.ɵɵelementStart(6, "span", 56);
|
|
162
247
|
i0.ɵɵtext(7);
|
|
163
248
|
i0.ɵɵelementEnd()();
|
|
164
|
-
i0.ɵɵconditionalCreate(8,
|
|
165
|
-
i0.ɵɵconditionalCreate(9,
|
|
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
|
|
253
|
+
const node_r10 = i0.ɵɵnextContext().node;
|
|
169
254
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
170
|
-
i0.ɵɵstyleProp("padding-left",
|
|
171
|
-
i0.ɵɵclassProp("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",
|
|
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",
|
|
260
|
+
i0.ɵɵclassProp("fa-folder-open", node_r10.expanded);
|
|
176
261
|
i0.ɵɵadvance(2);
|
|
177
|
-
i0.ɵɵtextInterpolate(
|
|
262
|
+
i0.ɵɵtextInterpolate(node_r10.category.Name);
|
|
178
263
|
i0.ɵɵadvance(2);
|
|
179
|
-
i0.ɵɵtextInterpolate1("(", ctx_r2.getNodeQueryCount(
|
|
264
|
+
i0.ɵɵtextInterpolate1("(", ctx_r2.getNodeQueryCount(node_r10), ")");
|
|
180
265
|
i0.ɵɵadvance();
|
|
181
|
-
i0.ɵɵconditional(
|
|
266
|
+
i0.ɵɵconditional(node_r10.expanded ? 8 : -1);
|
|
182
267
|
i0.ɵɵadvance();
|
|
183
|
-
i0.ɵɵconditional(
|
|
268
|
+
i0.ɵɵconditional(node_r10.expanded ? 9 : -1);
|
|
184
269
|
} }
|
|
185
|
-
function
|
|
186
|
-
i0.ɵɵconditionalCreate(0,
|
|
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
|
|
273
|
+
const node_r10 = ctx.node;
|
|
189
274
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
190
|
-
i0.ɵɵconditional(ctx_r2.hasVisibleContent(
|
|
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
|
|
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.
|
|
278
|
-
this.
|
|
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
|
-
//
|
|
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 =
|
|
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:
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
367
|
-
|
|
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.
|
|
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
|
-
//
|
|
444
|
-
|
|
445
|
-
const
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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:
|
|
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.ɵɵ
|
|
693
|
-
i0.ɵɵ
|
|
694
|
-
i0.ɵɵ
|
|
695
|
-
i0.ɵɵconditionalCreate(25, QueryBrowserResourceComponent_Conditional_25_Template,
|
|
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(
|
|
698
|
-
i0.ɵɵlistener("mousedown", function
|
|
699
|
-
i0.ɵɵelement(
|
|
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(
|
|
702
|
-
i0.ɵɵconditionalCreate(
|
|
703
|
-
i0.ɵɵconditionalCreate(
|
|
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(
|
|
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.ɵɵ
|
|
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 ?
|
|
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 ?
|
|
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 ?
|
|
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 ?
|
|
921
|
+
i0.ɵɵconditional(!ctx.selectedQuery ? 32 : -1);
|
|
728
922
|
i0.ɵɵadvance();
|
|
729
|
-
i0.ɵɵconditional(ctx.selectedQuery ?
|
|
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
|