@memberjunction/ng-query-viewer 5.10.1 → 5.12.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/lib/query-data-grid/query-data-grid.component.d.ts +15 -3
- package/dist/lib/query-data-grid/query-data-grid.component.d.ts.map +1 -1
- package/dist/lib/query-data-grid/query-data-grid.component.js +85 -35
- package/dist/lib/query-data-grid/query-data-grid.component.js.map +1 -1
- package/dist/lib/query-info-panel/query-info-panel.component.d.ts +6 -2
- package/dist/lib/query-info-panel/query-info-panel.component.d.ts.map +1 -1
- package/dist/lib/query-info-panel/query-info-panel.component.js +100 -11
- package/dist/lib/query-info-panel/query-info-panel.component.js.map +1 -1
- package/dist/lib/query-parameter-form/query-parameter-form.component.js +2 -2
- package/dist/lib/query-parameter-form/query-parameter-form.component.js.map +1 -1
- package/dist/lib/query-row-detail/query-row-detail.component.js +2 -2
- package/dist/lib/query-row-detail/query-row-detail.component.js.map +1 -1
- package/dist/lib/query-viewer/query-viewer.component.d.ts +19 -4
- package/dist/lib/query-viewer/query-viewer.component.d.ts.map +1 -1
- package/dist/lib/query-viewer/query-viewer.component.js +42 -10
- package/dist/lib/query-viewer/query-viewer.component.js.map +1 -1
- package/dist/lib/query-viewer.module.d.ts +5 -3
- package/dist/lib/query-viewer.module.d.ts.map +1 -1
- package/dist/lib/query-viewer.module.js +11 -3
- package/dist/lib/query-viewer.module.js.map +1 -1
- package/package.json +11 -9
|
@@ -5,6 +5,8 @@ import { debounceTime, takeUntil } from 'rxjs/operators';
|
|
|
5
5
|
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
6
6
|
import * as i0 from "@angular/core";
|
|
7
7
|
import * as i1 from "@memberjunction/ng-markdown";
|
|
8
|
+
import * as i2 from "@memberjunction/ng-code-editor";
|
|
9
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
8
10
|
function QueryInfoPanelComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
9
11
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
10
12
|
i0.ɵɵelementStart(0, "div", 2);
|
|
@@ -273,13 +275,14 @@ function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_23_Tem
|
|
|
273
275
|
i0.ɵɵconditional(ctx_r1.QueryInfo.Parameters.length ? 1 : 2);
|
|
274
276
|
} }
|
|
275
277
|
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
276
|
-
i0.ɵɵ
|
|
277
|
-
i0.ɵɵ
|
|
278
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
279
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "mj-code-editor", 56);
|
|
280
|
+
i0.ɵɵlistener("CompositionTokenClick", function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_1_Template_mj_code_editor_CompositionTokenClick_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnCompositionTokenClick($event)); });
|
|
278
281
|
i0.ɵɵelementEnd()();
|
|
279
282
|
} if (rf & 2) {
|
|
280
283
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
281
|
-
i0.ɵɵadvance(
|
|
282
|
-
i0.ɵɵ
|
|
284
|
+
i0.ɵɵadvance();
|
|
285
|
+
i0.ɵɵproperty("value", ctx_r1.QueryInfo.SQL)("readonly", true)("language", "sql");
|
|
283
286
|
} }
|
|
284
287
|
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
285
288
|
i0.ɵɵelementStart(0, "div", 35);
|
|
@@ -290,13 +293,76 @@ function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Con
|
|
|
290
293
|
} }
|
|
291
294
|
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
292
295
|
i0.ɵɵelementStart(0, "div", 22);
|
|
293
|
-
i0.ɵɵconditionalCreate(1, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_1_Template,
|
|
296
|
+
i0.ɵɵconditionalCreate(1, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_1_Template, 2, 3, "div", 55)(2, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Conditional_2_Template, 4, 0, "div", 35);
|
|
294
297
|
i0.ɵɵelementEnd();
|
|
295
298
|
} if (rf & 2) {
|
|
296
299
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
297
300
|
i0.ɵɵadvance();
|
|
298
301
|
i0.ɵɵconditional(ctx_r1.QueryInfo.SQL ? 1 : 2);
|
|
299
302
|
} }
|
|
303
|
+
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_For_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
+
i0.ɵɵelementStart(0, "span", 66);
|
|
305
|
+
i0.ɵɵtext(1);
|
|
306
|
+
i0.ɵɵelementEnd();
|
|
307
|
+
} if (rf & 2) {
|
|
308
|
+
const dep_r11 = i0.ɵɵnextContext().$implicit;
|
|
309
|
+
i0.ɵɵadvance();
|
|
310
|
+
i0.ɵɵtextInterpolate1(" via ", dep_r11.ReferencePath, " ");
|
|
311
|
+
} }
|
|
312
|
+
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
313
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
314
|
+
i0.ɵɵelementStart(0, "div", 62);
|
|
315
|
+
i0.ɵɵlistener("click", function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_For_3_Template_div_click_0_listener() { const dep_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.OnDependentQueryClick(dep_r11)); });
|
|
316
|
+
i0.ɵɵelementStart(1, "div", 63);
|
|
317
|
+
i0.ɵɵelement(2, "i", 64);
|
|
318
|
+
i0.ɵɵelementStart(3, "span", 65);
|
|
319
|
+
i0.ɵɵtext(4);
|
|
320
|
+
i0.ɵɵelementEnd()();
|
|
321
|
+
i0.ɵɵconditionalCreate(5, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_For_3_Conditional_5_Template, 2, 1, "span", 66);
|
|
322
|
+
i0.ɵɵelementEnd();
|
|
323
|
+
} if (rf & 2) {
|
|
324
|
+
const dep_r11 = ctx.$implicit;
|
|
325
|
+
i0.ɵɵadvance(4);
|
|
326
|
+
i0.ɵɵtextInterpolate(dep_r11.Query);
|
|
327
|
+
i0.ɵɵadvance();
|
|
328
|
+
i0.ɵɵconditional(dep_r11.ReferencePath ? 5 : -1);
|
|
329
|
+
} }
|
|
330
|
+
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
331
|
+
i0.ɵɵelementStart(0, "div", 22)(1, "div", 58);
|
|
332
|
+
i0.ɵɵrepeaterCreate(2, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_For_3_Template, 6, 2, "div", 59, _forTrack0);
|
|
333
|
+
i0.ɵɵelementEnd();
|
|
334
|
+
i0.ɵɵelementStart(4, "div", 60);
|
|
335
|
+
i0.ɵɵelement(5, "i", 61);
|
|
336
|
+
i0.ɵɵtext(6, " These queries reference this query via composition ");
|
|
337
|
+
i0.ɵɵelementEnd()();
|
|
338
|
+
} if (rf & 2) {
|
|
339
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
340
|
+
i0.ɵɵadvance(2);
|
|
341
|
+
i0.ɵɵrepeater(ctx_r1.QueryInfo.Dependents);
|
|
342
|
+
} }
|
|
343
|
+
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
344
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
345
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div", 19);
|
|
346
|
+
i0.ɵɵlistener("click", function QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleSection("dependents")); });
|
|
347
|
+
i0.ɵɵelement(2, "i", 20);
|
|
348
|
+
i0.ɵɵelementStart(3, "span", 21);
|
|
349
|
+
i0.ɵɵtext(4, "Dependent Queries");
|
|
350
|
+
i0.ɵɵelementEnd();
|
|
351
|
+
i0.ɵɵelementStart(5, "span", 24);
|
|
352
|
+
i0.ɵɵtext(6);
|
|
353
|
+
i0.ɵɵelementEnd()();
|
|
354
|
+
i0.ɵɵconditionalCreate(7, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Conditional_7_Template, 7, 0, "div", 22);
|
|
355
|
+
i0.ɵɵelementEnd();
|
|
356
|
+
} if (rf & 2) {
|
|
357
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
358
|
+
i0.ɵɵclassProp("expanded", ctx_r1.IsSectionExpanded("dependents"));
|
|
359
|
+
i0.ɵɵadvance(2);
|
|
360
|
+
i0.ɵɵclassProp("fa-chevron-down", ctx_r1.IsSectionExpanded("dependents"))("fa-chevron-right", !ctx_r1.IsSectionExpanded("dependents"));
|
|
361
|
+
i0.ɵɵadvance(4);
|
|
362
|
+
i0.ɵɵtextInterpolate1("(", ctx_r1.QueryInfo.Dependents.length, ")");
|
|
363
|
+
i0.ɵɵadvance();
|
|
364
|
+
i0.ɵɵconditional(ctx_r1.IsSectionExpanded("dependents") ? 7 : -1);
|
|
365
|
+
} }
|
|
300
366
|
function QueryInfoPanelComponent_Conditional_1_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
301
367
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
302
368
|
i0.ɵɵelementStart(0, "div", 13)(1, "div", 18)(2, "div", 19);
|
|
@@ -337,7 +403,9 @@ function QueryInfoPanelComponent_Conditional_1_Conditional_11_Template(rf, ctx)
|
|
|
337
403
|
i0.ɵɵtext(28, "SQL Query");
|
|
338
404
|
i0.ɵɵelementEnd()();
|
|
339
405
|
i0.ɵɵconditionalCreate(29, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_29_Template, 3, 1, "div", 22);
|
|
340
|
-
i0.ɵɵelementEnd()
|
|
406
|
+
i0.ɵɵelementEnd();
|
|
407
|
+
i0.ɵɵconditionalCreate(30, QueryInfoPanelComponent_Conditional_1_Conditional_11_Conditional_30_Template, 8, 8, "div", 23);
|
|
408
|
+
i0.ɵɵelementEnd();
|
|
341
409
|
} if (rf & 2) {
|
|
342
410
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
343
411
|
i0.ɵɵadvance();
|
|
@@ -370,6 +438,8 @@ function QueryInfoPanelComponent_Conditional_1_Conditional_11_Template(rf, ctx)
|
|
|
370
438
|
i0.ɵɵclassProp("fa-chevron-down", ctx_r1.IsSectionExpanded("sql"))("fa-chevron-right", !ctx_r1.IsSectionExpanded("sql"));
|
|
371
439
|
i0.ɵɵadvance(3);
|
|
372
440
|
i0.ɵɵconditional(ctx_r1.IsSectionExpanded("sql") ? 29 : -1);
|
|
441
|
+
i0.ɵɵadvance();
|
|
442
|
+
i0.ɵɵconditional(ctx_r1.QueryInfo.Dependents.length > 0 ? 30 : -1);
|
|
373
443
|
} }
|
|
374
444
|
function QueryInfoPanelComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
375
445
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
@@ -387,7 +457,7 @@ function QueryInfoPanelComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
387
457
|
i0.ɵɵlistener("click", function QueryInfoPanelComponent_Conditional_1_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnClose()); });
|
|
388
458
|
i0.ɵɵelement(10, "i", 12);
|
|
389
459
|
i0.ɵɵelementEnd()();
|
|
390
|
-
i0.ɵɵconditionalCreate(11, QueryInfoPanelComponent_Conditional_1_Conditional_11_Template,
|
|
460
|
+
i0.ɵɵconditionalCreate(11, QueryInfoPanelComponent_Conditional_1_Conditional_11_Template, 31, 32, "div", 13);
|
|
391
461
|
i0.ɵɵelementStart(12, "div", 14)(13, "button", 15);
|
|
392
462
|
i0.ɵɵlistener("click", function QueryInfoPanelComponent_Conditional_1_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnOpenRecord()); });
|
|
393
463
|
i0.ɵɵelement(14, "i", 16);
|
|
@@ -430,6 +500,7 @@ export class QueryInfoPanelComponent {
|
|
|
430
500
|
// ========================================
|
|
431
501
|
Close = new EventEmitter();
|
|
432
502
|
OpenRecord = new EventEmitter();
|
|
503
|
+
CompositionTokenClick = new EventEmitter();
|
|
433
504
|
// ========================================
|
|
434
505
|
// Internal State
|
|
435
506
|
// ========================================
|
|
@@ -473,6 +544,22 @@ export class QueryInfoPanelComponent {
|
|
|
473
544
|
OnClose() {
|
|
474
545
|
this.Close.emit();
|
|
475
546
|
}
|
|
547
|
+
OnCompositionTokenClick(event) {
|
|
548
|
+
this.CompositionTokenClick.emit(event);
|
|
549
|
+
}
|
|
550
|
+
OnDependentQueryClick(dep) {
|
|
551
|
+
// Navigate to the dependent (referencing) query
|
|
552
|
+
const depQuery = dep.QueryInfo;
|
|
553
|
+
const categoryPath = depQuery?.CategoryPath?.replace(/^\/|\/$/g, '') || '';
|
|
554
|
+
const fullPath = categoryPath ? `${categoryPath}/${dep.Query}` : dep.Query;
|
|
555
|
+
this.CompositionTokenClick.emit({
|
|
556
|
+
FullToken: `{{query:"${fullPath}"}}`,
|
|
557
|
+
QueryName: dep.Query,
|
|
558
|
+
CategorySegments: categoryPath ? categoryPath.split('/') : [],
|
|
559
|
+
FullPath: fullPath,
|
|
560
|
+
MouseEvent: new MouseEvent('click')
|
|
561
|
+
});
|
|
562
|
+
}
|
|
476
563
|
OnOpenRecord() {
|
|
477
564
|
if (this.QueryInfo) {
|
|
478
565
|
this.OpenRecord.emit({
|
|
@@ -539,14 +626,14 @@ export class QueryInfoPanelComponent {
|
|
|
539
626
|
static ɵfac = function QueryInfoPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || QueryInfoPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
540
627
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryInfoPanelComponent, selectors: [["mj-query-info-panel"]], hostBindings: function QueryInfoPanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
541
628
|
i0.ɵɵlistener("mousemove", function QueryInfoPanelComponent_mousemove_HostBindingHandler($event) { return ctx.OnMouseMove($event); }, i0.ɵɵresolveDocument)("mouseup", function QueryInfoPanelComponent_mouseup_HostBindingHandler() { return ctx.OnMouseUp(); }, i0.ɵɵresolveDocument);
|
|
542
|
-
} }, inputs: { QueryInfo: "QueryInfo", Visible: "Visible", ShowOverlay: "ShowOverlay" }, outputs: { Close: "Close", OpenRecord: "OpenRecord" }, standalone: false, decls: 2, vars: 2, consts: [[1, "info-panel-overlay"], [1, "info-panel", 3, "width"], [1, "info-panel-overlay", 3, "click"], [1, "info-panel"], [1, "resize-handle", 3, "mousedown"], [1, "panel-header"], [1, "header-content"], [1, "fa-solid", "fa-circle-info", "header-icon"], [1, "header-text"], [1, "header-title"], [1, "header-subtitle"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [1, "panel-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "btn", "btn-secondary", 3, "click"], [1, "info-section"], [1, "section-header", 3, "click"], [1, "fa-solid", "section-icon"], [1, "section-title"], [1, "section-content"], [1, "info-section", 3, "expanded"], [1, "section-count"], [1, "info-row"], [1, "info-label"], [1, "info-value"], [1, "status-badge"], [1, "info-value", "description"], [1, "fa-solid", "fa-folder", "category-icon"], [1, "fa-solid", "fa-check", "text-success"], [1, "section-content", "technical-description-content"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [1, "fields-list"], [1, "empty-section"], [1, "field-item"], [1, "field-header"], [1, "field-name"], [1, "field-type"], [1, "field-details"], [1, "field-description"], [1, "field-source"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-table-columns"], [1, "params-list"], [1, "param-item"], [1, "param-header"], [1, "param-name"], [1, "required-badge"], [1, "param-type"], [1, "param-details"], [1, "param-description"], [1, "param-default"], [1, "fa-solid", "fa-sliders"], [1, "sql-container"], [1, "
|
|
629
|
+
} }, inputs: { QueryInfo: "QueryInfo", Visible: "Visible", ShowOverlay: "ShowOverlay" }, outputs: { Close: "Close", OpenRecord: "OpenRecord", CompositionTokenClick: "CompositionTokenClick" }, standalone: false, decls: 2, vars: 2, consts: [[1, "info-panel-overlay"], [1, "info-panel", 3, "width"], [1, "info-panel-overlay", 3, "click"], [1, "info-panel"], [1, "resize-handle", 3, "mousedown"], [1, "panel-header"], [1, "header-content"], [1, "fa-solid", "fa-circle-info", "header-icon"], [1, "header-text"], [1, "header-title"], [1, "header-subtitle"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [1, "panel-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "btn", "btn-secondary", 3, "click"], [1, "info-section"], [1, "section-header", 3, "click"], [1, "fa-solid", "section-icon"], [1, "section-title"], [1, "section-content"], [1, "info-section", 3, "expanded"], [1, "section-count"], [1, "info-row"], [1, "info-label"], [1, "info-value"], [1, "status-badge"], [1, "info-value", "description"], [1, "fa-solid", "fa-folder", "category-icon"], [1, "fa-solid", "fa-check", "text-success"], [1, "section-content", "technical-description-content"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [1, "fields-list"], [1, "empty-section"], [1, "field-item"], [1, "field-header"], [1, "field-name"], [1, "field-type"], [1, "field-details"], [1, "field-description"], [1, "field-source"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-table-columns"], [1, "params-list"], [1, "param-item"], [1, "param-header"], [1, "param-name"], [1, "required-badge"], [1, "param-type"], [1, "param-details"], [1, "param-description"], [1, "param-default"], [1, "fa-solid", "fa-sliders"], [1, "sql-container"], [3, "CompositionTokenClick", "value", "readonly", "language"], [1, "fa-solid", "fa-code"], [1, "dependents-list"], [1, "dependent-item"], [1, "dependents-hint"], [1, "fa-solid", "fa-info-circle"], [1, "dependent-item", 3, "click"], [1, "dependent-header"], [1, "fa-solid", "fa-arrow-left", "dependent-icon"], [1, "dependent-name"], [1, "dependent-ref-path"]], template: function QueryInfoPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
543
630
|
i0.ɵɵconditionalCreate(0, QueryInfoPanelComponent_Conditional_0_Template, 1, 1, "div", 0);
|
|
544
631
|
i0.ɵɵconditionalCreate(1, QueryInfoPanelComponent_Conditional_1_Template, 18, 5, "div", 1);
|
|
545
632
|
} if (rf & 2) {
|
|
546
633
|
i0.ɵɵconditional(ctx.Visible && ctx.ShowOverlay ? 0 : -1);
|
|
547
634
|
i0.ɵɵadvance();
|
|
548
635
|
i0.ɵɵconditional(ctx.Visible ? 1 : -1);
|
|
549
|
-
} }, dependencies: [i1.MarkdownComponent], styles: ["\n\n\n\n\n.info-panel-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n}\n\n\n\n.info-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n background: #fff;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n min-width: 350px;\n max-width: 800px;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n background: transparent;\n transition: background 0.15s ease;\n z-index: 10;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: rgba(92, 107, 192, 0.3);\n}\n\n.resize-handle[_ngcontent-%COMP%]:active {\n background: rgba(92, 107, 192, 0.5);\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n flex-shrink: 0;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n opacity: 0.9;\n}\n\n.header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.header-subtitle[_ngcontent-%COMP%] {\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.info-section[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.info-section.expanded[_ngcontent-%COMP%] {\n border-color: #c5cae9;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: #fafafa;\n cursor: pointer;\n transition: background 0.15s ease;\n user-select: none;\n}\n\n.section-header[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n\n.info-section.expanded[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n background: #e8eaf6;\n border-bottom: 1px solid #c5cae9;\n}\n\n.section-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #666;\n width: 12px;\n text-align: center;\n}\n\n.section-title[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 600;\n font-size: 14px;\n color: #333;\n}\n\n.section-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n font-weight: 400;\n}\n\n.section-content[_ngcontent-%COMP%] {\n padding: 16px;\n background: #fff;\n}\n\n\n\n.technical-description-content[_ngcontent-%COMP%] {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content [_nghost-%COMP%] .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 0;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: #888;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n line-height: 1.4;\n}\n\n.info-value.description[_ngcontent-%COMP%] {\n color: #555;\n font-style: italic;\n}\n\n.category-icon[_ngcontent-%COMP%] {\n color: #f9a825;\n margin-right: 4px;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n background: #f5f5f5;\n color: #666;\n}\n\n.status-badge.approved[_ngcontent-%COMP%] {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: #2e7d32;\n}\n\n\n\n.fields-list[_ngcontent-%COMP%], \n.params-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item[_ngcontent-%COMP%], \n.param-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 3px solid #5c6bc0;\n}\n\n.field-header[_ngcontent-%COMP%], \n.param-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-name[_ngcontent-%COMP%], \n.param-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-type[_ngcontent-%COMP%], \n.param-type[_ngcontent-%COMP%] {\n font-size: 11px;\n font-family: 'Consolas', 'Monaco', monospace;\n color: #666;\n background: #e8eaf6;\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.field-details[_ngcontent-%COMP%], \n.param-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 6px;\n}\n\n.field-description[_ngcontent-%COMP%], \n.param-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666;\n font-style: italic;\n}\n\n.field-source[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #5c6bc0;\n}\n\n.field-source[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n.required-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 500;\n padding: 2px 6px;\n background: #ffebee;\n color: #c62828;\n border-radius: 4px;\n text-transform: uppercase;\n}\n\n.param-default[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n}\n\n\n\n.sql-container[_ngcontent-%COMP%] {\n background: #1e1e1e;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.sql-code[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: #d4d4d4;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-x: auto;\n}\n\n\n\n.empty-section[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: #888;\n font-style: italic;\n}\n\n.empty-section[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n opacity: 0.6;\n}\n\n\n\n.panel-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 12px;\n padding: 16px 20px;\n background: #f5f5f5;\n border-top: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #7986cb 0%, #5c6bc0 100%);\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.4);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: #fff;\n color: #333;\n border: 1px solid #ddd;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n border-color: #ccc;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f5f5f5;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}"], data: { animation: [
|
|
636
|
+
} }, dependencies: [i1.MarkdownComponent, i2.CodeEditorComponent], styles: ["\n\n\n\n\n.info-panel-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n\n\n.info-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 20px var(--mj-bg-overlay);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n min-width: 350px;\n max-width: 800px;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n background: transparent;\n transition: background 0.15s ease;\n z-index: 10;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.resize-handle[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n opacity: 0.9;\n}\n\n.header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.header-subtitle[_ngcontent-%COMP%] {\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.info-section[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.info-section.expanded[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n transition: background 0.15s ease;\n user-select: none;\n}\n\n.section-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.info-section.expanded[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n}\n\n.section-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-secondary);\n width: 12px;\n text-align: center;\n}\n\n.section-title[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.section-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.section-content[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n\n\n.technical-description-content[_ngcontent-%COMP%] {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content [_nghost-%COMP%] .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n\n\n.technical-description-content[_ngcontent-%COMP%] {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content [_nghost-%COMP%] .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n}\n\n.info-value.description[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n.category-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n margin-right: 4px;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.status-badge.approved[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n.fields-list[_ngcontent-%COMP%], \n.params-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item[_ngcontent-%COMP%], \n.param-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.field-header[_ngcontent-%COMP%], \n.param-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-name[_ngcontent-%COMP%], \n.param-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-type[_ngcontent-%COMP%], \n.param-type[_ngcontent-%COMP%] {\n font-size: 11px;\n font-family: 'Consolas', 'Monaco', monospace;\n color: var(--mj-text-secondary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.field-details[_ngcontent-%COMP%], \n.param-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 6px;\n}\n\n.field-description[_ngcontent-%COMP%], \n.param-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n.field-source[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.field-source[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n.required-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 500;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border-radius: 4px;\n text-transform: uppercase;\n}\n\n.param-default[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n.sql-container[_ngcontent-%COMP%] {\n background: #1e1e1e;\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.sql-container[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n display: block;\n max-height: 400px;\n overflow: auto;\n}\n\n\n\n.empty-section[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.empty-section[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n opacity: 0.6;\n}\n\n\n\n.panel-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n.dependents-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.dependent-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.dependent-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border-left-color: var(--mj-status-warning-text);\n}\n\n.dependent-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.dependent-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 11px;\n}\n\n.dependent-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.dependent-ref-path[_ngcontent-%COMP%] {\n display: block;\n margin-top: 4px;\n margin-left: 19px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.dependents-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 0 0;\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.dependents-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}"], data: { animation: [
|
|
550
637
|
trigger('slideIn', [
|
|
551
638
|
transition(':enter', [
|
|
552
639
|
style({ transform: 'translateX(100%)' }),
|
|
@@ -588,7 +675,7 @@ export class QueryInfoPanelComponent {
|
|
|
588
675
|
animate('150ms ease-in', style({ opacity: 0 }))
|
|
589
676
|
])
|
|
590
677
|
])
|
|
591
|
-
], template: "<!-- Query Info Panel - Slide-in Panel -->\n@if (Visible && ShowOverlay) {\n <div class=\"info-panel-overlay\"\n @fadeIn\n (click)=\"OnClose()\">\n </div>\n}\n\n@if (Visible) {\n <div class=\"info-panel\"\n @slideIn\n [style.width.px]=\"PanelWidth\">\n <!-- Resize handle -->\n <div class=\"resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-content\">\n <i class=\"fa-solid fa-circle-info header-icon\"></i>\n <div class=\"header-text\">\n <h3 class=\"header-title\">Query Information</h3>\n @if (QueryInfo) {\n <span class=\"header-subtitle\">{{ QueryInfo.Name }}</span>\n }\n </div>\n </div>\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Content -->\n @if (QueryInfo) {\n <div class=\"panel-content\">\n <!-- Overview Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('overview')\">\n <div class=\"section-header\" (click)=\"ToggleSection('overview')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('overview')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('overview')\"></i>\n <span class=\"section-title\">Overview</span>\n </div>\n @if (IsSectionExpanded('overview')) {\n <div class=\"section-content\">\n <div class=\"info-row\">\n <span class=\"info-label\">Name</span>\n <span class=\"info-value\">{{ QueryInfo.Name }}</span>\n </div>\n @if (QueryInfo.Description) {\n <div class=\"info-row\">\n <span class=\"info-label\">Description</span>\n <span class=\"info-value description\">{{ QueryInfo.Description }}</span>\n </div>\n }\n @if (QueryInfo.Category) {\n <div class=\"info-row\">\n <span class=\"info-label\">Category</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-folder category-icon\"></i>\n {{ QueryInfo.Category }}\n </span>\n </div>\n }\n <div class=\"info-row\">\n <span class=\"info-label\">Status</span>\n <span class=\"info-value\">\n <span class=\"status-badge\" [class.approved]=\"QueryInfo.Status === 'Approved'\">\n {{ QueryInfo.Status }}\n </span>\n </span>\n </div>\n @if (QueryInfo.OriginalSQL) {\n <div class=\"info-row\">\n <span class=\"info-label\">Has SQL</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-check text-success\"></i> Yes\n </span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Technical Description Section -->\n @if (QueryInfo.TechnicalDescription) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('technical')\">\n <div class=\"section-header\" (click)=\"ToggleSection('technical')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('technical')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('technical')\"></i>\n <span class=\"section-title\">Technical Description</span>\n </div>\n @if (IsSectionExpanded('technical')) {\n <div class=\"section-content technical-description-content\">\n <mj-markdown\n [data]=\"QueryInfo.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n }\n <!-- Fields Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('fields')\">\n <div class=\"section-header\" (click)=\"ToggleSection('fields')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('fields')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('fields')\"></i>\n <span class=\"section-title\">Fields</span>\n <span class=\"section-count\">({{ QueryInfo.Fields.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('fields')) {\n <div class=\"section-content\">\n @if (QueryInfo.Fields.length) {\n <div class=\"fields-list\">\n @for (field of QueryInfo.Fields; track TrackByField($index, field)) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{ field.Name }}</span>\n <span class=\"field-type\">{{ GetFieldTypeDisplay(field) }}</span>\n </div>\n @if (field.Description || field.SourceEntity) {\n <div class=\"field-details\">\n @if (field.Description) {\n <span class=\"field-description\">\n {{ field.Description }}\n </span>\n }\n @if (field.SourceEntity) {\n <span class=\"field-source\">\n <i class=\"fa-solid fa-link\"></i>\n {{ field.SourceEntity }}.{{ field.SourceFieldName }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>No fields defined</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Parameters Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('parameters')\">\n <div class=\"section-header\" (click)=\"ToggleSection('parameters')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('parameters')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('parameters')\"></i>\n <span class=\"section-title\">Parameters</span>\n <span class=\"section-count\">({{ QueryInfo.Parameters.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('parameters')) {\n <div class=\"section-content\">\n @if (QueryInfo.Parameters.length) {\n <div class=\"params-list\">\n @for (param of QueryInfo.Parameters; track TrackByParam($index, param)) {\n <div class=\"param-item\">\n <div class=\"param-header\">\n <span class=\"param-name\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-badge\">Required</span>\n }\n </span>\n <span class=\"param-type\">{{ GetParamTypeDisplay(param) }}</span>\n </div>\n @if (param.Description || param.DefaultValue) {\n <div class=\"param-details\">\n @if (param.Description) {\n <span class=\"param-description\">\n {{ param.Description }}\n </span>\n }\n @if (param.DefaultValue) {\n <span class=\"param-default\">\n Default: {{ param.DefaultValue }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>No parameters required</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- SQL Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('sql')\">\n <div class=\"section-header\" (click)=\"ToggleSection('sql')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('sql')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('sql')\"></i>\n <span class=\"section-title\">SQL Query</span>\n </div>\n @if (IsSectionExpanded('sql')) {\n <div class=\"section-content\">\n @if (QueryInfo.SQL) {\n <div class=\"sql-container\">\n <pre class=\"sql-code\">{{ QueryInfo.SQL }}</pre>\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-code\"></i>\n <span>SQL not available</span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <!-- Footer -->\n <div class=\"panel-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnOpenRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnClose()\">\n Close\n </button>\n </div>\n </div>\n}\n", styles: ["/* Query Info Panel Styles */\n\n/* Overlay */\n.info-panel-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n}\n\n/* Panel Container */\n.info-panel {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n background: #fff;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n min-width: 350px;\n max-width: 800px;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n background: transparent;\n transition: background 0.15s ease;\n z-index: 10;\n}\n\n.resize-handle:hover {\n background: rgba(92, 107, 192, 0.3);\n}\n\n.resize-handle:active {\n background: rgba(92, 107, 192, 0.5);\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n flex-shrink: 0;\n}\n\n.header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon {\n font-size: 24px;\n opacity: 0.9;\n}\n\n.header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.header-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.header-subtitle {\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.close-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sections */\n.info-section {\n margin-bottom: 8px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.info-section.expanded {\n border-color: #c5cae9;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: #fafafa;\n cursor: pointer;\n transition: background 0.15s ease;\n user-select: none;\n}\n\n.section-header:hover {\n background: #f0f0f0;\n}\n\n.info-section.expanded .section-header {\n background: #e8eaf6;\n border-bottom: 1px solid #c5cae9;\n}\n\n.section-icon {\n font-size: 10px;\n color: #666;\n width: 12px;\n text-align: center;\n}\n\n.section-title {\n flex: 1;\n font-weight: 600;\n font-size: 14px;\n color: #333;\n}\n\n.section-count {\n font-size: 12px;\n color: #888;\n font-weight: 400;\n}\n\n.section-content {\n padding: 16px;\n background: #fff;\n}\n\n/* Technical Description Markdown */\n.technical-description-content {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content :host ::ng-deep .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* Info Rows */\n.info-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 0;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.info-row:last-child {\n border-bottom: none;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 600;\n color: #888;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.info-value {\n font-size: 14px;\n color: #333;\n line-height: 1.4;\n}\n\n.info-value.description {\n color: #555;\n font-style: italic;\n}\n\n.category-icon {\n color: #f9a825;\n margin-right: 4px;\n}\n\n.status-badge {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n background: #f5f5f5;\n color: #666;\n}\n\n.status-badge.approved {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.text-success {\n color: #2e7d32;\n}\n\n/* Fields List */\n.fields-list,\n.params-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item,\n.param-item {\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 3px solid #5c6bc0;\n}\n\n.field-header,\n.param-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-name,\n.param-name {\n font-weight: 600;\n font-size: 13px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-type,\n.param-type {\n font-size: 11px;\n font-family: 'Consolas', 'Monaco', monospace;\n color: #666;\n background: #e8eaf6;\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.field-details,\n.param-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 6px;\n}\n\n.field-description,\n.param-description {\n font-size: 12px;\n color: #666;\n font-style: italic;\n}\n\n.field-source {\n font-size: 11px;\n color: #5c6bc0;\n}\n\n.field-source i {\n margin-right: 4px;\n}\n\n.required-badge {\n font-size: 10px;\n font-weight: 500;\n padding: 2px 6px;\n background: #ffebee;\n color: #c62828;\n border-radius: 4px;\n text-transform: uppercase;\n}\n\n.param-default {\n font-size: 11px;\n color: #888;\n}\n\n/* SQL Section */\n.sql-container {\n background: #1e1e1e;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.sql-code {\n margin: 0;\n padding: 16px;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: #d4d4d4;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-x: auto;\n}\n\n/* Empty State */\n.empty-section {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: #888;\n font-style: italic;\n}\n\n.empty-section i {\n font-size: 16px;\n opacity: 0.6;\n}\n\n/* Footer */\n.panel-footer {\n display: flex;\n justify-content: flex-start;\n gap: 12px;\n padding: 16px 20px;\n background: #f5f5f5;\n border-top: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary {\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n color: #fff;\n}\n\n.btn-primary:hover {\n background: linear-gradient(135deg, #7986cb 0%, #5c6bc0 100%);\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.4);\n}\n\n.btn-secondary {\n background: #fff;\n color: #333;\n border: 1px solid #ddd;\n}\n\n.btn-secondary:hover {\n background: #f5f5f5;\n border-color: #ccc;\n}\n\n/* Scrollbar */\n.panel-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background: #f5f5f5;\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n"] }]
|
|
678
|
+
], template: "<!-- Query Info Panel - Slide-in Panel -->\n@if (Visible && ShowOverlay) {\n <div class=\"info-panel-overlay\"\n @fadeIn\n (click)=\"OnClose()\">\n </div>\n}\n\n@if (Visible) {\n <div class=\"info-panel\"\n @slideIn\n [style.width.px]=\"PanelWidth\">\n <!-- Resize handle -->\n <div class=\"resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-content\">\n <i class=\"fa-solid fa-circle-info header-icon\"></i>\n <div class=\"header-text\">\n <h3 class=\"header-title\">Query Information</h3>\n @if (QueryInfo) {\n <span class=\"header-subtitle\">{{ QueryInfo.Name }}</span>\n }\n </div>\n </div>\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Content -->\n @if (QueryInfo) {\n <div class=\"panel-content\">\n <!-- Overview Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('overview')\">\n <div class=\"section-header\" (click)=\"ToggleSection('overview')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('overview')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('overview')\"></i>\n <span class=\"section-title\">Overview</span>\n </div>\n @if (IsSectionExpanded('overview')) {\n <div class=\"section-content\">\n <div class=\"info-row\">\n <span class=\"info-label\">Name</span>\n <span class=\"info-value\">{{ QueryInfo.Name }}</span>\n </div>\n @if (QueryInfo.Description) {\n <div class=\"info-row\">\n <span class=\"info-label\">Description</span>\n <span class=\"info-value description\">{{ QueryInfo.Description }}</span>\n </div>\n }\n @if (QueryInfo.Category) {\n <div class=\"info-row\">\n <span class=\"info-label\">Category</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-folder category-icon\"></i>\n {{ QueryInfo.Category }}\n </span>\n </div>\n }\n <div class=\"info-row\">\n <span class=\"info-label\">Status</span>\n <span class=\"info-value\">\n <span class=\"status-badge\" [class.approved]=\"QueryInfo.Status === 'Approved'\">\n {{ QueryInfo.Status }}\n </span>\n </span>\n </div>\n @if (QueryInfo.OriginalSQL) {\n <div class=\"info-row\">\n <span class=\"info-label\">Has SQL</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-check text-success\"></i> Yes\n </span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Technical Description Section -->\n @if (QueryInfo.TechnicalDescription) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('technical')\">\n <div class=\"section-header\" (click)=\"ToggleSection('technical')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('technical')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('technical')\"></i>\n <span class=\"section-title\">Technical Description</span>\n </div>\n @if (IsSectionExpanded('technical')) {\n <div class=\"section-content technical-description-content\">\n <mj-markdown\n [data]=\"QueryInfo.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n }\n <!-- Fields Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('fields')\">\n <div class=\"section-header\" (click)=\"ToggleSection('fields')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('fields')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('fields')\"></i>\n <span class=\"section-title\">Fields</span>\n <span class=\"section-count\">({{ QueryInfo.Fields.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('fields')) {\n <div class=\"section-content\">\n @if (QueryInfo.Fields.length) {\n <div class=\"fields-list\">\n @for (field of QueryInfo.Fields; track TrackByField($index, field)) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{ field.Name }}</span>\n <span class=\"field-type\">{{ GetFieldTypeDisplay(field) }}</span>\n </div>\n @if (field.Description || field.SourceEntity) {\n <div class=\"field-details\">\n @if (field.Description) {\n <span class=\"field-description\">\n {{ field.Description }}\n </span>\n }\n @if (field.SourceEntity) {\n <span class=\"field-source\">\n <i class=\"fa-solid fa-link\"></i>\n {{ field.SourceEntity }}.{{ field.SourceFieldName }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>No fields defined</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Parameters Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('parameters')\">\n <div class=\"section-header\" (click)=\"ToggleSection('parameters')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('parameters')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('parameters')\"></i>\n <span class=\"section-title\">Parameters</span>\n <span class=\"section-count\">({{ QueryInfo.Parameters.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('parameters')) {\n <div class=\"section-content\">\n @if (QueryInfo.Parameters.length) {\n <div class=\"params-list\">\n @for (param of QueryInfo.Parameters; track TrackByParam($index, param)) {\n <div class=\"param-item\">\n <div class=\"param-header\">\n <span class=\"param-name\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-badge\">Required</span>\n }\n </span>\n <span class=\"param-type\">{{ GetParamTypeDisplay(param) }}</span>\n </div>\n @if (param.Description || param.DefaultValue) {\n <div class=\"param-details\">\n @if (param.Description) {\n <span class=\"param-description\">\n {{ param.Description }}\n </span>\n }\n @if (param.DefaultValue) {\n <span class=\"param-default\">\n Default: {{ param.DefaultValue }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>No parameters required</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- SQL Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('sql')\">\n <div class=\"section-header\" (click)=\"ToggleSection('sql')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('sql')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('sql')\"></i>\n <span class=\"section-title\">SQL Query</span>\n </div>\n @if (IsSectionExpanded('sql')) {\n <div class=\"section-content\">\n @if (QueryInfo.SQL) {\n <div class=\"sql-container\">\n <mj-code-editor\n [value]=\"QueryInfo.SQL\"\n [readonly]=\"true\"\n [language]=\"'sql'\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-code\"></i>\n <span>SQL not available</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Dependent Queries Section -->\n @if (QueryInfo.Dependents.length > 0) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('dependents')\">\n <div class=\"section-header\" (click)=\"ToggleSection('dependents')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('dependents')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('dependents')\"></i>\n <span class=\"section-title\">Dependent Queries</span>\n <span class=\"section-count\">({{ QueryInfo.Dependents.length }})</span>\n </div>\n @if (IsSectionExpanded('dependents')) {\n <div class=\"section-content\">\n <div class=\"dependents-list\">\n @for (dep of QueryInfo.Dependents; track dep.ID) {\n <div class=\"dependent-item\" (click)=\"OnDependentQueryClick(dep)\">\n <div class=\"dependent-header\">\n <i class=\"fa-solid fa-arrow-left dependent-icon\"></i>\n <span class=\"dependent-name\">{{ dep.Query }}</span>\n </div>\n @if (dep.ReferencePath) {\n <span class=\"dependent-ref-path\">\n via {{ dep.ReferencePath }}\n </span>\n }\n </div>\n }\n </div>\n <div class=\"dependents-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n These queries reference this query via composition\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Footer -->\n <div class=\"panel-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnOpenRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnClose()\">\n Close\n </button>\n </div>\n </div>\n}\n", styles: ["/* Query Info Panel Styles */\n\n/* Overlay */\n.info-panel-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n/* Panel Container */\n.info-panel {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 20px var(--mj-bg-overlay);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n min-width: 350px;\n max-width: 800px;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n background: transparent;\n transition: background 0.15s ease;\n z-index: 10;\n}\n\n.resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon {\n font-size: 24px;\n opacity: 0.9;\n}\n\n.header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.header-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.header-subtitle {\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.close-btn:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sections */\n.info-section {\n margin-bottom: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.info-section.expanded {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n transition: background 0.15s ease;\n user-select: none;\n}\n\n.section-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.info-section.expanded .section-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n}\n\n.section-icon {\n font-size: 10px;\n color: var(--mj-text-secondary);\n width: 12px;\n text-align: center;\n}\n\n.section-title {\n flex: 1;\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.section-count {\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.section-content {\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n/* Technical Description Markdown */\n.technical-description-content {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content :host ::ng-deep .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* Technical Description Markdown */\n.technical-description-content {\n max-height: 400px;\n overflow-y: auto;\n}\n\n.technical-description-content :host ::ng-deep .mj-markdown-container {\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* Info Rows */\n.info-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.info-row:last-child {\n border-bottom: none;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.info-value {\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n}\n\n.info-value.description {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n.category-icon {\n color: var(--mj-status-warning);\n margin-right: 4px;\n}\n\n.status-badge {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.status-badge.approved {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.text-success {\n color: var(--mj-status-success);\n}\n\n/* Fields List */\n.fields-list,\n.params-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.field-item,\n.param-item {\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.field-header,\n.param-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-name,\n.param-name {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-type,\n.param-type {\n font-size: 11px;\n font-family: 'Consolas', 'Monaco', monospace;\n color: var(--mj-text-secondary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.field-details,\n.param-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 6px;\n}\n\n.field-description,\n.param-description {\n font-size: 12px;\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n.field-source {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.field-source i {\n margin-right: 4px;\n}\n\n.required-badge {\n font-size: 10px;\n font-weight: 500;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border-radius: 4px;\n text-transform: uppercase;\n}\n\n.param-default {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* SQL Section */\n.sql-container {\n background: #1e1e1e;\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.sql-container mj-code-editor {\n display: block;\n max-height: 400px;\n overflow: auto;\n}\n\n/* Empty State */\n.empty-section {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.empty-section i {\n font-size: 16px;\n opacity: 0.6;\n}\n\n/* Footer */\n.panel-footer {\n display: flex;\n justify-content: flex-start;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n/* Scrollbar */\n.panel-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Dependent Queries */\n.dependents-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.dependent-item {\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.dependent-item:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border-left-color: var(--mj-status-warning-text);\n}\n\n.dependent-header {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.dependent-icon {\n color: var(--mj-status-warning);\n font-size: 11px;\n}\n\n.dependent-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.dependent-ref-path {\n display: block;\n margin-top: 4px;\n margin-left: 19px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.dependents-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 0 0;\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.dependents-hint i {\n font-size: 10px;\n}\n"] }]
|
|
592
679
|
}], () => [{ type: i0.ChangeDetectorRef }], { QueryInfo: [{
|
|
593
680
|
type: Input
|
|
594
681
|
}], Visible: [{
|
|
@@ -599,6 +686,8 @@ export class QueryInfoPanelComponent {
|
|
|
599
686
|
type: Output
|
|
600
687
|
}], OpenRecord: [{
|
|
601
688
|
type: Output
|
|
689
|
+
}], CompositionTokenClick: [{
|
|
690
|
+
type: Output
|
|
602
691
|
}], OnMouseMove: [{
|
|
603
692
|
type: HostListener,
|
|
604
693
|
args: ['document:mousemove', ['$event']]
|
|
@@ -606,5 +695,5 @@ export class QueryInfoPanelComponent {
|
|
|
606
695
|
type: HostListener,
|
|
607
696
|
args: ['document:mouseup']
|
|
608
697
|
}] }); })();
|
|
609
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(QueryInfoPanelComponent, { className: "QueryInfoPanelComponent", filePath: "src/lib/query-info-panel/query-info-panel.component.ts", lineNumber:
|
|
698
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(QueryInfoPanelComponent, { className: "QueryInfoPanelComponent", filePath: "src/lib/query-info-panel/query-info-panel.component.ts", lineNumber: 66 }); })();
|
|
610
699
|
//# sourceMappingURL=query-info-panel.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-info-panel.component.js","sourceRoot":"","sources":["../../../src/lib/query-info-panel/query-info-panel.component.ts","../../../src/lib/query-info-panel/query-info-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n OnInit,\n OnDestroy,\n HostListener\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { QueryInfo, QueryFieldInfo, QueryParameterInfo } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\n\n/**\n * User Settings key for info panel width\n */\nconst INFO_PANEL_WIDTH_KEY = 'QueryViewer_InfoPanelWidth';\n\n/**\n * Event emitted when opening the full query record\n */\nexport interface OpenQueryRecordEvent {\n queryId: string;\n queryName: string;\n}\n\n/**\n * A slide-in panel that displays detailed query information.\n * Features:\n * - Expandable sections for fields, parameters, and SQL\n * - Resizable width with persistence\n * - Open button to navigate to full record\n */\n@Component({\n standalone: false,\n selector: 'mj-query-info-panel',\n templateUrl: './query-info-panel.component.html',\n styleUrls: ['./query-info-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('slideIn', [\n transition(':enter', [\n style({ transform: 'translateX(100%)' }),\n animate('250ms ease-out', style({ transform: 'translateX(0)' }))\n ]),\n transition(':leave', [\n animate('200ms ease-in', style({ transform: 'translateX(100%)' }))\n ])\n ]),\n trigger('fadeIn', [\n transition(':enter', [\n style({ opacity: 0 }),\n animate('200ms ease-out', style({ opacity: 1 }))\n ]),\n transition(':leave', [\n animate('150ms ease-in', style({ opacity: 0 }))\n ])\n ])\n ]\n})\nexport class QueryInfoPanelComponent implements OnInit, OnDestroy {\n // ========================================\n // Inputs\n // ========================================\n\n @Input() QueryInfo: QueryInfo | null = null;\n @Input() Visible: boolean = false;\n @Input() ShowOverlay: boolean = true;\n\n // ========================================\n // Outputs\n // ========================================\n\n @Output() Close = new EventEmitter<void>();\n @Output() OpenRecord = new EventEmitter<OpenQueryRecordEvent>();\n\n // ========================================\n // Internal State\n // ========================================\n\n public PanelWidth: number = 450;\n public ExpandedSections: Set<string> = new Set(['overview', 'fields']);\n\n private isResizing: boolean = false;\n private destroy$ = new Subject<void>();\n private widthPersistSubject = new Subject<number>();\n\n constructor(private cdr: ChangeDetectorRef) {\n // Debounce width persistence\n this.widthPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(width => {\n this.persistPanelWidth(width);\n });\n }\n\n ngOnInit(): void {\n this.loadPanelWidth();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Section Toggle\n // ========================================\n\n public ToggleSection(section: string): void {\n if (this.ExpandedSections.has(section)) {\n this.ExpandedSections.delete(section);\n } else {\n this.ExpandedSections.add(section);\n }\n this.cdr.markForCheck();\n }\n\n public IsSectionExpanded(section: string): boolean {\n return this.ExpandedSections.has(section);\n }\n\n // ========================================\n // Panel Actions\n // ========================================\n\n public OnClose(): void {\n this.Close.emit();\n }\n\n public OnOpenRecord(): void {\n if (this.QueryInfo) {\n this.OpenRecord.emit({\n queryId: this.QueryInfo.ID,\n queryName: this.QueryInfo.Name\n });\n }\n }\n\n // ========================================\n // Resize Handling\n // ========================================\n\n public OnResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.isResizing = true;\n }\n\n @HostListener('document:mousemove', ['$event'])\n OnMouseMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const newWidth = window.innerWidth - event.clientX;\n this.PanelWidth = Math.min(Math.max(newWidth, 350), 800);\n this.widthPersistSubject.next(this.PanelWidth);\n this.cdr.markForCheck();\n }\n\n @HostListener('document:mouseup')\n OnMouseUp(): void {\n this.isResizing = false;\n }\n\n // ========================================\n // Width Persistence\n // ========================================\n\n private loadPanelWidth(): void {\n try {\n const saved = UserInfoEngine.Instance.GetSetting(INFO_PANEL_WIDTH_KEY);\n if (saved) {\n this.PanelWidth = parseInt(saved, 10) || 450;\n }\n } catch (error) {\n console.warn('[query-info-panel] Failed to load panel width:', error);\n }\n }\n\n private async persistPanelWidth(width: number): Promise<void> {\n try {\n await UserInfoEngine.Instance.SetSetting(INFO_PANEL_WIDTH_KEY, String(width));\n } catch (error) {\n console.warn('[query-info-panel] Failed to persist panel width:', error);\n }\n }\n\n // ========================================\n // Helpers\n // ========================================\n\n public GetFieldTypeDisplay(field: QueryFieldInfo): string {\n return field.SQLFullType || field.SQLBaseType || 'unknown';\n }\n\n public GetParamTypeDisplay(param: QueryParameterInfo): string {\n return param.Type || 'string';\n }\n\n public TrackByField(index: number, field: QueryFieldInfo): string {\n return field.Name;\n }\n\n public TrackByParam(index: number, param: QueryParameterInfo): string {\n return param.Name;\n }\n}\n","<!-- Query Info Panel - Slide-in Panel -->\n@if (Visible && ShowOverlay) {\n <div class=\"info-panel-overlay\"\n @fadeIn\n (click)=\"OnClose()\">\n </div>\n}\n\n@if (Visible) {\n <div class=\"info-panel\"\n @slideIn\n [style.width.px]=\"PanelWidth\">\n <!-- Resize handle -->\n <div class=\"resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-content\">\n <i class=\"fa-solid fa-circle-info header-icon\"></i>\n <div class=\"header-text\">\n <h3 class=\"header-title\">Query Information</h3>\n @if (QueryInfo) {\n <span class=\"header-subtitle\">{{ QueryInfo.Name }}</span>\n }\n </div>\n </div>\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Content -->\n @if (QueryInfo) {\n <div class=\"panel-content\">\n <!-- Overview Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('overview')\">\n <div class=\"section-header\" (click)=\"ToggleSection('overview')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('overview')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('overview')\"></i>\n <span class=\"section-title\">Overview</span>\n </div>\n @if (IsSectionExpanded('overview')) {\n <div class=\"section-content\">\n <div class=\"info-row\">\n <span class=\"info-label\">Name</span>\n <span class=\"info-value\">{{ QueryInfo.Name }}</span>\n </div>\n @if (QueryInfo.Description) {\n <div class=\"info-row\">\n <span class=\"info-label\">Description</span>\n <span class=\"info-value description\">{{ QueryInfo.Description }}</span>\n </div>\n }\n @if (QueryInfo.Category) {\n <div class=\"info-row\">\n <span class=\"info-label\">Category</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-folder category-icon\"></i>\n {{ QueryInfo.Category }}\n </span>\n </div>\n }\n <div class=\"info-row\">\n <span class=\"info-label\">Status</span>\n <span class=\"info-value\">\n <span class=\"status-badge\" [class.approved]=\"QueryInfo.Status === 'Approved'\">\n {{ QueryInfo.Status }}\n </span>\n </span>\n </div>\n @if (QueryInfo.OriginalSQL) {\n <div class=\"info-row\">\n <span class=\"info-label\">Has SQL</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-check text-success\"></i> Yes\n </span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Technical Description Section -->\n @if (QueryInfo.TechnicalDescription) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('technical')\">\n <div class=\"section-header\" (click)=\"ToggleSection('technical')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('technical')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('technical')\"></i>\n <span class=\"section-title\">Technical Description</span>\n </div>\n @if (IsSectionExpanded('technical')) {\n <div class=\"section-content technical-description-content\">\n <mj-markdown\n [data]=\"QueryInfo.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n }\n <!-- Fields Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('fields')\">\n <div class=\"section-header\" (click)=\"ToggleSection('fields')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('fields')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('fields')\"></i>\n <span class=\"section-title\">Fields</span>\n <span class=\"section-count\">({{ QueryInfo.Fields.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('fields')) {\n <div class=\"section-content\">\n @if (QueryInfo.Fields.length) {\n <div class=\"fields-list\">\n @for (field of QueryInfo.Fields; track TrackByField($index, field)) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{ field.Name }}</span>\n <span class=\"field-type\">{{ GetFieldTypeDisplay(field) }}</span>\n </div>\n @if (field.Description || field.SourceEntity) {\n <div class=\"field-details\">\n @if (field.Description) {\n <span class=\"field-description\">\n {{ field.Description }}\n </span>\n }\n @if (field.SourceEntity) {\n <span class=\"field-source\">\n <i class=\"fa-solid fa-link\"></i>\n {{ field.SourceEntity }}.{{ field.SourceFieldName }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>No fields defined</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Parameters Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('parameters')\">\n <div class=\"section-header\" (click)=\"ToggleSection('parameters')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('parameters')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('parameters')\"></i>\n <span class=\"section-title\">Parameters</span>\n <span class=\"section-count\">({{ QueryInfo.Parameters.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('parameters')) {\n <div class=\"section-content\">\n @if (QueryInfo.Parameters.length) {\n <div class=\"params-list\">\n @for (param of QueryInfo.Parameters; track TrackByParam($index, param)) {\n <div class=\"param-item\">\n <div class=\"param-header\">\n <span class=\"param-name\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-badge\">Required</span>\n }\n </span>\n <span class=\"param-type\">{{ GetParamTypeDisplay(param) }}</span>\n </div>\n @if (param.Description || param.DefaultValue) {\n <div class=\"param-details\">\n @if (param.Description) {\n <span class=\"param-description\">\n {{ param.Description }}\n </span>\n }\n @if (param.DefaultValue) {\n <span class=\"param-default\">\n Default: {{ param.DefaultValue }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>No parameters required</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- SQL Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('sql')\">\n <div class=\"section-header\" (click)=\"ToggleSection('sql')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('sql')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('sql')\"></i>\n <span class=\"section-title\">SQL Query</span>\n </div>\n @if (IsSectionExpanded('sql')) {\n <div class=\"section-content\">\n @if (QueryInfo.SQL) {\n <div class=\"sql-container\">\n <pre class=\"sql-code\">{{ QueryInfo.SQL }}</pre>\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-code\"></i>\n <span>SQL not available</span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <!-- Footer -->\n <div class=\"panel-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnOpenRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnClose()\">\n Close\n </button>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"query-info-panel.component.js","sourceRoot":"","sources":["../../../src/lib/query-info-panel/query-info-panel.component.ts","../../../src/lib/query-info-panel/query-info-panel.component.html"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EAEZ,uBAAuB,EAGvB,YAAY,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;;;;;;;ICd7D,8BAEsB;IAApB,wLAAS,gBAAS,KAAC;IACrB,iBAAM;;IAFJ,mCAAO;;;IAkBC,gCAA8B;IAAA,YAAoB;IAAA,iBAAO;;;IAA3B,cAAoB;IAApB,2CAAoB;;;IA2B5C,AADF,+BAAsB,eACK;IAAA,2BAAW;IAAA,iBAAO;IAC3C,gCAAqC;IAAA,YAA2B;IAClE,AADkE,iBAAO,EACnE;;;IADiC,eAA2B;IAA3B,kDAA2B;;;IAKhE,AADF,+BAAsB,eACK;IAAA,wBAAQ;IAAA,iBAAO;IACxC,gCAAyB;IACvB,wBAAgD;IAChD,YACF;IACF,AADE,iBAAO,EACH;;;IAFF,eACF;IADE,0DACF;;;IAaA,AADF,+BAAsB,eACK;IAAA,uBAAO;IAAA,iBAAO;IACvC,gCAAyB;IACvB,wBAA8C;IAAC,qBACjD;IACF,AADE,iBAAO,EACH;;;IAhCN,AADF,AADF,+BAA6B,cACL,eACK;IAAA,oBAAI;IAAA,iBAAO;IACpC,gCAAyB;IAAA,YAAoB;IAC/C,AAD+C,iBAAO,EAChD;IACN,qIAA6B;IAM7B,qIAA0B;IAUxB,AADF,+BAAsB,eACK;IAAA,uBAAM;IAAA,iBAAO;IAEpC,AADF,iCAAyB,gBACuD;IAC5E,aACF;IAEJ,AADE,AADE,iBAAO,EACF,EACH;IACN,uIAA6B;IAQ/B,iBAAM;;;IAjCuB,eAAoB;IAApB,2CAAoB;IAE/C,cAKC;IALD,uDAKC;IACD,cAQC;IARD,oDAQC;IAI8B,eAAkD;IAAlD,kEAAkD;IAC3E,cACF;IADE,wDACF;IAGJ,cAOC;IAPD,wDAOC;;;IAcD,+BAA2D;IACzD,kCAMc;IAChB,iBAAM;;;IANF,cAA6C;IAI7C,AADA,AADA,AADA,AADA,kEAA6C,uBACvB,yBACE,oCACW,2BACT;;;;IAbhC,AADF,+BAA4E,cACT;IAArC,sNAAS,qBAAc,WAAW,CAAC,KAAC;IAC9D,wBAEiE;IACjE,gCAA4B;IAAA,qCAAqB;IACnD,AADmD,iBAAO,EACpD;IACN,qIAAsC;IAWxC,iBAAM;;;IAlBoB,iEAAiD;IAGrE,eAAwD;IACxD,AADA,wEAAwD,4DACE;IAG9D,eAUC;IAVD,gEAUC;;;IAyBe,gCAAgC;IAC9B,YACF;IAAA,iBAAO;;;IADL,cACF;IADE,qDACF;;;IAGA,gCAA2B;IACzB,wBAAgC;IAChC,YACF;IAAA,iBAAO;;;IADL,eACF;IADE,qFACF;;;IAVJ,+BAA2B;IACzB,yKAAyB;IAKzB,yKAA0B;IAM5B,iBAAM;;;IAXJ,cAIC;IAJD,+CAIC;IACD,cAKC;IALD,gDAKC;;;IAfH,AADF,AADF,+BAAwB,cACI,eACC;IAAA,YAAgB;IAAA,iBAAO;IAChD,gCAAyB;IAAA,YAAgC;IAC3D,AAD2D,iBAAO,EAC5D;IACN,0JAA+C;IAejD,iBAAM;;;;IAlBuB,eAAgB;IAAhB,mCAAgB;IAChB,eAAgC;IAAhC,0DAAgC;IAE3D,cAcC;IAdD,wEAcC;;;IArBP,+BAAyB;IACvB,sLAsBC;IACH,iBAAM;;;IAvBJ,cAsBC;IAtBD,sCAsBC;;;IAGH,+BAA2B;IACzB,wBAAyC;IACzC,4BAAM;IAAA,iCAAiB;IACzB,AADyB,iBAAO,EAC1B;;;IA/BV,+BAA6B;IA2BzB,AA1BF,sIAA+B,gHA0BtB;IAMX,iBAAM;;;IAhCJ,cA+BC;IA/BD,wDA+BC;;;IAuBa,gCAA6B;IAAA,wBAAQ;IAAA,iBAAO;;;IAQ5C,gCAAgC;IAC9B,YACF;IAAA,iBAAO;;;IADL,cACF;IADE,qDACF;;;IAGA,gCAA4B;IAC1B,YACF;IAAA,iBAAO;;;IADL,cACF;IADE,+DACF;;;IATJ,+BAA2B;IACzB,yKAAyB;IAKzB,yKAA0B;IAK5B,iBAAM;;;IAVJ,cAIC;IAJD,+CAIC;IACD,cAIC;IAJD,gDAIC;;;IAnBH,AADF,AADF,+BAAwB,cACI,eACC;IACvB,YACA;IAAA,2JAAwB;IAG1B,iBAAO;IACP,gCAAyB;IAAA,YAAgC;IAC3D,AAD2D,iBAAO,EAC5D;IACN,0JAA+C;IAcjD,iBAAM;;;;IArBA,eACA;IADA,8CACA;IAAA,cAEC;IAFD,8CAEC;IAEsB,eAAgC;IAAhC,0DAAgC;IAE3D,cAaC;IAbD,wEAaC;;;IAzBP,+BAAyB;IACvB,sLA0BC;IACH,iBAAM;;;IA3BJ,cA0BC;IA1BD,0CA0BC;;;IAGH,+BAA2B;IACzB,wBAAmC;IACnC,4BAAM;IAAA,sCAAsB;IAC9B,AAD8B,iBAAO,EAC/B;;;IAnCV,+BAA6B;IA+BzB,AA9BF,sIAAmC,gHA8B1B;IAMX,iBAAM;;;IApCJ,cAmCC;IAnCD,4DAmCC;;;;IAgBG,AADF,+BAA2B,yBAKmC;IAA1D,sRAAyB,sCAA+B,KAAC;IAE7D,AADE,iBAAiB,EACb;;;IALF,cAAuB;IAEvB,AADA,AADA,4CAAuB,kBACN,mBACC;;;IAKtB,+BAA2B;IACzB,wBAAgC;IAChC,4BAAM;IAAA,iCAAiB;IACzB,AADyB,iBAAO,EAC1B;;;IAdV,+BAA6B;IAUzB,AATF,sIAAqB,gHASZ;IAMX,iBAAM;;;IAfJ,cAcC;IAdD,8CAcC;;;IAwBS,gCAAiC;IAC/B,YACF;IAAA,iBAAO;;;IADL,cACF;IADE,0DACF;;;;IARJ,+BAAiE;IAArC,sQAAS,qCAA0B,KAAC;IAC9D,+BAA8B;IAC5B,wBAAqD;IACrD,gCAA6B;IAAA,YAAe;IAC9C,AAD8C,iBAAO,EAC/C;IACN,2JAAyB;IAK3B,iBAAM;;;IAP2B,eAAe;IAAf,mCAAe;IAE9C,cAIC;IAJD,gDAIC;;;IAXP,AADF,+BAA6B,cACE;IAC3B,qJAYC;IACH,iBAAM;IACN,+BAA6B;IAC3B,wBAAuC;IACvC,oEACF;IACF,AADE,iBAAM,EACF;;;IAlBF,eAYC;IAZD,0CAYC;;;;IAtBP,AADF,+BAA6E,cACT;IAAtC,uNAAS,qBAAc,YAAY,CAAC,KAAC;IAC/D,wBAEkE;IAClE,gCAA4B;IAAA,iCAAiB;IAAA,iBAAO;IACpD,gCAA4B;IAAA,YAAmC;IACjE,AADiE,iBAAO,EAClE;IACN,sIAAuC;IAuBzC,iBAAM;;;IA/BoB,kEAAkD;IAGtE,eAAyD;IACzD,AADA,yEAAyD,6DACE;IAEjC,eAAmC;IAAnC,mEAAmC;IAEjE,cAsBC;IAtBD,iEAsBC;;;;IAhOH,AADF,AAFF,+BAA2B,cAEkD,cACT;IAApC,wMAAS,qBAAc,UAAU,CAAC,KAAC;IAC7D,wBAE8D;IAC9D,gCAA4B;IAAA,wBAAQ;IACtC,AADsC,iBAAO,EACvC;IACN,wHAAqC;IAuCvC,iBAAM;IAEN,uHAAsC;IAuBpC,AADF,+BAAyE,cACT;IAAlC,wMAAS,qBAAc,QAAQ,CAAC,KAAC;IAC3D,yBAE4D;IAC5D,iCAA4B;IAAA,uBAAM;IAAA,iBAAO;IACzC,iCAA4B;IAAA,aAAoC;IAClE,AADkE,iBAAO,EACnE;IACN,yHAAmC;IAoCrC,iBAAM;IAGJ,AADF,gCAA6E,eACT;IAAtC,yMAAS,qBAAc,YAAY,CAAC,KAAC;IAC/D,yBAEgE;IAChE,iCAA4B;IAAA,2BAAU;IAAA,iBAAO;IAC7C,iCAA4B;IAAA,aAAwC;IACtE,AADsE,iBAAO,EACvE;IACN,yHAAuC;IAwCzC,iBAAM;IAGJ,AADF,gCAAsE,eACT;IAA/B,yMAAS,qBAAc,KAAK,CAAC,KAAC;IACxD,yBAEyD;IACzD,iCAA4B;IAAA,0BAAS;IACvC,AADuC,iBAAO,EACxC;IACN,yHAAgC;IAmBlC,iBAAM;IAEN,yHAAuC;IAkCzC,iBAAM;;;IApOsB,cAAgD;IAAhD,gEAAgD;IAGpE,eAAuD;IACzD,AADE,uEAAuD,2DACA;IAG3D,eAsCC;IAtCD,+DAsCC;IAGH,cAoBC;IApBD,gEAoBC;IAEyB,cAA8C;IAA9C,8DAA8C;IAGlE,eAAqD;IACvD,AADE,qEAAqD,yDACA;IAE3B,eAAoC;IAApC,oEAAoC;IAElE,cAmCC;IAnCD,8DAmCC;IAGuB,cAAkD;IAAlD,kEAAkD;IAGtE,eAAyD;IAC3D,AADE,yEAAyD,6DACA;IAE/B,eAAwC;IAAxC,wEAAwC;IAEtE,cAuCC;IAvCD,kEAuCC;IAGuB,cAA2C;IAA3C,2DAA2C;IAG/D,eAAkD;IACpD,AADE,kEAAkD,sDACA;IAGtD,eAkBC;IAlBD,2DAkBC;IAGH,cAiCC;IAjCD,kEAiCC;;;;IAvPL,AAJF,8BAEgC,aAEiC;IAApC,sMAAa,4BAAqB,KAAC;IAAC,iBAAM;IAGnE,AADF,8BAA0B,aACI;IAC1B,uBAAmD;IAEjD,AADF,8BAAyB,YACE;IAAA,iCAAiB;IAAA,iBAAK;IAC/C,yGAAiB;IAIrB,AADE,iBAAM,EACF;IACN,kCAA4D;IAAlC,2LAAS,gBAAS,KAAC;IAC3C,yBAAiC;IAErC,AADE,iBAAS,EACL;IAEN,4GAAiB;IA2Of,AADF,gCAA0B,kBACiC;IAAzB,4LAAS,qBAAc,KAAC;IACtD,yBAA6C;IAC7C,mCACF;IAAA,iBAAS;IACT,mCAAsD;IAApB,4LAAS,gBAAS,KAAC;IACnD,wBACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IAtQJ,gDAA6B;IAD7B,oCAAQ;IAUF,eAEC;IAFD,2CAEC;IAQP,eAwOC;IAxOD,4CAwOC;;ADpPL;;GAEG;AACH,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAU1D;;;;;;GAMG;AA4BH,MAAM,OAAO,uBAAuB;IA4BZ;IA3BpB,2CAA2C;IAC3C,SAAS;IACT,2CAA2C;IAElC,SAAS,GAAqB,IAAI,CAAC;IACnC,OAAO,GAAY,KAAK,CAAC;IACzB,WAAW,GAAY,IAAI,CAAC;IAErC,2CAA2C;IAC3C,UAAU;IACV,2CAA2C;IAEjC,KAAK,GAAG,IAAI,YAAY,EAAQ,CAAC;IACjC,UAAU,GAAG,IAAI,YAAY,EAAwB,CAAC;IACtD,qBAAqB,GAAG,IAAI,YAAY,EAA8B,CAAC;IAEjF,2CAA2C;IAC3C,iBAAiB;IACjB,2CAA2C;IAEpC,UAAU,GAAW,GAAG,CAAC;IACzB,gBAAgB,GAAgB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE/D,UAAU,GAAY,KAAK,CAAC;IAC5B,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,mBAAmB,GAAG,IAAI,OAAO,EAAU,CAAC;IAEpD,YAAoB,GAAsB;QAAtB,QAAG,GAAH,GAAG,CAAmB;QACtC,6BAA6B;QAC7B,IAAI,CAAC,mBAAmB,CAAC,IAAI,CACzB,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC3B,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,QAAQ;QACJ,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,WAAW;QACP,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,2CAA2C;IAC3C,iBAAiB;IACjB,2CAA2C;IAEpC,aAAa,CAAC,OAAe;QAChC,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,iBAAiB,CAAC,OAAe;QACpC,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,2CAA2C;IAC3C,gBAAgB;IAChB,2CAA2C;IAEpC,OAAO;QACV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAEM,uBAAuB,CAAC,KAAiC;QAC5D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAEM,qBAAqB,CAAC,GAAwB;QACjD,gDAAgD;QAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC;QAC/B,MAAM,YAAY,GAAG,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QAC3E,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3E,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAC5B,SAAS,EAAE,YAAY,QAAQ,KAAK;YACpC,SAAS,EAAE,GAAG,CAAC,KAAK;YACpB,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7D,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC;SACtC,CAAC,CAAC;IACP,CAAC;IAEM,YAAY;QACf,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACjB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;gBAC1B,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;aACjC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,2CAA2C;IAC3C,kBAAkB;IAClB,2CAA2C;IAEpC,aAAa,CAAC,KAAiB;QAClC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3B,CAAC;IAGD,WAAW,CAAC,KAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAGD,SAAS;QACL,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,2CAA2C;IAC3C,oBAAoB;IACpB,2CAA2C;IAEnC,cAAc;QAClB,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;YACvE,IAAI,KAAK,EAAE,CAAC;gBACR,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;YACjD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,KAAa;QACzC,IAAI,CAAC;YACD,MAAM,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;QAC7E,CAAC;IACL,CAAC;IAED,2CAA2C;IAC3C,UAAU;IACV,2CAA2C;IAEpC,mBAAmB,CAAC,KAAqB;QAC5C,OAAO,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,IAAI,SAAS,CAAC;IAC/D,CAAC;IAEM,mBAAmB,CAAC,KAAyB;QAChD,OAAO,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC;IAClC,CAAC;IAEM,YAAY,CAAC,KAAa,EAAE,KAAqB;QACpD,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;IAEM,YAAY,CAAC,KAAa,EAAE,KAAyB;QACxD,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;iHApKQ,uBAAuB;6DAAvB,uBAAuB;YAAvB,0GAAA,uBAAmB,0BAAI,mFAAvB,eAAW,0BAAY;;YChEpC,yFAA8B;YAO9B,0FAAe;;YAPf,yDAKC;YAED,cA0QC;YA1QD,sCA0QC;mzVDtOe;gBACR,OAAO,CAAC,SAAS,EAAE;oBACf,UAAU,CAAC,QAAQ,EAAE;wBACjB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;wBACxC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;qBACnE,CAAC;oBACF,UAAU,CAAC,QAAQ,EAAE;wBACjB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;qBACrE,CAAC;iBACL,CAAC;gBACF,OAAO,CAAC,QAAQ,EAAE;oBACd,UAAU,CAAC,QAAQ,EAAE;wBACjB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;wBACrB,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;qBACnD,CAAC;oBACF,UAAU,CAAC,QAAQ,EAAE;wBACjB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;qBAClD,CAAC;iBACL,CAAC;aACL;;iFAEQ,uBAAuB;cA3BnC,SAAS;6BACI,KAAK,YACL,qBAAqB,mBAGd,uBAAuB,CAAC,MAAM,cACnC;oBACR,OAAO,CAAC,SAAS,EAAE;wBACf,UAAU,CAAC,QAAQ,EAAE;4BACjB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;4BACxC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;yBACnE,CAAC;wBACF,UAAU,CAAC,QAAQ,EAAE;4BACjB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;yBACrE,CAAC;qBACL,CAAC;oBACF,OAAO,CAAC,QAAQ,EAAE;wBACd,UAAU,CAAC,QAAQ,EAAE;4BACjB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;4BACrB,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;yBACnD,CAAC;wBACF,UAAU,CAAC,QAAQ,EAAE;4BACjB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;yBAClD,CAAC;qBACL,CAAC;iBACL;;kBAOA,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAML,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBA6FN,YAAY;mBAAC,oBAAoB,EAAE,CAAC,QAAQ,CAAC;;kBAU7C,YAAY;mBAAC,kBAAkB;;kFAtHvB,uBAAuB","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n OnInit,\n OnDestroy,\n HostListener\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { QueryInfo, QueryFieldInfo, QueryParameterInfo, QueryDependencyInfo } from '@memberjunction/core';\nimport { CompositionTokenClickEvent } from '@memberjunction/ng-code-editor';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\n\n/**\n * User Settings key for info panel width\n */\nconst INFO_PANEL_WIDTH_KEY = 'QueryViewer_InfoPanelWidth';\n\n/**\n * Event emitted when opening the full query record\n */\nexport interface OpenQueryRecordEvent {\n queryId: string;\n queryName: string;\n}\n\n/**\n * A slide-in panel that displays detailed query information.\n * Features:\n * - Expandable sections for fields, parameters, and SQL\n * - Resizable width with persistence\n * - Open button to navigate to full record\n */\n@Component({\n standalone: false,\n selector: 'mj-query-info-panel',\n templateUrl: './query-info-panel.component.html',\n styleUrls: ['./query-info-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('slideIn', [\n transition(':enter', [\n style({ transform: 'translateX(100%)' }),\n animate('250ms ease-out', style({ transform: 'translateX(0)' }))\n ]),\n transition(':leave', [\n animate('200ms ease-in', style({ transform: 'translateX(100%)' }))\n ])\n ]),\n trigger('fadeIn', [\n transition(':enter', [\n style({ opacity: 0 }),\n animate('200ms ease-out', style({ opacity: 1 }))\n ]),\n transition(':leave', [\n animate('150ms ease-in', style({ opacity: 0 }))\n ])\n ])\n ]\n})\nexport class QueryInfoPanelComponent implements OnInit, OnDestroy {\n // ========================================\n // Inputs\n // ========================================\n\n @Input() QueryInfo: QueryInfo | null = null;\n @Input() Visible: boolean = false;\n @Input() ShowOverlay: boolean = true;\n\n // ========================================\n // Outputs\n // ========================================\n\n @Output() Close = new EventEmitter<void>();\n @Output() OpenRecord = new EventEmitter<OpenQueryRecordEvent>();\n @Output() CompositionTokenClick = new EventEmitter<CompositionTokenClickEvent>();\n\n // ========================================\n // Internal State\n // ========================================\n\n public PanelWidth: number = 450;\n public ExpandedSections: Set<string> = new Set(['overview', 'fields']);\n\n private isResizing: boolean = false;\n private destroy$ = new Subject<void>();\n private widthPersistSubject = new Subject<number>();\n\n constructor(private cdr: ChangeDetectorRef) {\n // Debounce width persistence\n this.widthPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(width => {\n this.persistPanelWidth(width);\n });\n }\n\n ngOnInit(): void {\n this.loadPanelWidth();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Section Toggle\n // ========================================\n\n public ToggleSection(section: string): void {\n if (this.ExpandedSections.has(section)) {\n this.ExpandedSections.delete(section);\n } else {\n this.ExpandedSections.add(section);\n }\n this.cdr.markForCheck();\n }\n\n public IsSectionExpanded(section: string): boolean {\n return this.ExpandedSections.has(section);\n }\n\n // ========================================\n // Panel Actions\n // ========================================\n\n public OnClose(): void {\n this.Close.emit();\n }\n\n public OnCompositionTokenClick(event: CompositionTokenClickEvent): void {\n this.CompositionTokenClick.emit(event);\n }\n\n public OnDependentQueryClick(dep: QueryDependencyInfo): void {\n // Navigate to the dependent (referencing) query\n const depQuery = dep.QueryInfo;\n const categoryPath = depQuery?.CategoryPath?.replace(/^\\/|\\/$/g, '') || '';\n const fullPath = categoryPath ? `${categoryPath}/${dep.Query}` : dep.Query;\n this.CompositionTokenClick.emit({\n FullToken: `{{query:\"${fullPath}\"}}`,\n QueryName: dep.Query,\n CategorySegments: categoryPath ? categoryPath.split('/') : [],\n FullPath: fullPath,\n MouseEvent: new MouseEvent('click')\n });\n }\n\n public OnOpenRecord(): void {\n if (this.QueryInfo) {\n this.OpenRecord.emit({\n queryId: this.QueryInfo.ID,\n queryName: this.QueryInfo.Name\n });\n }\n }\n\n // ========================================\n // Resize Handling\n // ========================================\n\n public OnResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.isResizing = true;\n }\n\n @HostListener('document:mousemove', ['$event'])\n OnMouseMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const newWidth = window.innerWidth - event.clientX;\n this.PanelWidth = Math.min(Math.max(newWidth, 350), 800);\n this.widthPersistSubject.next(this.PanelWidth);\n this.cdr.markForCheck();\n }\n\n @HostListener('document:mouseup')\n OnMouseUp(): void {\n this.isResizing = false;\n }\n\n // ========================================\n // Width Persistence\n // ========================================\n\n private loadPanelWidth(): void {\n try {\n const saved = UserInfoEngine.Instance.GetSetting(INFO_PANEL_WIDTH_KEY);\n if (saved) {\n this.PanelWidth = parseInt(saved, 10) || 450;\n }\n } catch (error) {\n console.warn('[query-info-panel] Failed to load panel width:', error);\n }\n }\n\n private async persistPanelWidth(width: number): Promise<void> {\n try {\n await UserInfoEngine.Instance.SetSetting(INFO_PANEL_WIDTH_KEY, String(width));\n } catch (error) {\n console.warn('[query-info-panel] Failed to persist panel width:', error);\n }\n }\n\n // ========================================\n // Helpers\n // ========================================\n\n public GetFieldTypeDisplay(field: QueryFieldInfo): string {\n return field.SQLFullType || field.SQLBaseType || 'unknown';\n }\n\n public GetParamTypeDisplay(param: QueryParameterInfo): string {\n return param.Type || 'string';\n }\n\n public TrackByField(index: number, field: QueryFieldInfo): string {\n return field.Name;\n }\n\n public TrackByParam(index: number, param: QueryParameterInfo): string {\n return param.Name;\n }\n}\n","<!-- Query Info Panel - Slide-in Panel -->\n@if (Visible && ShowOverlay) {\n <div class=\"info-panel-overlay\"\n @fadeIn\n (click)=\"OnClose()\">\n </div>\n}\n\n@if (Visible) {\n <div class=\"info-panel\"\n @slideIn\n [style.width.px]=\"PanelWidth\">\n <!-- Resize handle -->\n <div class=\"resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-content\">\n <i class=\"fa-solid fa-circle-info header-icon\"></i>\n <div class=\"header-text\">\n <h3 class=\"header-title\">Query Information</h3>\n @if (QueryInfo) {\n <span class=\"header-subtitle\">{{ QueryInfo.Name }}</span>\n }\n </div>\n </div>\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Content -->\n @if (QueryInfo) {\n <div class=\"panel-content\">\n <!-- Overview Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('overview')\">\n <div class=\"section-header\" (click)=\"ToggleSection('overview')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('overview')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('overview')\"></i>\n <span class=\"section-title\">Overview</span>\n </div>\n @if (IsSectionExpanded('overview')) {\n <div class=\"section-content\">\n <div class=\"info-row\">\n <span class=\"info-label\">Name</span>\n <span class=\"info-value\">{{ QueryInfo.Name }}</span>\n </div>\n @if (QueryInfo.Description) {\n <div class=\"info-row\">\n <span class=\"info-label\">Description</span>\n <span class=\"info-value description\">{{ QueryInfo.Description }}</span>\n </div>\n }\n @if (QueryInfo.Category) {\n <div class=\"info-row\">\n <span class=\"info-label\">Category</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-folder category-icon\"></i>\n {{ QueryInfo.Category }}\n </span>\n </div>\n }\n <div class=\"info-row\">\n <span class=\"info-label\">Status</span>\n <span class=\"info-value\">\n <span class=\"status-badge\" [class.approved]=\"QueryInfo.Status === 'Approved'\">\n {{ QueryInfo.Status }}\n </span>\n </span>\n </div>\n @if (QueryInfo.OriginalSQL) {\n <div class=\"info-row\">\n <span class=\"info-label\">Has SQL</span>\n <span class=\"info-value\">\n <i class=\"fa-solid fa-check text-success\"></i> Yes\n </span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Technical Description Section -->\n @if (QueryInfo.TechnicalDescription) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('technical')\">\n <div class=\"section-header\" (click)=\"ToggleSection('technical')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('technical')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('technical')\"></i>\n <span class=\"section-title\">Technical Description</span>\n </div>\n @if (IsSectionExpanded('technical')) {\n <div class=\"section-content technical-description-content\">\n <mj-markdown\n [data]=\"QueryInfo.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n }\n <!-- Fields Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('fields')\">\n <div class=\"section-header\" (click)=\"ToggleSection('fields')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('fields')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('fields')\"></i>\n <span class=\"section-title\">Fields</span>\n <span class=\"section-count\">({{ QueryInfo.Fields.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('fields')) {\n <div class=\"section-content\">\n @if (QueryInfo.Fields.length) {\n <div class=\"fields-list\">\n @for (field of QueryInfo.Fields; track TrackByField($index, field)) {\n <div class=\"field-item\">\n <div class=\"field-header\">\n <span class=\"field-name\">{{ field.Name }}</span>\n <span class=\"field-type\">{{ GetFieldTypeDisplay(field) }}</span>\n </div>\n @if (field.Description || field.SourceEntity) {\n <div class=\"field-details\">\n @if (field.Description) {\n <span class=\"field-description\">\n {{ field.Description }}\n </span>\n }\n @if (field.SourceEntity) {\n <span class=\"field-source\">\n <i class=\"fa-solid fa-link\"></i>\n {{ field.SourceEntity }}.{{ field.SourceFieldName }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>No fields defined</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Parameters Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('parameters')\">\n <div class=\"section-header\" (click)=\"ToggleSection('parameters')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('parameters')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('parameters')\"></i>\n <span class=\"section-title\">Parameters</span>\n <span class=\"section-count\">({{ QueryInfo.Parameters.length || 0 }})</span>\n </div>\n @if (IsSectionExpanded('parameters')) {\n <div class=\"section-content\">\n @if (QueryInfo.Parameters.length) {\n <div class=\"params-list\">\n @for (param of QueryInfo.Parameters; track TrackByParam($index, param)) {\n <div class=\"param-item\">\n <div class=\"param-header\">\n <span class=\"param-name\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-badge\">Required</span>\n }\n </span>\n <span class=\"param-type\">{{ GetParamTypeDisplay(param) }}</span>\n </div>\n @if (param.Description || param.DefaultValue) {\n <div class=\"param-details\">\n @if (param.Description) {\n <span class=\"param-description\">\n {{ param.Description }}\n </span>\n }\n @if (param.DefaultValue) {\n <span class=\"param-default\">\n Default: {{ param.DefaultValue }}\n </span>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>No parameters required</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- SQL Section -->\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('sql')\">\n <div class=\"section-header\" (click)=\"ToggleSection('sql')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('sql')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('sql')\"></i>\n <span class=\"section-title\">SQL Query</span>\n </div>\n @if (IsSectionExpanded('sql')) {\n <div class=\"section-content\">\n @if (QueryInfo.SQL) {\n <div class=\"sql-container\">\n <mj-code-editor\n [value]=\"QueryInfo.SQL\"\n [readonly]=\"true\"\n [language]=\"'sql'\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-section\">\n <i class=\"fa-solid fa-code\"></i>\n <span>SQL not available</span>\n </div>\n }\n </div>\n }\n </div>\n <!-- Dependent Queries Section -->\n @if (QueryInfo.Dependents.length > 0) {\n <div class=\"info-section\" [class.expanded]=\"IsSectionExpanded('dependents')\">\n <div class=\"section-header\" (click)=\"ToggleSection('dependents')\">\n <i class=\"fa-solid section-icon\"\n [class.fa-chevron-down]=\"IsSectionExpanded('dependents')\"\n [class.fa-chevron-right]=\"!IsSectionExpanded('dependents')\"></i>\n <span class=\"section-title\">Dependent Queries</span>\n <span class=\"section-count\">({{ QueryInfo.Dependents.length }})</span>\n </div>\n @if (IsSectionExpanded('dependents')) {\n <div class=\"section-content\">\n <div class=\"dependents-list\">\n @for (dep of QueryInfo.Dependents; track dep.ID) {\n <div class=\"dependent-item\" (click)=\"OnDependentQueryClick(dep)\">\n <div class=\"dependent-header\">\n <i class=\"fa-solid fa-arrow-left dependent-icon\"></i>\n <span class=\"dependent-name\">{{ dep.Query }}</span>\n </div>\n @if (dep.ReferencePath) {\n <span class=\"dependent-ref-path\">\n via {{ dep.ReferencePath }}\n </span>\n }\n </div>\n }\n </div>\n <div class=\"dependents-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n These queries reference this query via composition\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Footer -->\n <div class=\"panel-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnOpenRecord()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnClose()\">\n Close\n </button>\n </div>\n </div>\n}\n"]}
|