@memberjunction/ng-core-entity-forms 5.10.0 → 5.11.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/custom/AIPrompts/ai-prompt-form.component.js +3 -3
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.d.ts +25 -2
- package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +299 -139
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +87 -49
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJQueryDependency/mjquerydependency.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJQueryDependency/mjquerydependency.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJQueryDependency/mjquerydependency.form.component.js +69 -0
- package/dist/lib/generated/Entities/MJQueryDependency/mjquerydependency.form.component.js.map +1 -0
- package/dist/lib/generated/generated-forms.module.d.ts +86 -85
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +23 -20
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/package.json +31 -31
|
@@ -4,12 +4,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component, ViewChild } from '@angular/core';
|
|
7
|
+
import { Component, ViewChild, inject } from '@angular/core';
|
|
8
8
|
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
|
-
import { BaseFormComponent } from '@memberjunction/ng-base-forms';
|
|
9
|
+
import { BaseFormComponent, DEFAULT_TOOLBAR_CONFIG } from '@memberjunction/ng-base-forms';
|
|
10
10
|
import { MJQueryFormComponent } from '../../generated/Entities/MJQuery/mjquery.form.component';
|
|
11
|
-
import { Metadata, RunView, RUN_QUERY_SQL_FILTERS } from '@memberjunction/core';
|
|
11
|
+
import { Metadata, RunView, RUN_QUERY_SQL_FILTERS, CompositeKey } from '@memberjunction/core';
|
|
12
12
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
13
|
+
import { NavigationService } from '@memberjunction/ng-shared';
|
|
13
14
|
import { Subject } from 'rxjs';
|
|
14
15
|
import * as i0 from "@angular/core";
|
|
15
16
|
import * as i1 from "@angular/common";
|
|
@@ -74,7 +75,7 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_17_Template(rf,
|
|
|
74
75
|
} if (rf & 2) {
|
|
75
76
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
76
77
|
i0.ɵɵadvance();
|
|
77
|
-
i0.ɵɵtextInterpolate(ctx_r2.
|
|
78
|
+
i0.ɵɵtextInterpolate(ctx_r2.categoryPathDisplay || "Uncategorized");
|
|
78
79
|
} }
|
|
79
80
|
function MJQueryFormComponentExtended_Conditional_1_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
80
81
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
@@ -298,7 +299,7 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_33_ng_template_1
|
|
|
298
299
|
function MJQueryFormComponentExtended_Conditional_1_Conditional_33_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
299
300
|
i0.ɵɵelementStart(0, "span", 53);
|
|
300
301
|
i0.ɵɵelement(1, "i", 76);
|
|
301
|
-
i0.ɵɵtext(2, "
|
|
302
|
+
i0.ɵɵtext(2, " Parameters ");
|
|
302
303
|
i0.ɵɵconditionalCreate(3, MJQueryFormComponentExtended_Conditional_1_Conditional_33_ng_template_1_Conditional_3_Template, 2, 1, "span", 77);
|
|
303
304
|
i0.ɵɵelementEnd();
|
|
304
305
|
} if (rf & 2) {
|
|
@@ -464,7 +465,7 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_34_ng_template_1
|
|
|
464
465
|
function MJQueryFormComponentExtended_Conditional_1_Conditional_34_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
465
466
|
i0.ɵɵelementStart(0, "span", 53);
|
|
466
467
|
i0.ɵɵelement(1, "i", 106);
|
|
467
|
-
i0.ɵɵtext(2, "
|
|
468
|
+
i0.ɵɵtext(2, " Fields ");
|
|
468
469
|
i0.ɵɵconditionalCreate(3, MJQueryFormComponentExtended_Conditional_1_Conditional_34_ng_template_1_Conditional_3_Template, 2, 1, "span", 77);
|
|
469
470
|
i0.ɵɵelementEnd();
|
|
470
471
|
} if (rf & 2) {
|
|
@@ -599,7 +600,89 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_34_Template(rf,
|
|
|
599
600
|
i0.ɵɵadvance(3);
|
|
600
601
|
i0.ɵɵconditional(ctx_r2.isLoadingFields ? 3 : 4);
|
|
601
602
|
} }
|
|
602
|
-
function
|
|
603
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_35_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
604
|
+
i0.ɵɵelementStart(0, "span", 53);
|
|
605
|
+
i0.ɵɵelement(1, "i", 118);
|
|
606
|
+
i0.ɵɵtext(2, " Dependent Queries ");
|
|
607
|
+
i0.ɵɵelementStart(3, "span", 77);
|
|
608
|
+
i0.ɵɵtext(4);
|
|
609
|
+
i0.ɵɵelementEnd()();
|
|
610
|
+
} if (rf & 2) {
|
|
611
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
612
|
+
i0.ɵɵadvance(4);
|
|
613
|
+
i0.ɵɵtextInterpolate(ctx_r2.DependentQueries.length);
|
|
614
|
+
} }
|
|
615
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
616
|
+
i0.ɵɵelementStart(0, "div", 97)(1, "span", 98);
|
|
617
|
+
i0.ɵɵelement(2, "i", 124);
|
|
618
|
+
i0.ɵɵtext(3);
|
|
619
|
+
i0.ɵɵelementEnd()();
|
|
620
|
+
} if (rf & 2) {
|
|
621
|
+
const dep_r25 = i0.ɵɵnextContext().$implicit;
|
|
622
|
+
i0.ɵɵadvance(3);
|
|
623
|
+
i0.ɵɵtextInterpolate1(" ", dep_r25.ReferencePath, " ");
|
|
624
|
+
} }
|
|
625
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
626
|
+
i0.ɵɵelementStart(0, "div", 97)(1, "span", 98)(2, "strong");
|
|
627
|
+
i0.ɵɵtext(3, "Alias:");
|
|
628
|
+
i0.ɵɵelementEnd();
|
|
629
|
+
i0.ɵɵelementStart(4, "code", 100);
|
|
630
|
+
i0.ɵɵtext(5);
|
|
631
|
+
i0.ɵɵelementEnd()()();
|
|
632
|
+
} if (rf & 2) {
|
|
633
|
+
const dep_r25 = i0.ɵɵnextContext().$implicit;
|
|
634
|
+
i0.ɵɵadvance(5);
|
|
635
|
+
i0.ɵɵtextInterpolate(dep_r25.Alias);
|
|
636
|
+
} }
|
|
637
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
638
|
+
const _r24 = i0.ɵɵgetCurrentView();
|
|
639
|
+
i0.ɵɵelementStart(0, "div", 119);
|
|
640
|
+
i0.ɵɵlistener("click", function MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Template_div_click_0_listener() { const dep_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onDependentQueryClick(dep_r25)); });
|
|
641
|
+
i0.ɵɵelementStart(1, "div", 90)(2, "div", 91);
|
|
642
|
+
i0.ɵɵelement(3, "i", 120);
|
|
643
|
+
i0.ɵɵtext(4);
|
|
644
|
+
i0.ɵɵelementEnd()();
|
|
645
|
+
i0.ɵɵelementStart(5, "div", 95);
|
|
646
|
+
i0.ɵɵconditionalCreate(6, MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Conditional_6_Template, 4, 1, "div", 97);
|
|
647
|
+
i0.ɵɵconditionalCreate(7, MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Conditional_7_Template, 6, 1, "div", 97);
|
|
648
|
+
i0.ɵɵelementEnd();
|
|
649
|
+
i0.ɵɵelementStart(8, "div", 121)(9, "span", 122);
|
|
650
|
+
i0.ɵɵelement(10, "i", 123);
|
|
651
|
+
i0.ɵɵtext(11, " Open ");
|
|
652
|
+
i0.ɵɵelementEnd()()();
|
|
653
|
+
} if (rf & 2) {
|
|
654
|
+
const dep_r25 = ctx.$implicit;
|
|
655
|
+
i0.ɵɵadvance(4);
|
|
656
|
+
i0.ɵɵtextInterpolate1(" ", dep_r25.Query, " ");
|
|
657
|
+
i0.ɵɵadvance(2);
|
|
658
|
+
i0.ɵɵconditional(dep_r25.ReferencePath ? 6 : -1);
|
|
659
|
+
i0.ɵɵadvance();
|
|
660
|
+
i0.ɵɵconditional(dep_r25.Alias ? 7 : -1);
|
|
661
|
+
} }
|
|
662
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
663
|
+
const _r23 = i0.ɵɵgetCurrentView();
|
|
664
|
+
i0.ɵɵelementStart(0, "kendo-expansionpanel", 24);
|
|
665
|
+
i0.ɵɵtwoWayListener("expandedChange", function MJQueryFormComponentExtended_Conditional_1_Conditional_35_Template_kendo_expansionpanel_expandedChange_0_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.dependentsPanelExpanded, $event) || (ctx_r2.dependentsPanelExpanded = $event); return i0.ɵɵresetView($event); });
|
|
666
|
+
i0.ɵɵtemplate(1, MJQueryFormComponentExtended_Conditional_1_Conditional_35_ng_template_1_Template, 5, 1, "ng-template", 25);
|
|
667
|
+
i0.ɵɵelementStart(2, "div", 30)(3, "div", 116);
|
|
668
|
+
i0.ɵɵtext(4, " These queries reference this query via ");
|
|
669
|
+
i0.ɵɵelementStart(5, "code");
|
|
670
|
+
i0.ɵɵtext(6);
|
|
671
|
+
i0.ɵɵelementEnd();
|
|
672
|
+
i0.ɵɵtext(7, " composition syntax. ");
|
|
673
|
+
i0.ɵɵelementEnd();
|
|
674
|
+
i0.ɵɵelementStart(8, "div", 87);
|
|
675
|
+
i0.ɵɵrepeaterCreate(9, MJQueryFormComponentExtended_Conditional_1_Conditional_35_For_10_Template, 12, 3, "div", 117, _forTrack2);
|
|
676
|
+
i0.ɵɵelementEnd()()();
|
|
677
|
+
} if (rf & 2) {
|
|
678
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
679
|
+
i0.ɵɵtwoWayProperty("expanded", ctx_r2.dependentsPanelExpanded);
|
|
680
|
+
i0.ɵɵadvance(6);
|
|
681
|
+
i0.ɵɵtextInterpolate1("", "{{query:\"...\"}}", " ");
|
|
682
|
+
i0.ɵɵadvance(3);
|
|
683
|
+
i0.ɵɵrepeater(ctx_r2.DependentQueries);
|
|
684
|
+
} }
|
|
685
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_ng_template_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
603
686
|
i0.ɵɵelementStart(0, "span", 77);
|
|
604
687
|
i0.ɵɵtext(1);
|
|
605
688
|
i0.ɵɵelementEnd();
|
|
@@ -608,105 +691,105 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_35_ng_template_1
|
|
|
608
691
|
i0.ɵɵadvance();
|
|
609
692
|
i0.ɵɵtextInterpolate(ctx_r2.queryEntities.length);
|
|
610
693
|
} }
|
|
611
|
-
function
|
|
694
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
612
695
|
i0.ɵɵelementStart(0, "span", 53);
|
|
613
|
-
i0.ɵɵelement(1, "i",
|
|
614
|
-
i0.ɵɵtext(2, "
|
|
615
|
-
i0.ɵɵconditionalCreate(3,
|
|
696
|
+
i0.ɵɵelement(1, "i", 125);
|
|
697
|
+
i0.ɵɵtext(2, " Entities ");
|
|
698
|
+
i0.ɵɵconditionalCreate(3, MJQueryFormComponentExtended_Conditional_1_Conditional_36_ng_template_1_Conditional_3_Template, 2, 1, "span", 77);
|
|
616
699
|
i0.ɵɵelementEnd();
|
|
617
700
|
} if (rf & 2) {
|
|
618
701
|
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
619
702
|
i0.ɵɵadvance(3);
|
|
620
703
|
i0.ɵɵconditional(ctx_r2.queryEntities.length > 0 ? 3 : -1);
|
|
621
704
|
} }
|
|
622
|
-
function
|
|
705
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
623
706
|
i0.ɵɵelementStart(0, "div", 75);
|
|
624
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
707
|
+
i0.ɵɵelement(1, "mj-loading", 126);
|
|
625
708
|
i0.ɵɵelementEnd();
|
|
626
709
|
} }
|
|
627
|
-
function
|
|
628
|
-
const
|
|
710
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_0_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
711
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
629
712
|
i0.ɵɵelementStart(0, "button", 84);
|
|
630
|
-
i0.ɵɵlistener("click", function
|
|
713
|
+
i0.ɵɵlistener("click", function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_0_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.addEntity()); });
|
|
631
714
|
i0.ɵɵelement(1, "i", 85);
|
|
632
715
|
i0.ɵɵtext(2, " Add First Entity ");
|
|
633
716
|
i0.ɵɵelementEnd();
|
|
634
717
|
} }
|
|
635
|
-
function
|
|
718
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
636
719
|
i0.ɵɵelementStart(0, "div", 79);
|
|
637
|
-
i0.ɵɵelement(1, "i",
|
|
720
|
+
i0.ɵɵelement(1, "i", 127);
|
|
638
721
|
i0.ɵɵelementStart(2, "div", 81);
|
|
639
722
|
i0.ɵɵtext(3, "No Entities Tracked");
|
|
640
723
|
i0.ɵɵelementEnd();
|
|
641
724
|
i0.ɵɵelementStart(4, "div", 82);
|
|
642
725
|
i0.ɵɵtext(5, " Track which entities this query uses for documentation. ");
|
|
643
726
|
i0.ɵɵelementEnd();
|
|
644
|
-
i0.ɵɵconditionalCreate(6,
|
|
727
|
+
i0.ɵɵconditionalCreate(6, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_0_Conditional_6_Template, 3, 0, "button", 83);
|
|
645
728
|
i0.ɵɵelementEnd();
|
|
646
729
|
} if (rf & 2) {
|
|
647
730
|
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
648
731
|
i0.ɵɵadvance(6);
|
|
649
732
|
i0.ɵɵconditional(ctx_r2.EditMode ? 6 : -1);
|
|
650
733
|
} }
|
|
651
|
-
function
|
|
652
|
-
const
|
|
734
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
735
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
653
736
|
i0.ɵɵelementStart(0, "div", 86)(1, "button", 84);
|
|
654
|
-
i0.ɵɵlistener("click", function
|
|
737
|
+
i0.ɵɵlistener("click", function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r28); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.addEntity()); });
|
|
655
738
|
i0.ɵɵelement(2, "i", 85);
|
|
656
739
|
i0.ɵɵtext(3, " Add Entity ");
|
|
657
740
|
i0.ɵɵelementEnd()();
|
|
658
741
|
} }
|
|
659
|
-
function
|
|
660
|
-
const
|
|
661
|
-
i0.ɵɵelementStart(0, "div",
|
|
662
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
742
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
743
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
744
|
+
i0.ɵɵelementStart(0, "div", 129)(1, "kendo-dropdownlist", 130);
|
|
745
|
+
i0.ɵɵtwoWayListener("ngModelChange", function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_5_Template_kendo_dropdownlist_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r29); const entity_r30 = i0.ɵɵnextContext().$implicit; i0.ɵɵtwoWayBindingSet(entity_r30.EntityID, $event) || (entity_r30.EntityID = $event); return i0.ɵɵresetView($event); });
|
|
663
746
|
i0.ɵɵelementEnd()();
|
|
664
747
|
} if (rf & 2) {
|
|
665
|
-
const
|
|
748
|
+
const entity_r30 = i0.ɵɵnextContext().$implicit;
|
|
666
749
|
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
667
750
|
i0.ɵɵadvance();
|
|
668
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
669
|
-
i0.ɵɵproperty("name", "entity_" +
|
|
751
|
+
i0.ɵɵtwoWayProperty("ngModel", entity_r30.EntityID);
|
|
752
|
+
i0.ɵɵproperty("name", "entity_" + entity_r30.ID)("data", ctx_r2.getEntityOptions())("valuePrimitive", true);
|
|
670
753
|
} }
|
|
671
|
-
function
|
|
754
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
672
755
|
i0.ɵɵelementStart(0, "div", 95)(1, "div", 97)(2, "span", 98);
|
|
673
|
-
i0.ɵɵelement(3, "i",
|
|
756
|
+
i0.ɵɵelement(3, "i", 131);
|
|
674
757
|
i0.ɵɵtext(4, " Data Source ");
|
|
675
758
|
i0.ɵɵelementEnd()()();
|
|
676
759
|
} }
|
|
677
|
-
function
|
|
678
|
-
const
|
|
679
|
-
i0.ɵɵelementStart(0, "div", 114)(1, "button",
|
|
680
|
-
i0.ɵɵlistener("click", function
|
|
760
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
761
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
762
|
+
i0.ɵɵelementStart(0, "div", 114)(1, "button", 132);
|
|
763
|
+
i0.ɵɵlistener("click", function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_7_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r31); const entity_r30 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.deleteEntity(entity_r30)); });
|
|
681
764
|
i0.ɵɵelement(2, "i", 105);
|
|
682
765
|
i0.ɵɵelementEnd()();
|
|
683
766
|
} }
|
|
684
|
-
function
|
|
767
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
685
768
|
i0.ɵɵelementStart(0, "div", 109)(1, "div", 90)(2, "div", 91);
|
|
686
|
-
i0.ɵɵelement(3, "i",
|
|
769
|
+
i0.ɵɵelement(3, "i", 128);
|
|
687
770
|
i0.ɵɵtext(4);
|
|
688
771
|
i0.ɵɵelementEnd();
|
|
689
|
-
i0.ɵɵconditionalCreate(5,
|
|
772
|
+
i0.ɵɵconditionalCreate(5, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_5_Template, 2, 4, "div", 129);
|
|
690
773
|
i0.ɵɵelementEnd();
|
|
691
|
-
i0.ɵɵconditionalCreate(6,
|
|
692
|
-
i0.ɵɵconditionalCreate(7,
|
|
774
|
+
i0.ɵɵconditionalCreate(6, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_6_Template, 5, 0, "div", 95);
|
|
775
|
+
i0.ɵɵconditionalCreate(7, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Conditional_7_Template, 3, 0, "div", 114);
|
|
693
776
|
i0.ɵɵelementEnd();
|
|
694
777
|
} if (rf & 2) {
|
|
695
|
-
const
|
|
778
|
+
const entity_r30 = ctx.$implicit;
|
|
696
779
|
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
697
780
|
i0.ɵɵadvance(4);
|
|
698
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
781
|
+
i0.ɵɵtextInterpolate1(" ", entity_r30.Entity || "Select Entity...", " ");
|
|
699
782
|
i0.ɵɵadvance();
|
|
700
783
|
i0.ɵɵconditional(ctx_r2.EditMode ? 5 : -1);
|
|
701
784
|
i0.ɵɵadvance();
|
|
702
|
-
i0.ɵɵconditional(!ctx_r2.EditMode &&
|
|
785
|
+
i0.ɵɵconditional(!ctx_r2.EditMode && entity_r30.Entity ? 6 : -1);
|
|
703
786
|
i0.ɵɵadvance();
|
|
704
787
|
i0.ɵɵconditional(ctx_r2.EditMode ? 7 : -1);
|
|
705
788
|
} }
|
|
706
|
-
function
|
|
707
|
-
i0.ɵɵconditionalCreate(0,
|
|
789
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
790
|
+
i0.ɵɵconditionalCreate(0, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_Conditional_0_Template, 4, 0, "div", 86);
|
|
708
791
|
i0.ɵɵelementStart(1, "div", 87);
|
|
709
|
-
i0.ɵɵrepeaterCreate(2,
|
|
792
|
+
i0.ɵɵrepeaterCreate(2, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_For_3_Template, 8, 4, "div", 109, _forTrack2);
|
|
710
793
|
i0.ɵɵelementEnd();
|
|
711
794
|
} if (rf & 2) {
|
|
712
795
|
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
@@ -714,19 +797,19 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_35_Conditional_4
|
|
|
714
797
|
i0.ɵɵadvance(2);
|
|
715
798
|
i0.ɵɵrepeater(ctx_r2.queryEntities);
|
|
716
799
|
} }
|
|
717
|
-
function
|
|
718
|
-
i0.ɵɵconditionalCreate(0,
|
|
800
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
801
|
+
i0.ɵɵconditionalCreate(0, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_0_Template, 7, 1, "div", 79)(1, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Conditional_1_Template, 4, 1);
|
|
719
802
|
} if (rf & 2) {
|
|
720
803
|
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
721
804
|
i0.ɵɵconditional(ctx_r2.queryEntities.length === 0 ? 0 : 1);
|
|
722
805
|
} }
|
|
723
|
-
function
|
|
724
|
-
const
|
|
806
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
807
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
725
808
|
i0.ɵɵelementStart(0, "kendo-expansionpanel", 24);
|
|
726
|
-
i0.ɵɵtwoWayListener("expandedChange", function
|
|
727
|
-
i0.ɵɵtemplate(1,
|
|
809
|
+
i0.ɵɵtwoWayListener("expandedChange", function MJQueryFormComponentExtended_Conditional_1_Conditional_36_Template_kendo_expansionpanel_expandedChange_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.entitiesPanelExpanded, $event) || (ctx_r2.entitiesPanelExpanded = $event); return i0.ɵɵresetView($event); });
|
|
810
|
+
i0.ɵɵtemplate(1, MJQueryFormComponentExtended_Conditional_1_Conditional_36_ng_template_1_Template, 4, 1, "ng-template", 25);
|
|
728
811
|
i0.ɵɵelementStart(2, "div", 30);
|
|
729
|
-
i0.ɵɵconditionalCreate(3,
|
|
812
|
+
i0.ɵɵconditionalCreate(3, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_3_Template, 2, 0, "div", 75)(4, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Conditional_4_Template, 2, 1);
|
|
730
813
|
i0.ɵɵelementEnd()();
|
|
731
814
|
} if (rf & 2) {
|
|
732
815
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -734,45 +817,45 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_35_Template(rf,
|
|
|
734
817
|
i0.ɵɵadvance(3);
|
|
735
818
|
i0.ɵɵconditional(ctx_r2.isLoadingEntities ? 3 : 4);
|
|
736
819
|
} }
|
|
737
|
-
function
|
|
820
|
+
function MJQueryFormComponentExtended_Conditional_1_ng_template_38_Template(rf, ctx) { if (rf & 1) {
|
|
738
821
|
i0.ɵɵelementStart(0, "span", 53);
|
|
739
|
-
i0.ɵɵelement(1, "i",
|
|
740
|
-
i0.ɵɵtext(2, "
|
|
822
|
+
i0.ɵɵelement(1, "i", 133);
|
|
823
|
+
i0.ɵɵtext(2, " Details ");
|
|
741
824
|
i0.ɵɵelementEnd();
|
|
742
825
|
} }
|
|
743
|
-
function
|
|
744
|
-
const
|
|
745
|
-
i0.ɵɵelementStart(0, "kendo-switch",
|
|
746
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
826
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_45_Template(rf, ctx) { if (rf & 1) {
|
|
827
|
+
const _r32 = i0.ɵɵgetCurrentView();
|
|
828
|
+
i0.ɵɵelementStart(0, "kendo-switch", 134);
|
|
829
|
+
i0.ɵɵtwoWayListener("ngModelChange", function MJQueryFormComponentExtended_Conditional_1_Conditional_45_Template_kendo_switch_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.record.UsesTemplate, $event) || (ctx_r2.record.UsesTemplate = $event); return i0.ɵɵresetView($event); });
|
|
747
830
|
i0.ɵɵelementEnd();
|
|
748
831
|
} if (rf & 2) {
|
|
749
832
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
750
833
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.record.UsesTemplate);
|
|
751
834
|
} }
|
|
752
|
-
function
|
|
753
|
-
i0.ɵɵelementStart(0, "span",
|
|
835
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_46_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
836
|
+
i0.ɵɵelementStart(0, "span", 135);
|
|
754
837
|
i0.ɵɵelement(1, "i", 59);
|
|
755
838
|
i0.ɵɵtext(2, " Uses Templates");
|
|
756
839
|
i0.ɵɵelementEnd();
|
|
757
840
|
} }
|
|
758
|
-
function
|
|
759
|
-
i0.ɵɵelementStart(0, "span",
|
|
760
|
-
i0.ɵɵelement(1, "i",
|
|
841
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_46_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
842
|
+
i0.ɵɵelementStart(0, "span", 136);
|
|
843
|
+
i0.ɵɵelement(1, "i", 137);
|
|
761
844
|
i0.ɵɵtext(2, " No Templates");
|
|
762
845
|
i0.ɵɵelementEnd();
|
|
763
846
|
} }
|
|
764
|
-
function
|
|
847
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_46_Template(rf, ctx) { if (rf & 1) {
|
|
765
848
|
i0.ɵɵelementStart(0, "div", 36);
|
|
766
|
-
i0.ɵɵconditionalCreate(1,
|
|
849
|
+
i0.ɵɵconditionalCreate(1, MJQueryFormComponentExtended_Conditional_1_Conditional_46_Conditional_1_Template, 3, 0, "span", 135)(2, MJQueryFormComponentExtended_Conditional_1_Conditional_46_Conditional_2_Template, 3, 0, "span", 136);
|
|
767
850
|
i0.ɵɵelementEnd();
|
|
768
851
|
} if (rf & 2) {
|
|
769
852
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
770
853
|
i0.ɵɵadvance();
|
|
771
854
|
i0.ɵɵconditional(ctx_r2.record.UsesTemplate ? 1 : 2);
|
|
772
855
|
} }
|
|
773
|
-
function
|
|
856
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_59_Template(rf, ctx) { if (rf & 1) {
|
|
774
857
|
i0.ɵɵelementStart(0, "div", 32)(1, "label", 33);
|
|
775
|
-
i0.ɵɵelement(2, "i",
|
|
858
|
+
i0.ɵɵelement(2, "i", 138);
|
|
776
859
|
i0.ɵɵtext(3, " Quality Rank ");
|
|
777
860
|
i0.ɵɵelementEnd();
|
|
778
861
|
i0.ɵɵelementStart(4, "div", 36);
|
|
@@ -783,20 +866,20 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_58_Template(rf,
|
|
|
783
866
|
i0.ɵɵadvance(5);
|
|
784
867
|
i0.ɵɵtextInterpolate1("", ctx_r2.record.QualityRank, "/10");
|
|
785
868
|
} }
|
|
786
|
-
function
|
|
869
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
787
870
|
i0.ɵɵelementStart(0, "span", 53);
|
|
788
|
-
i0.ɵɵelement(1, "i",
|
|
789
|
-
i0.ɵɵtext(2, "
|
|
871
|
+
i0.ɵɵelement(1, "i", 139);
|
|
872
|
+
i0.ɵɵtext(2, " Permissions ");
|
|
790
873
|
i0.ɵɵelementEnd();
|
|
791
874
|
} }
|
|
792
|
-
function
|
|
875
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
793
876
|
i0.ɵɵelementStart(0, "div", 75);
|
|
794
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
877
|
+
i0.ɵɵelement(1, "mj-loading", 140);
|
|
795
878
|
i0.ɵɵelementEnd();
|
|
796
879
|
} }
|
|
797
|
-
function
|
|
880
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
798
881
|
i0.ɵɵelementStart(0, "div", 79);
|
|
799
|
-
i0.ɵɵelement(1, "i",
|
|
882
|
+
i0.ɵɵelement(1, "i", 141);
|
|
800
883
|
i0.ɵɵelementStart(2, "div", 81);
|
|
801
884
|
i0.ɵɵtext(3, "No Permissions Set");
|
|
802
885
|
i0.ɵɵelementEnd();
|
|
@@ -804,58 +887,58 @@ function MJQueryFormComponentExtended_Conditional_1_Conditional_59_Conditional_4
|
|
|
804
887
|
i0.ɵɵtext(5, " This query uses default permissions. ");
|
|
805
888
|
i0.ɵɵelementEnd()();
|
|
806
889
|
} }
|
|
807
|
-
function
|
|
808
|
-
i0.ɵɵelement(0, "mj-explorer-entity-data-grid",
|
|
890
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
891
|
+
i0.ɵɵelement(0, "mj-explorer-entity-data-grid", 142);
|
|
809
892
|
} if (rf & 2) {
|
|
810
893
|
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
811
894
|
i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Query Permissions", "QueryID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Query Permissions"))("AllowLoad", true)("ShowToolbar", false);
|
|
812
895
|
} }
|
|
813
|
-
function
|
|
814
|
-
i0.ɵɵelementStart(0, "div",
|
|
815
|
-
i0.ɵɵelement(1, "i",
|
|
816
|
-
i0.ɵɵelementStart(2, "div",
|
|
896
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
897
|
+
i0.ɵɵelementStart(0, "div", 144);
|
|
898
|
+
i0.ɵɵelement(1, "i", 145);
|
|
899
|
+
i0.ɵɵelementStart(2, "div", 146)(3, "div", 147);
|
|
817
900
|
i0.ɵɵtext(4);
|
|
818
901
|
i0.ɵɵelementEnd();
|
|
819
|
-
i0.ɵɵelementStart(5, "div",
|
|
902
|
+
i0.ɵɵelementStart(5, "div", 148);
|
|
820
903
|
i0.ɵɵtext(6, "Role Permission");
|
|
821
904
|
i0.ɵɵelementEnd()();
|
|
822
|
-
i0.ɵɵelementStart(7, "span",
|
|
905
|
+
i0.ɵɵelementStart(7, "span", 149);
|
|
823
906
|
i0.ɵɵelement(8, "i", 43);
|
|
824
907
|
i0.ɵɵtext(9, " Can Execute ");
|
|
825
908
|
i0.ɵɵelementEnd()();
|
|
826
909
|
} if (rf & 2) {
|
|
827
|
-
const
|
|
910
|
+
const permission_r34 = ctx.$implicit;
|
|
828
911
|
i0.ɵɵadvance(4);
|
|
829
|
-
i0.ɵɵtextInterpolate(
|
|
912
|
+
i0.ɵɵtextInterpolate(permission_r34.Role);
|
|
830
913
|
} }
|
|
831
|
-
function
|
|
832
|
-
i0.ɵɵelementStart(0, "div",
|
|
833
|
-
i0.ɵɵrepeaterCreate(1,
|
|
914
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
915
|
+
i0.ɵɵelementStart(0, "div", 143);
|
|
916
|
+
i0.ɵɵrepeaterCreate(1, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_1_For_2_Template, 10, 1, "div", 144, _forTrack2);
|
|
834
917
|
i0.ɵɵelementEnd();
|
|
835
918
|
} if (rf & 2) {
|
|
836
919
|
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
837
920
|
i0.ɵɵadvance();
|
|
838
921
|
i0.ɵɵrepeater(ctx_r2.queryPermissions);
|
|
839
922
|
} }
|
|
840
|
-
function
|
|
841
|
-
i0.ɵɵconditionalCreate(0,
|
|
923
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
924
|
+
i0.ɵɵconditionalCreate(0, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_0_Template, 1, 4, "mj-explorer-entity-data-grid", 142)(1, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Conditional_1_Template, 3, 0, "div", 143);
|
|
842
925
|
} if (rf & 2) {
|
|
843
926
|
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
844
927
|
i0.ɵɵconditional(ctx_r2.EditMode ? 0 : 1);
|
|
845
928
|
} }
|
|
846
|
-
function
|
|
847
|
-
i0.ɵɵconditionalCreate(0,
|
|
929
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
930
|
+
i0.ɵɵconditionalCreate(0, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_0_Template, 6, 0, "div", 79)(1, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Conditional_1_Template, 2, 1);
|
|
848
931
|
} if (rf & 2) {
|
|
849
932
|
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
850
933
|
i0.ɵɵconditional(ctx_r2.queryPermissions.length === 0 && !ctx_r2.EditMode ? 0 : 1);
|
|
851
934
|
} }
|
|
852
|
-
function
|
|
853
|
-
const
|
|
935
|
+
function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Template(rf, ctx) { if (rf & 1) {
|
|
936
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
854
937
|
i0.ɵɵelementStart(0, "kendo-expansionpanel", 24);
|
|
855
|
-
i0.ɵɵtwoWayListener("expandedChange", function
|
|
856
|
-
i0.ɵɵtemplate(1,
|
|
938
|
+
i0.ɵɵtwoWayListener("expandedChange", function MJQueryFormComponentExtended_Conditional_1_Conditional_60_Template_kendo_expansionpanel_expandedChange_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.permissionsPanelExpanded, $event) || (ctx_r2.permissionsPanelExpanded = $event); return i0.ɵɵresetView($event); });
|
|
939
|
+
i0.ɵɵtemplate(1, MJQueryFormComponentExtended_Conditional_1_Conditional_60_ng_template_1_Template, 3, 0, "ng-template", 25);
|
|
857
940
|
i0.ɵɵelementStart(2, "div", 30);
|
|
858
|
-
i0.ɵɵconditionalCreate(3,
|
|
941
|
+
i0.ɵɵconditionalCreate(3, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_3_Template, 2, 0, "div", 75)(4, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Conditional_4_Template, 2, 1);
|
|
859
942
|
i0.ɵɵelementEnd()();
|
|
860
943
|
} if (rf & 2) {
|
|
861
944
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -891,53 +974,54 @@ function MJQueryFormComponentExtended_Conditional_1_Template(rf, ctx) { if (rf &
|
|
|
891
974
|
i0.ɵɵtwoWayListener("expandedChange", function MJQueryFormComponentExtended_Conditional_1_Template_kendo_expansionpanel_expandedChange_26_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.sqlPanelExpanded, $event) || (ctx_r2.sqlPanelExpanded = $event); return i0.ɵɵresetView($event); });
|
|
892
975
|
i0.ɵɵtemplate(27, MJQueryFormComponentExtended_Conditional_1_ng_template_27_Template, 10, 2, "ng-template", 25);
|
|
893
976
|
i0.ɵɵelementStart(28, "div", 26)(29, "mj-code-editor", 27, 1);
|
|
894
|
-
i0.ɵɵlistener("change", function MJQueryFormComponentExtended_Conditional_1_Template_mj_code_editor_change_29_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSQLChange($event)); });
|
|
977
|
+
i0.ɵɵlistener("change", function MJQueryFormComponentExtended_Conditional_1_Template_mj_code_editor_change_29_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSQLChange($event)); })("CompositionTokenClick", function MJQueryFormComponentExtended_Conditional_1_Template_mj_code_editor_CompositionTokenClick_29_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCompositionTokenClick($event)); });
|
|
895
978
|
i0.ɵɵelementEnd();
|
|
896
979
|
i0.ɵɵconditionalCreate(31, MJQueryFormComponentExtended_Conditional_1_Conditional_31_Template, 7, 0, "div", 28);
|
|
897
980
|
i0.ɵɵelementEnd()();
|
|
898
981
|
i0.ɵɵconditionalCreate(32, MJQueryFormComponentExtended_Conditional_1_Conditional_32_Template, 5, 2, "kendo-expansionpanel", 29);
|
|
899
982
|
i0.ɵɵconditionalCreate(33, MJQueryFormComponentExtended_Conditional_1_Conditional_33_Template, 5, 2, "kendo-expansionpanel", 29);
|
|
900
983
|
i0.ɵɵconditionalCreate(34, MJQueryFormComponentExtended_Conditional_1_Conditional_34_Template, 5, 2, "kendo-expansionpanel", 29);
|
|
901
|
-
i0.ɵɵconditionalCreate(35, MJQueryFormComponentExtended_Conditional_1_Conditional_35_Template,
|
|
902
|
-
i0.ɵɵ
|
|
903
|
-
i0.ɵɵ
|
|
904
|
-
i0.ɵɵ
|
|
905
|
-
i0.ɵɵ
|
|
906
|
-
i0.ɵɵ
|
|
907
|
-
i0.ɵɵ
|
|
908
|
-
i0.ɵɵ
|
|
909
|
-
i0.ɵɵ
|
|
910
|
-
i0.ɵɵ
|
|
911
|
-
i0.ɵɵ
|
|
912
|
-
i0.ɵɵ
|
|
913
|
-
i0.ɵɵ
|
|
914
|
-
i0.ɵɵ
|
|
915
|
-
i0.ɵɵ
|
|
916
|
-
i0.ɵɵ
|
|
984
|
+
i0.ɵɵconditionalCreate(35, MJQueryFormComponentExtended_Conditional_1_Conditional_35_Template, 11, 2, "kendo-expansionpanel", 29);
|
|
985
|
+
i0.ɵɵconditionalCreate(36, MJQueryFormComponentExtended_Conditional_1_Conditional_36_Template, 5, 2, "kendo-expansionpanel", 29);
|
|
986
|
+
i0.ɵɵelementStart(37, "kendo-expansionpanel", 24);
|
|
987
|
+
i0.ɵɵtwoWayListener("expandedChange", function MJQueryFormComponentExtended_Conditional_1_Template_kendo_expansionpanel_expandedChange_37_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.detailsPanelExpanded, $event) || (ctx_r2.detailsPanelExpanded = $event); return i0.ɵɵresetView($event); });
|
|
988
|
+
i0.ɵɵtemplate(38, MJQueryFormComponentExtended_Conditional_1_ng_template_38_Template, 3, 0, "ng-template", 25);
|
|
989
|
+
i0.ɵɵelementStart(39, "div", 30)(40, "div", 31)(41, "div", 32)(42, "label", 33);
|
|
990
|
+
i0.ɵɵelement(43, "i", 34);
|
|
991
|
+
i0.ɵɵtext(44, " Template Usage ");
|
|
992
|
+
i0.ɵɵelementEnd();
|
|
993
|
+
i0.ɵɵconditionalCreate(45, MJQueryFormComponentExtended_Conditional_1_Conditional_45_Template, 1, 1, "kendo-switch", 35)(46, MJQueryFormComponentExtended_Conditional_1_Conditional_46_Template, 3, 1, "div", 36);
|
|
994
|
+
i0.ɵɵelementEnd();
|
|
995
|
+
i0.ɵɵelementStart(47, "div", 32)(48, "label", 33);
|
|
996
|
+
i0.ɵɵelement(49, "i", 37);
|
|
997
|
+
i0.ɵɵtext(50, " Created ");
|
|
998
|
+
i0.ɵɵelementEnd();
|
|
999
|
+
i0.ɵɵelementStart(51, "div", 36);
|
|
1000
|
+
i0.ɵɵtext(52);
|
|
917
1001
|
i0.ɵɵelementEnd()();
|
|
918
|
-
i0.ɵɵelementStart(
|
|
919
|
-
i0.ɵɵelement(
|
|
920
|
-
i0.ɵɵtext(
|
|
1002
|
+
i0.ɵɵelementStart(53, "div", 32)(54, "label", 33);
|
|
1003
|
+
i0.ɵɵelement(55, "i", 38);
|
|
1004
|
+
i0.ɵɵtext(56, " Last Updated ");
|
|
921
1005
|
i0.ɵɵelementEnd();
|
|
922
|
-
i0.ɵɵelementStart(
|
|
923
|
-
i0.ɵɵtext(
|
|
1006
|
+
i0.ɵɵelementStart(57, "div", 36);
|
|
1007
|
+
i0.ɵɵtext(58);
|
|
924
1008
|
i0.ɵɵelementEnd()();
|
|
925
|
-
i0.ɵɵconditionalCreate(
|
|
1009
|
+
i0.ɵɵconditionalCreate(59, MJQueryFormComponentExtended_Conditional_1_Conditional_59_Template, 6, 1, "div", 32);
|
|
926
1010
|
i0.ɵɵelementEnd()()();
|
|
927
|
-
i0.ɵɵconditionalCreate(
|
|
1011
|
+
i0.ɵɵconditionalCreate(60, MJQueryFormComponentExtended_Conditional_1_Conditional_60_Template, 5, 2, "kendo-expansionpanel", 29);
|
|
928
1012
|
i0.ɵɵelementEnd()();
|
|
929
|
-
i0.ɵɵelementStart(
|
|
930
|
-
i0.ɵɵtwoWayListener("isVisibleChange", function
|
|
931
|
-
i0.ɵɵlistener("onClose", function
|
|
1013
|
+
i0.ɵɵelementStart(61, "mj-query-run-dialog", 39);
|
|
1014
|
+
i0.ɵɵtwoWayListener("isVisibleChange", function MJQueryFormComponentExtended_Conditional_1_Template_mj_query_run_dialog_isVisibleChange_61_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.showRunDialog, $event) || (ctx_r2.showRunDialog = $event); return i0.ɵɵresetView($event); });
|
|
1015
|
+
i0.ɵɵlistener("onClose", function MJQueryFormComponentExtended_Conditional_1_Template_mj_query_run_dialog_onClose_61_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRunDialogClose()); });
|
|
932
1016
|
i0.ɵɵelementEnd();
|
|
933
|
-
i0.ɵɵelementStart(
|
|
934
|
-
i0.ɵɵtwoWayListener("isVisibleChange", function
|
|
935
|
-
i0.ɵɵlistener("onCategoryCreated", function
|
|
1017
|
+
i0.ɵɵelementStart(62, "mj-query-category-dialog", 40);
|
|
1018
|
+
i0.ɵɵtwoWayListener("isVisibleChange", function MJQueryFormComponentExtended_Conditional_1_Template_mj_query_category_dialog_isVisibleChange_62_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.showCategoryDialog, $event) || (ctx_r2.showCategoryDialog = $event); return i0.ɵɵresetView($event); });
|
|
1019
|
+
i0.ɵɵlistener("onCategoryCreated", function MJQueryFormComponentExtended_Conditional_1_Template_mj_query_category_dialog_onCategoryCreated_62_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCategoryCreated($event)); });
|
|
936
1020
|
i0.ɵɵelementEnd();
|
|
937
1021
|
} if (rf & 2) {
|
|
938
1022
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
939
1023
|
i0.ɵɵadvance(2);
|
|
940
|
-
i0.ɵɵproperty("Form", ctx_r2);
|
|
1024
|
+
i0.ɵɵproperty("Form", ctx_r2)("Config", ctx_r2.ToolbarConfig);
|
|
941
1025
|
i0.ɵɵadvance(6);
|
|
942
1026
|
i0.ɵɵconditional(ctx_r2.EditMode ? 8 : 9);
|
|
943
1027
|
i0.ɵɵadvance(3);
|
|
@@ -963,19 +1047,21 @@ function MJQueryFormComponentExtended_Conditional_1_Template(rf, ctx) { if (rf &
|
|
|
963
1047
|
i0.ɵɵadvance();
|
|
964
1048
|
i0.ɵɵconditional(ctx_r2.record.IsSaved ? 34 : -1);
|
|
965
1049
|
i0.ɵɵadvance();
|
|
966
|
-
i0.ɵɵconditional(ctx_r2.record.IsSaved ? 35 : -1);
|
|
1050
|
+
i0.ɵɵconditional(ctx_r2.record.IsSaved && ctx_r2.DependentQueries.length > 0 ? 35 : -1);
|
|
1051
|
+
i0.ɵɵadvance();
|
|
1052
|
+
i0.ɵɵconditional(ctx_r2.record.IsSaved ? 36 : -1);
|
|
967
1053
|
i0.ɵɵadvance();
|
|
968
1054
|
i0.ɵɵtwoWayProperty("expanded", ctx_r2.detailsPanelExpanded);
|
|
969
1055
|
i0.ɵɵadvance(8);
|
|
970
|
-
i0.ɵɵconditional(ctx_r2.EditMode ?
|
|
1056
|
+
i0.ɵɵconditional(ctx_r2.EditMode ? 45 : 46);
|
|
971
1057
|
i0.ɵɵadvance(7);
|
|
972
1058
|
i0.ɵɵtextInterpolate(ctx_r2.formatDate(ctx_r2.record.__mj_CreatedAt));
|
|
973
1059
|
i0.ɵɵadvance(6);
|
|
974
1060
|
i0.ɵɵtextInterpolate(ctx_r2.formatDate(ctx_r2.record.__mj_UpdatedAt));
|
|
975
1061
|
i0.ɵɵadvance();
|
|
976
|
-
i0.ɵɵconditional(ctx_r2.record.QualityRank != null ?
|
|
1062
|
+
i0.ɵɵconditional(ctx_r2.record.QualityRank != null ? 59 : -1);
|
|
977
1063
|
i0.ɵɵadvance();
|
|
978
|
-
i0.ɵɵconditional(ctx_r2.record.IsSaved ?
|
|
1064
|
+
i0.ɵɵconditional(ctx_r2.record.IsSaved ? 60 : -1);
|
|
979
1065
|
i0.ɵɵadvance();
|
|
980
1066
|
i0.ɵɵproperty("query", ctx_r2.record)("parameters", ctx_r2.queryParameters);
|
|
981
1067
|
i0.ɵɵtwoWayProperty("isVisible", ctx_r2.showRunDialog);
|
|
@@ -997,6 +1083,7 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
997
1083
|
this.showFiltersHelp = false;
|
|
998
1084
|
this.showRunDialog = false;
|
|
999
1085
|
this.showCategoryDialog = false;
|
|
1086
|
+
this.categoryPathDisplay = '';
|
|
1000
1087
|
// Expansion panel states
|
|
1001
1088
|
this.sqlPanelExpanded = true;
|
|
1002
1089
|
this.parametersPanelExpanded = false;
|
|
@@ -1005,6 +1092,7 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1005
1092
|
this.technicalDescriptionPanelExpanded = false;
|
|
1006
1093
|
this.detailsPanelExpanded = false;
|
|
1007
1094
|
this.permissionsPanelExpanded = false;
|
|
1095
|
+
this.dependentsPanelExpanded = false;
|
|
1008
1096
|
// Category data
|
|
1009
1097
|
this.categoryOptions = [
|
|
1010
1098
|
{ text: 'Select Category...', value: '' }
|
|
@@ -1018,13 +1106,41 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1018
1106
|
{ text: 'Rejected', value: 'Rejected' },
|
|
1019
1107
|
{ text: 'Expired', value: 'Expired' }
|
|
1020
1108
|
];
|
|
1109
|
+
// Toolbar config: hide non-functional buttons (delete/favorite/history are not wired
|
|
1110
|
+
// in legacy [Form] mode) and section controls (custom form uses its own panel state).
|
|
1111
|
+
this.ToolbarConfig = {
|
|
1112
|
+
...DEFAULT_TOOLBAR_CONFIG,
|
|
1113
|
+
ShowDeleteButton: false,
|
|
1114
|
+
ShowFavoriteButton: false,
|
|
1115
|
+
ShowHistoryButton: false,
|
|
1116
|
+
ShowListButton: false,
|
|
1117
|
+
ShowSectionControls: false,
|
|
1118
|
+
ShowSectionFilter: false,
|
|
1119
|
+
AllowSectionReorder: false,
|
|
1120
|
+
ShowSectionManager: false,
|
|
1121
|
+
};
|
|
1021
1122
|
this.sqlEditor = null;
|
|
1022
1123
|
// SQL Filters for help display
|
|
1023
1124
|
this.sqlFilters = RUN_QUERY_SQL_FILTERS;
|
|
1125
|
+
this.navigationService = inject(NavigationService);
|
|
1024
1126
|
this.destroy$ = new Subject();
|
|
1025
1127
|
this.isUpdatingEditorValue = false;
|
|
1026
1128
|
this.isInitialLoad = true;
|
|
1027
1129
|
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Gets the QueryInfo metadata object for the current record, used to access Dependents.
|
|
1132
|
+
*/
|
|
1133
|
+
get CurrentQueryInfo() {
|
|
1134
|
+
if (!this.record?.ID)
|
|
1135
|
+
return undefined;
|
|
1136
|
+
return Metadata.Provider.Queries.find(q => UUIDsEqual(q.ID, this.record.ID));
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Gets queries that depend on (reference) this query via composition.
|
|
1140
|
+
*/
|
|
1141
|
+
get DependentQueries() {
|
|
1142
|
+
return this.CurrentQueryInfo?.Dependents ?? [];
|
|
1143
|
+
}
|
|
1028
1144
|
async ngOnInit() {
|
|
1029
1145
|
await super.ngOnInit();
|
|
1030
1146
|
// During init, suppress per-method detectChanges to avoid NG0100.
|
|
@@ -1210,6 +1326,8 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1210
1326
|
];
|
|
1211
1327
|
// Build tree data after options are set
|
|
1212
1328
|
this.categoryTreeData = this.buildCategoryTree(this.categories);
|
|
1329
|
+
// Update cached category path display
|
|
1330
|
+
this.updateCategoryPathDisplay();
|
|
1213
1331
|
// Trigger change detection to update the view (skip during init)
|
|
1214
1332
|
if (!this.isInitialLoad)
|
|
1215
1333
|
this.cdr.detectChanges();
|
|
@@ -1258,7 +1376,7 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1258
1376
|
return rootCategories;
|
|
1259
1377
|
}
|
|
1260
1378
|
getCategoryPath() {
|
|
1261
|
-
if (!this.record
|
|
1379
|
+
if (!this.record?.CategoryID)
|
|
1262
1380
|
return '';
|
|
1263
1381
|
const findPath = (categoryId) => {
|
|
1264
1382
|
const category = this.categories.find(c => UUIDsEqual(c.ID, categoryId));
|
|
@@ -1271,6 +1389,9 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1271
1389
|
};
|
|
1272
1390
|
return findPath(this.record.CategoryID).join(' / ');
|
|
1273
1391
|
}
|
|
1392
|
+
updateCategoryPathDisplay() {
|
|
1393
|
+
this.categoryPathDisplay = this.getCategoryPath();
|
|
1394
|
+
}
|
|
1274
1395
|
async onCategoryChange(value) {
|
|
1275
1396
|
// If it's a new category (string but not in existing options)
|
|
1276
1397
|
if (value && !this.categoryOptions.find(opt => opt.value === value)) {
|
|
@@ -1493,6 +1614,7 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1493
1614
|
this.loadQueryFields(),
|
|
1494
1615
|
this.loadQueryEntities()
|
|
1495
1616
|
]);
|
|
1617
|
+
this.updateCategoryPathDisplay();
|
|
1496
1618
|
this.cdr.detectChanges();
|
|
1497
1619
|
}
|
|
1498
1620
|
}
|
|
@@ -1523,6 +1645,44 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1523
1645
|
default: return '';
|
|
1524
1646
|
}
|
|
1525
1647
|
}
|
|
1648
|
+
/**
|
|
1649
|
+
* Handle composition token click — navigate to the referenced query
|
|
1650
|
+
*/
|
|
1651
|
+
onCompositionTokenClick(event) {
|
|
1652
|
+
const md = new Metadata();
|
|
1653
|
+
const segments = event.FullPath.split('/').map(s => s.trim()).filter(s => s.length > 0);
|
|
1654
|
+
if (segments.length === 0)
|
|
1655
|
+
return;
|
|
1656
|
+
const queryName = segments[segments.length - 1];
|
|
1657
|
+
const categorySegments = segments.slice(0, -1);
|
|
1658
|
+
// First try: exact match on Name + CategoryPath
|
|
1659
|
+
let targetQuery = md.Queries.find(q => {
|
|
1660
|
+
if (q.Name !== queryName)
|
|
1661
|
+
return false;
|
|
1662
|
+
if (categorySegments.length === 0)
|
|
1663
|
+
return true;
|
|
1664
|
+
const expectedPath = '/' + categorySegments.join('/') + '/';
|
|
1665
|
+
return q.CategoryPath === expectedPath;
|
|
1666
|
+
});
|
|
1667
|
+
// Fallback: match on Name alone
|
|
1668
|
+
if (!targetQuery) {
|
|
1669
|
+
targetQuery = md.Queries.find(q => q.Name === queryName);
|
|
1670
|
+
}
|
|
1671
|
+
if (targetQuery) {
|
|
1672
|
+
const compositeKey = CompositeKey.FromID(targetQuery.ID);
|
|
1673
|
+
this.navigationService.OpenEntityRecord('MJ: Queries', compositeKey);
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Referenced query "${event.FullPath}" not found.`, 'warning', 3000);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Navigate to a dependent query's record
|
|
1681
|
+
*/
|
|
1682
|
+
onDependentQueryClick(dep) {
|
|
1683
|
+
const compositeKey = CompositeKey.FromID(dep.QueryID);
|
|
1684
|
+
this.navigationService.OpenEntityRecord('MJ: Queries', compositeKey);
|
|
1685
|
+
}
|
|
1526
1686
|
/**
|
|
1527
1687
|
* Handle SQL value changes from the code editor
|
|
1528
1688
|
*/
|
|
@@ -1638,14 +1798,14 @@ let MJQueryFormComponentExtended = class MJQueryFormComponentExtended extends MJ
|
|
|
1638
1798
|
} if (rf & 2) {
|
|
1639
1799
|
let _t;
|
|
1640
1800
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.sqlEditor = _t.first);
|
|
1641
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [["form", "ngForm"], ["sqlEditor", ""], [1, "record-form-container", 2, "height", "100%", "display", "flex", "flex-direction", "column"], [1, "record-form", 2, "display", "flex", "flex-direction", "column", "height", "100%", "overflow", "hidden"], [3, "Form"], [1, "query-header"], [1, "query-header-content"], [1, "query-header-top"], [1, "query-name-section"], [1, "fa-solid", "fa-database", "query-title-icon"], ["name", "queryName", "placeholder", "Enter query name...", 1, "query-name-input", 3, "ngModel"], [1, "query-name-display"], [1, "query-header-actions"], ["kendoButton", "", "title", "Run Query", 1, "run-query-btn", 3, "themeColor", "size", "disabled"], [1, "query-meta-row"], [1, "query-meta-item"], [1, "meta-label"], ["name", "categoryId", "textField", "text", "valueField", "value", "placeholder", "Select category...", 1, "meta-dropdown", 3, "ngModel", "data", "valuePrimitive"], [1, "meta-value"], ["name", "status", "textField", "text", "valueField", "value", 1, "meta-dropdown", "status-dropdown", 3, "ngModel", "data", "valuePrimitive"], [1, "status-pill", 3, "background"], [1, "query-description-row"], [1, "status-warning-banner", 3, "border-left-color"], [1, "query-content"], [1, "query-panel", 3, "expandedChange", "expanded"], ["kendoExpansionPanelTitleDirective", ""], [1, "sql-panel-content"], [1, "sql-editor", 3, "change", "language"], [1, "filters-help"], [1, "query-panel", 3, "expanded"], [1, "panel-body"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "fa-solid", "fa-file-code"], ["name", "usesTemplate", 3, "ngModel"], [1, "detail-value"], [1, "fa-solid", "fa-calendar-plus"], [1, "fa-solid", "fa-calendar-check"], [3, "isVisibleChange", "onClose", "query", "parameters", "isVisible"], [3, "isVisibleChange", "onCategoryCreated", "isVisible"], ["name", "queryName", "placeholder", "Enter query name...", 1, "query-name-input", 3, "ngModelChange", "ngModel"], ["kendoButton", "", "title", "Run Query", 1, "run-query-btn", 3, "click", "themeColor", "size", "disabled"], [1, "fa-solid", "fa-play"], ["name", "categoryId", "textField", "text", "valueField", "value", "placeholder", "Select category...", 1, "meta-dropdown", 3, "ngModelChange", "ngModel", "data", "valuePrimitive"], ["name", "status", "textField", "text", "valueField", "value", 1, "meta-dropdown", "status-dropdown", 3, "ngModelChange", "ngModel", "data", "valuePrimitive"], [1, "status-pill"], [1, "fa-solid"], ["name", "description", "placeholder", "Enter query description...", 1, "query-description-input", 3, "ngModel", "rows"], [1, "query-description-text"], ["name", "description", "placeholder", "Enter query description...", 1, "query-description-input", 3, "ngModelChange", "ngModel", "rows"], [1, "status-warning-banner"], [1, "panel-title-row"], [1, "panel-title"], [1, "fa-solid", "fa-code", "panel-icon", "sql-icon"], [1, "panel-badge", "defined"], ["type", "button", "kendoButton", "", "fillMode", "flat", "size", "small", "title", "Show/hide SQL filters help", 1, "filters-help-btn", 3, "click"], [1, "fa-solid", "fa-question-circle"], [1, "fa-solid", 3, "ngClass"], [1, "fa-solid", "fa-check"], [1, "filters-help-title"], [1, "fa-solid", "fa-filter"], [1, "filters-grid"], [1, "filter-card"], [1, "filter-name"], [1, "filter-description"], [1, "filter-syntax"], [1, "filter-notes"], [1, "technical-description-view"], [1, "fa-solid", "fa-book", "panel-icon"], ["name", "technicalDescription", "placeholder", "Technical documentation of the query logic, performance considerations, and parameter usage. Supports markdown and mermaid diagrams.", 1, "technical-description-textarea", 3, "ngModelChange", "ngModel", "rows"], [1, "technical-description-preview"], [1, "preview-label"], [1, "fa-solid", "fa-eye"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [1, "panel-loading"], [1, "fa-solid", "fa-sliders", "panel-icon"], [1, "panel-badge", "count"], ["text", "Loading parameters..."], [1, "empty-state"], [1, "fa-solid", "fa-sliders", "empty-state-icon"], [1, "empty-state-title"], [1, "empty-state-text"], ["type", "button", 1, "add-item-btn"], ["type", "button", 1, "add-item-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "panel-toolbar"], [1, "card-grid"], [1, "item-card", 3, "required"], [1, "item-card", 3, "click"], [1, "item-card-header"], [1, "item-name"], [1, "fa-solid", "fa-at", "item-name-icon", "param-icon"], [1, "item-badges"], [1, "item-badge", "required"], [1, "item-card-body"], [1, "item-description"], [1, "item-meta"], [1, "meta-tag"], [1, "item-actions"], [1, "meta-code"], [1, "item-actions", 3, "click"], ["type", "button", "title", "Edit parameter", 1, "item-action-btn", 3, "click"], [1, "fa-solid", "fa-pen"], ["type", "button", "title", "Delete parameter", 1, "item-action-btn", "delete", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-table", "panel-icon"], ["text", "Loading fields..."], [1, "fa-solid", "fa-table", "empty-state-icon"], [1, "item-card"], [1, "fa-solid", "fa-columns", "item-name-icon", "field-icon"], [1, "item-badge", "type"], [1, "item-badge", "sequence"], [1, "fa-solid", "fa-code"], [1, "item-card-actions"], ["type", "button", "title", "Delete field", 1, "item-action-btn", "delete", 3, "click"], [1, "fa-solid", "fa-database", "panel-icon"], ["text", "Loading entities..."], [1, "fa-solid", "fa-database", "empty-state-icon"], [1, "fa-solid", "fa-table", "item-name-icon", "entity-icon"], [1, "entity-dropdown-wrapper"], ["textField", "text", "valueField", "id", "placeholder", "Select entity...", 1, "entity-dropdown", 3, "ngModelChange", "ngModel", "name", "data", "valuePrimitive"], [1, "fa-solid", "fa-database"], ["type", "button", "title", "Delete entity", 1, "item-action-btn", "delete", 3, "click"], [1, "fa-solid", "fa-info-circle", "panel-icon"], ["name", "usesTemplate", 3, "ngModelChange", "ngModel"], [1, "detail-tag", "positive"], [1, "detail-tag", "neutral"], [1, "fa-solid", "fa-times"], [1, "fa-solid", "fa-star"], [1, "fa-solid", "fa-shield-alt", "panel-icon"], ["text", "Loading permissions..."], [1, "fa-solid", "fa-shield-alt", "empty-state-icon"], [3, "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"], [1, "permissions-list"], [1, "permission-card"], [1, "fa-solid", "fa-users", "permission-icon"], [1, "permission-info"], [1, "permission-role"], [1, "permission-type"], [1, "permission-badge"]], template: function MJQueryFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
1801
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [["form", "ngForm"], ["sqlEditor", ""], [1, "record-form-container", 2, "height", "100%", "display", "flex", "flex-direction", "column"], [1, "record-form", 2, "display", "flex", "flex-direction", "column", "height", "100%", "overflow", "hidden"], [3, "Form", "Config"], [1, "query-header"], [1, "query-header-content"], [1, "query-header-top"], [1, "query-name-section"], [1, "fa-solid", "fa-database", "query-title-icon"], ["name", "queryName", "placeholder", "Enter query name...", 1, "query-name-input", 3, "ngModel"], [1, "query-name-display"], [1, "query-header-actions"], ["kendoButton", "", "title", "Run Query", 1, "run-query-btn", 3, "themeColor", "size", "disabled"], [1, "query-meta-row"], [1, "query-meta-item"], [1, "meta-label"], ["name", "categoryId", "textField", "text", "valueField", "value", "placeholder", "Select category...", 1, "meta-dropdown", 3, "ngModel", "data", "valuePrimitive"], [1, "meta-value"], ["name", "status", "textField", "text", "valueField", "value", 1, "meta-dropdown", "status-dropdown", 3, "ngModel", "data", "valuePrimitive"], [1, "status-pill", 3, "background"], [1, "query-description-row"], [1, "status-warning-banner", 3, "border-left-color"], [1, "query-content"], [1, "query-panel", 3, "expandedChange", "expanded"], ["kendoExpansionPanelTitleDirective", ""], [1, "sql-panel-content"], [1, "sql-editor", 3, "change", "CompositionTokenClick", "language"], [1, "filters-help"], [1, "query-panel", 3, "expanded"], [1, "panel-body"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "fa-solid", "fa-file-code"], ["name", "usesTemplate", 3, "ngModel"], [1, "detail-value"], [1, "fa-solid", "fa-calendar-plus"], [1, "fa-solid", "fa-calendar-check"], [3, "isVisibleChange", "onClose", "query", "parameters", "isVisible"], [3, "isVisibleChange", "onCategoryCreated", "isVisible"], ["name", "queryName", "placeholder", "Enter query name...", 1, "query-name-input", 3, "ngModelChange", "ngModel"], ["kendoButton", "", "title", "Run Query", 1, "run-query-btn", 3, "click", "themeColor", "size", "disabled"], [1, "fa-solid", "fa-play"], ["name", "categoryId", "textField", "text", "valueField", "value", "placeholder", "Select category...", 1, "meta-dropdown", 3, "ngModelChange", "ngModel", "data", "valuePrimitive"], ["name", "status", "textField", "text", "valueField", "value", 1, "meta-dropdown", "status-dropdown", 3, "ngModelChange", "ngModel", "data", "valuePrimitive"], [1, "status-pill"], [1, "fa-solid"], ["name", "description", "placeholder", "Enter query description...", 1, "query-description-input", 3, "ngModel", "rows"], [1, "query-description-text"], ["name", "description", "placeholder", "Enter query description...", 1, "query-description-input", 3, "ngModelChange", "ngModel", "rows"], [1, "status-warning-banner"], [1, "panel-title-row"], [1, "panel-title"], [1, "fa-solid", "fa-code", "panel-icon", "sql-icon"], [1, "panel-badge", "defined"], ["type", "button", "kendoButton", "", "fillMode", "flat", "size", "small", "title", "Show/hide SQL filters help", 1, "filters-help-btn", 3, "click"], [1, "fa-solid", "fa-question-circle"], [1, "fa-solid", 3, "ngClass"], [1, "fa-solid", "fa-check"], [1, "filters-help-title"], [1, "fa-solid", "fa-filter"], [1, "filters-grid"], [1, "filter-card"], [1, "filter-name"], [1, "filter-description"], [1, "filter-syntax"], [1, "filter-notes"], [1, "technical-description-view"], [1, "fa-solid", "fa-book", "panel-icon"], ["name", "technicalDescription", "placeholder", "Technical documentation of the query logic, performance considerations, and parameter usage. Supports markdown and mermaid diagrams.", 1, "technical-description-textarea", 3, "ngModelChange", "ngModel", "rows"], [1, "technical-description-preview"], [1, "preview-label"], [1, "fa-solid", "fa-eye"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [1, "panel-loading"], [1, "fa-solid", "fa-sliders", "panel-icon"], [1, "panel-badge", "count"], ["text", "Loading parameters..."], [1, "empty-state"], [1, "fa-solid", "fa-sliders", "empty-state-icon"], [1, "empty-state-title"], [1, "empty-state-text"], ["type", "button", 1, "add-item-btn"], ["type", "button", 1, "add-item-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "panel-toolbar"], [1, "card-grid"], [1, "item-card", 3, "required"], [1, "item-card", 3, "click"], [1, "item-card-header"], [1, "item-name"], [1, "fa-solid", "fa-at", "item-name-icon", "param-icon"], [1, "item-badges"], [1, "item-badge", "required"], [1, "item-card-body"], [1, "item-description"], [1, "item-meta"], [1, "meta-tag"], [1, "item-actions"], [1, "meta-code"], [1, "item-actions", 3, "click"], ["type", "button", "title", "Edit parameter", 1, "item-action-btn", 3, "click"], [1, "fa-solid", "fa-pen"], ["type", "button", "title", "Delete parameter", 1, "item-action-btn", "delete", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-table", "panel-icon"], ["text", "Loading fields..."], [1, "fa-solid", "fa-table", "empty-state-icon"], [1, "item-card"], [1, "fa-solid", "fa-columns", "item-name-icon", "field-icon"], [1, "item-badge", "type"], [1, "item-badge", "sequence"], [1, "fa-solid", "fa-code"], [1, "item-card-actions"], ["type", "button", "title", "Delete field", 1, "item-action-btn", "delete", 3, "click"], [1, "dependents-description"], [1, "item-card", "dependent-card"], [1, "fa-solid", "fa-arrow-left", "panel-icon", "dependents-icon"], [1, "item-card", "dependent-card", 3, "click"], [1, "fa-solid", "fa-arrow-left", "item-name-icon", "dependent-query-icon"], [1, "item-card-footer"], [1, "open-link"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-database", "panel-icon"], ["text", "Loading entities..."], [1, "fa-solid", "fa-database", "empty-state-icon"], [1, "fa-solid", "fa-table", "item-name-icon", "entity-icon"], [1, "entity-dropdown-wrapper"], ["textField", "text", "valueField", "id", "placeholder", "Select entity...", 1, "entity-dropdown", 3, "ngModelChange", "ngModel", "name", "data", "valuePrimitive"], [1, "fa-solid", "fa-database"], ["type", "button", "title", "Delete entity", 1, "item-action-btn", "delete", 3, "click"], [1, "fa-solid", "fa-info-circle", "panel-icon"], ["name", "usesTemplate", 3, "ngModelChange", "ngModel"], [1, "detail-tag", "positive"], [1, "detail-tag", "neutral"], [1, "fa-solid", "fa-times"], [1, "fa-solid", "fa-star"], [1, "fa-solid", "fa-shield-alt", "panel-icon"], ["text", "Loading permissions..."], [1, "fa-solid", "fa-shield-alt", "empty-state-icon"], [3, "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"], [1, "permissions-list"], [1, "permission-card"], [1, "fa-solid", "fa-users", "permission-icon"], [1, "permission-info"], [1, "permission-role"], [1, "permission-type"], [1, "permission-badge"]], template: function MJQueryFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
1642
1802
|
i0.ɵɵelementStart(0, "div", 2);
|
|
1643
|
-
i0.ɵɵconditionalCreate(1, MJQueryFormComponentExtended_Conditional_1_Template,
|
|
1803
|
+
i0.ɵɵconditionalCreate(1, MJQueryFormComponentExtended_Conditional_1_Template, 63, 26);
|
|
1644
1804
|
i0.ɵɵelementEnd();
|
|
1645
1805
|
} if (rf & 2) {
|
|
1646
1806
|
i0.ɵɵadvance();
|
|
1647
1807
|
i0.ɵɵconditional(ctx.record ? 1 : -1);
|
|
1648
|
-
} }, dependencies: [i1.NgClass, i2.ɵNgNoValidate, i2.NgControlStatus, i2.NgControlStatusGroup, i2.NgModel, i2.NgForm, i3.ExpansionPanelComponent, i3.ExpansionPanelTitleDirective, i4.TextBoxComponent, i4.TextAreaComponent, i4.SwitchComponent, i5.DropDownListComponent, i6.ButtonComponent, i7.MjFormToolbarComponent, i7.ExplorerEntityDataGridComponent, i8.CodeEditorComponent, i9.LoadingComponent, i10.MarkdownComponent, i11.QueryRunDialogComponent, i12.QueryCategoryDialogComponent], styles: [".k-pane[_ngcontent-%COMP%] {\n background-color: #F5F6FA;\n}\n\n.content-margin[_ngcontent-%COMP%] {\n margin: 10px;\n} \n\n\na[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: bolder;\n}\n\n.tab-header-icon[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.record-form[_ngcontent-%COMP%] {\n display: block;\n flex-direction: column;\n background-color: #F5F6FA;\n padding: 0;\n min-height: 100vh;\n}\n\n.record-form-group[_ngcontent-%COMP%] {\n margin-top: 0px;\n background-color: #F5F6FA;\n}\n\nbutton[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.record-form[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin-bottom: 10px;\n}\n\n.k-splitter[_ngcontent-%COMP%] {\n border-width: 0px;\n}\n\n.record-form-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n.record-form[_ngcontent-%COMP%] .record-form-row[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:first-child {\n font-weight: bold;\n padding-right: 10px;\n} \n\n.record-form[_ngcontent-%COMP%] .record-form-row[_ngcontent-%COMP%] > span[_ngcontent-%COMP%] {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n \n\n@media (min-width: 768px) {\n .record-form-row[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .record-form-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n width: 240px;\n margin-bottom: 0;\n }\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n background-color: #F5F6FA;\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] > .form-card[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] .related-entity-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr;\n gap: 16px;\n width: 100%;\n}\n\n\n\n@media (min-width: 1400px) {\n .form-panels-container[_ngcontent-%COMP%] .related-entity-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));\n }\n}\n\n.form-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n}\n\n.collapsible-card[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.collapsible-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.collapsible-header[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #f3f4f6 0%, #f9fafb 100%);\n border-bottom-color: #667eea;\n}\n\n.collapsible-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.collapsible-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #667eea;\n}\n\n.collapsible-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.collapsible-header[_ngcontent-%COMP%] .collapse-icon[_ngcontent-%COMP%] {\n color: #6b7280;\n transition: transform 0.3s ease;\n}\n\n.collapsible-body[_ngcontent-%COMP%] {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.collapsible-body.collapsed[_ngcontent-%COMP%] {\n max-height: 0;\n padding: 0;\n opacity: 0;\n}\n\n.form-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.form-card.related-entity[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%);\n border-left: 3px solid #3b82f6;\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-header[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #e0f2fe 0%, #f0f9ff 100%);\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-header[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #bfdbfe 0%, #e0f2fe 100%);\n border-bottom-color: #3b82f6;\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.form-section-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 14px 18px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n align-items: center;\n flex-wrap: wrap;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.form-section-controls[_ngcontent-%COMP%] .control-group[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n background: white;\n color: #374151;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n margin-right: 0;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: #667eea;\n color: white;\n border-color: #667eea;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 0;\n font-size: 14px;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n width: 240px;\n transition: all 0.2s;\n background: white;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%]::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6b7280;\n margin-left: auto;\n font-weight: 500;\n}\n\n\n\n.form-card.search-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.section-count-badge[_ngcontent-%COMP%] {\n background: #667eea;\n color: white;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] .search-highlight[_ngcontent-%COMP%] {\n background-color: #fef08a;\n color: #854d0e;\n padding: 2px 4px;\n border-radius: 3px;\n font-weight: 700;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] .row-count-badge[_ngcontent-%COMP%] {\n background: #10b981;\n color: white;\n padding: 3px 6px 2px 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n vertical-align: middle;\n position: relative;\n top: -2px;\n display: inline-block;\n line-height: 1;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] .row-count-badge.zero-rows[_ngcontent-%COMP%] {\n background: #9ca3af;\n}", "\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n\n\n.record-form[_ngcontent-%COMP%] {\n min-height: 0 !important;\n}\n\n\n\n\n\n\n.query-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n border-bottom: none;\n padding: 0;\n}\n\n.query-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px 20px;\n}\n\n.query-header-top[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.query-name-section[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-title-icon[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.85);\n font-size: 1.3em;\n flex-shrink: 0;\n}\n\n.query-name-input[_ngcontent-%COMP%] {\n font-size: 1.2em;\n font-weight: 600;\n min-width: 300px;\n flex: 1;\n}\n\n.query-name-display[_ngcontent-%COMP%] {\n margin: 0;\n color: #fff;\n font-weight: 600;\n font-size: 1.2em;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.run-query-btn[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n\n.query-meta-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.query-meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-weight: 500;\n color: rgba(255, 255, 255, 0.75);\n font-size: 13px;\n min-width: 60px;\n}\n\n.meta-value[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.95);\n font-size: 14px;\n}\n\n.meta-dropdown[_ngcontent-%COMP%] {\n min-width: 200px;\n}\n\n.status-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.query-description-row[_ngcontent-%COMP%] {\n margin-top: 2px;\n}\n\n.query-description-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.query-description-text[_ngcontent-%COMP%] {\n margin: 0;\n color: rgba(255, 255, 255, 0.8);\n font-size: 13px;\n line-height: 1.4;\n}\n\n\n\n\n\n\n.status-warning-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px;\n margin: 0;\n background: #fff8e1;\n border-left: 4px solid #f59e0b;\n font-size: 13px;\n color: #5d4037;\n flex-shrink: 0;\n}\n\n.status-warning-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.status-warning-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n\n\n\n.query-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n padding: 16px;\n overflow-y: auto;\n background: #f5f5f5;\n}\n\n\n\n\n\n\n.query-panel[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n .query-content kendo-expansionpanel {\n border: none !important;\n border-radius: 8px !important;\n margin-bottom: 12px !important;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important;\n background: white !important;\n overflow: hidden !important;\n}\n\n .query-content .k-expander-header {\n background: white !important;\n border: none !important;\n padding: 14px 18px !important;\n border-radius: 8px !important;\n color: #333 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n transition: background 0.15s ease !important;\n}\n\n .query-content .k-expander-header:hover {\n background: #f8f9fa !important;\n}\n\n .query-content kendo-expansionpanel[aria-expanded=\"true\"] .k-expander-header {\n background: #5c6bc0 !important;\n color: white !important;\n border-radius: 8px 8px 0 0 !important;\n}\n\n .query-content .k-expander-content {\n padding: 0 !important;\n border: none !important;\n background: white !important;\n border-radius: 0 0 8px 8px !important;\n}\n\n\n\n\n\n\n.panel-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.panel-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n opacity: 0.7;\n}\n\n.sql-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-icon {\n color: rgba(255, 255, 255, 0.85) !important;\n opacity: 1;\n}\n\n.panel-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.panel-badge.defined[_ngcontent-%COMP%] {\n background: #28a745;\n color: white;\n}\n\n.panel-badge.count[_ngcontent-%COMP%] {\n background: #5c6bc0;\n color: white;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.count {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.defined {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.filters-help-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n font-size: 12px;\n}\n\n\n\n\n\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 16px 0;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n padding: 0 20px 12px;\n}\n\n\n\n\n\n\n.sql-panel-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.sql-editor[_ngcontent-%COMP%] {\n flex: 1;\n height: 400px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n margin: 16px;\n}\n\n\n\n.filters-help[_ngcontent-%COMP%] {\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 16px;\n margin: 0 16px 16px;\n}\n\n.filters-help-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: #333;\n font-weight: 600;\n font-size: 14px;\n}\n\n.filters-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 10px;\n}\n\n.filter-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 12px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.filter-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-name[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-weight: bold;\n color: #5c6bc0;\n margin-bottom: 4px;\n}\n\n.filter-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #555;\n margin-bottom: 6px;\n}\n\n.filter-syntax[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-size: 11px;\n background: #f5f5f5;\n padding: 6px;\n border-radius: 4px;\n margin-bottom: 4px;\n}\n\n.filter-notes[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n font-style: italic;\n}\n\n\n\n\n\n\n.card-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 12px;\n padding: 0 20px 20px;\n}\n\n.item-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px;\n transition: all 0.15s ease;\n cursor: pointer;\n position: relative;\n}\n\n.item-card[_ngcontent-%COMP%]:hover {\n border-color: #5c6bc0;\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.12);\n}\n\n.item-card.required[_ngcontent-%COMP%] {\n border-left: 3px solid #f59e0b;\n}\n\n.item-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 10px;\n}\n\n.item-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.item-name-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.item-name-icon.param-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n.item-name-icon.field-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n.item-name-icon.entity-icon[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.item-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.item-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n color: white;\n}\n\n.item-badge.required[_ngcontent-%COMP%] {\n background: #f59e0b;\n}\n\n.item-badge.type[_ngcontent-%COMP%] {\n background: #e8eaf6;\n color: #3949ab;\n}\n\n.item-badge.sequence[_ngcontent-%COMP%] {\n background: #f3e5f5;\n color: #7b1fa2;\n}\n\n.item-card-body[_ngcontent-%COMP%] {\n color: #666;\n font-size: 13px;\n}\n\n.item-description[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.item-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n}\n\n.meta-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-code[_ngcontent-%COMP%] {\n background: #f5f5f5;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 11px;\n}\n\n\n\n.item-actions[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.item-card[_ngcontent-%COMP%]:hover .item-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.item-card-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-top: 8px;\n}\n\n.item-action-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n color: #888;\n transition: all 0.15s ease;\n}\n\n.item-action-btn[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n color: #5c6bc0;\n}\n\n.item-action-btn.delete[_ngcontent-%COMP%]:hover {\n background: #fff5f5;\n color: #dc3545;\n}\n\n\n\n.entity-dropdown-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n margin-left: 12px;\n}\n\n.entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n\n\n\n\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n padding: 16px 20px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #888;\n display: flex;\n align-items: center;\n gap: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n}\n\n.detail-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n}\n\n.detail-tag.positive[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.detail-tag.neutral[_ngcontent-%COMP%] {\n color: #888;\n}\n\n\n\n\n\n\n.permissions-list[_ngcontent-%COMP%] {\n padding: 0 20px;\n}\n\n.permission-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px 16px;\n margin-bottom: 8px;\n}\n\n.permission-icon[_ngcontent-%COMP%] {\n font-size: 1.3em;\n color: #5c6bc0;\n}\n\n.permission-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.permission-role[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #333;\n font-size: 14px;\n}\n\n.permission-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: #5c6bc0;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 20px;\n text-align: center;\n color: #888;\n}\n\n.empty-state-icon[_ngcontent-%COMP%] {\n font-size: 40px;\n margin-bottom: 14px;\n opacity: 0.25;\n color: #333;\n}\n\n.empty-state-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 6px;\n color: #555;\n}\n\n.empty-state-text[_ngcontent-%COMP%] {\n font-size: 13px;\n margin-bottom: 16px;\n color: #888;\n}\n\n\n\n\n\n\n.add-item-btn[_ngcontent-%COMP%] {\n background: #5c6bc0;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n font-size: 13px;\n}\n\n.add-item-btn[_ngcontent-%COMP%]:hover {\n background: #3949ab;\n box-shadow: 0 2px 6px rgba(92, 107, 192, 0.3);\n}\n\n\n\n\n\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n\n\n\n\n\n.technical-description-textarea[_ngcontent-%COMP%] {\n width: 100%;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n}\n\n.technical-description-preview[_ngcontent-%COMP%] {\n margin-top: 16px;\n border-top: 1px solid #e0e0e0;\n padding-top: 12px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.technical-description-view[_ngcontent-%COMP%] {\n max-height: 500px;\n overflow-y: auto;\n padding: 12px 16px;\n}"] }); }
|
|
1808
|
+
} }, dependencies: [i1.NgClass, i2.ɵNgNoValidate, i2.NgControlStatus, i2.NgControlStatusGroup, i2.NgModel, i2.NgForm, i3.ExpansionPanelComponent, i3.ExpansionPanelTitleDirective, i4.TextBoxComponent, i4.TextAreaComponent, i4.SwitchComponent, i5.DropDownListComponent, i6.ButtonComponent, i7.MjFormToolbarComponent, i7.ExplorerEntityDataGridComponent, i8.CodeEditorComponent, i9.LoadingComponent, i10.MarkdownComponent, i11.QueryRunDialogComponent, i12.QueryCategoryDialogComponent], styles: [".k-pane[_ngcontent-%COMP%] {\n background-color: #F5F6FA;\n}\n\n.content-margin[_ngcontent-%COMP%] {\n margin: 10px;\n} \n\n\na[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: bolder;\n}\n\n.tab-header-icon[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.record-form[_ngcontent-%COMP%] {\n display: block;\n flex-direction: column;\n background-color: #F5F6FA;\n padding: 0;\n min-height: 100vh;\n}\n\n.record-form-group[_ngcontent-%COMP%] {\n margin-top: 0px;\n background-color: #F5F6FA;\n}\n\nbutton[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.record-form[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin-bottom: 10px;\n}\n\n.k-splitter[_ngcontent-%COMP%] {\n border-width: 0px;\n}\n\n.record-form-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n.record-form[_ngcontent-%COMP%] .record-form-row[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:first-child {\n font-weight: bold;\n padding-right: 10px;\n} \n\n.record-form[_ngcontent-%COMP%] .record-form-row[_ngcontent-%COMP%] > span[_ngcontent-%COMP%] {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n \n\n@media (min-width: 768px) {\n .record-form-row[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n }\n\n .record-form-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n width: 240px;\n margin-bottom: 0;\n }\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n background-color: #F5F6FA;\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] > .form-card[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n\n\n.form-panels-container[_ngcontent-%COMP%] .related-entity-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr;\n gap: 16px;\n width: 100%;\n}\n\n\n\n@media (min-width: 1400px) {\n .form-panels-container[_ngcontent-%COMP%] .related-entity-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));\n }\n}\n\n.form-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n}\n\n.collapsible-card[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.collapsible-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.collapsible-header[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #f3f4f6 0%, #f9fafb 100%);\n border-bottom-color: #667eea;\n}\n\n.collapsible-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.collapsible-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #667eea;\n}\n\n.collapsible-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.collapsible-header[_ngcontent-%COMP%] .collapse-icon[_ngcontent-%COMP%] {\n color: #6b7280;\n transition: transform 0.3s ease;\n}\n\n.collapsible-body[_ngcontent-%COMP%] {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.collapsible-body.collapsed[_ngcontent-%COMP%] {\n max-height: 0;\n padding: 0;\n opacity: 0;\n}\n\n.form-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n\n.form-card.related-entity[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%);\n border-left: 3px solid #3b82f6;\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-header[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #e0f2fe 0%, #f0f9ff 100%);\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-header[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #bfdbfe 0%, #e0f2fe 100%);\n border-bottom-color: #3b82f6;\n}\n\n.form-card.related-entity[_ngcontent-%COMP%] .collapsible-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.form-section-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 14px 18px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n align-items: center;\n flex-wrap: wrap;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.form-section-controls[_ngcontent-%COMP%] .control-group[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n background: white;\n color: #374151;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n margin-right: 0;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: #667eea;\n color: white;\n border-color: #667eea;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n\n.form-section-controls[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 0;\n font-size: 14px;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n width: 240px;\n transition: all 0.2s;\n background: white;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-search[_ngcontent-%COMP%]::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n.form-section-controls[_ngcontent-%COMP%] .section-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6b7280;\n margin-left: auto;\n font-weight: 500;\n}\n\n\n\n.form-card.search-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.section-count-badge[_ngcontent-%COMP%] {\n background: #667eea;\n color: white;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] .search-highlight[_ngcontent-%COMP%] {\n background-color: #fef08a;\n color: #854d0e;\n padding: 2px 4px;\n border-radius: 3px;\n font-weight: 700;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] .row-count-badge[_ngcontent-%COMP%] {\n background: #10b981;\n color: white;\n padding: 3px 6px 2px 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n vertical-align: middle;\n position: relative;\n top: -2px;\n display: inline-block;\n line-height: 1;\n}\n\n\n\n.collapsible-title[_ngcontent-%COMP%] .row-count-badge.zero-rows[_ngcontent-%COMP%] {\n background: #9ca3af;\n}", "\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n\n\n.record-form[_ngcontent-%COMP%] {\n min-height: 0 !important;\n}\n\n\n\n\n\n\n.query-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n border-bottom: none;\n padding: 0;\n}\n\n.query-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px 20px;\n}\n\n.query-header-top[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.query-name-section[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-title-icon[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.85);\n font-size: 1.3em;\n flex-shrink: 0;\n}\n\n.query-name-input[_ngcontent-%COMP%] {\n font-size: 1.2em;\n font-weight: 600;\n min-width: 300px;\n flex: 1;\n}\n\n.query-name-display[_ngcontent-%COMP%] {\n margin: 0;\n color: #fff;\n font-weight: 600;\n font-size: 1.2em;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.run-query-btn[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n\n.query-meta-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.query-meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-weight: 500;\n color: rgba(255, 255, 255, 0.75);\n font-size: 13px;\n min-width: 60px;\n}\n\n.meta-value[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.95);\n font-size: 14px;\n}\n\n.meta-dropdown[_ngcontent-%COMP%] {\n min-width: 200px;\n}\n\n.status-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.query-description-row[_ngcontent-%COMP%] {\n margin-top: 2px;\n}\n\n.query-description-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.query-description-text[_ngcontent-%COMP%] {\n margin: 0;\n color: rgba(255, 255, 255, 0.8);\n font-size: 13px;\n line-height: 1.4;\n}\n\n\n\n\n\n\n.status-warning-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px;\n margin: 0;\n background: #fff8e1;\n border-left: 4px solid #f59e0b;\n font-size: 13px;\n color: #5d4037;\n flex-shrink: 0;\n}\n\n.status-warning-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.status-warning-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n\n\n\n.query-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n padding: 16px;\n overflow-y: auto;\n background: #f5f5f5;\n}\n\n\n\n\n\n\n.query-panel[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n .query-content kendo-expansionpanel {\n border: none !important;\n border-radius: 8px !important;\n margin-bottom: 12px !important;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important;\n background: white !important;\n overflow: hidden !important;\n}\n\n .query-content .k-expander-header {\n background: white !important;\n border: none !important;\n padding: 14px 18px !important;\n border-radius: 8px !important;\n color: #333 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n transition: background 0.15s ease !important;\n}\n\n .query-content .k-expander-header:hover {\n background: #f8f9fa !important;\n}\n\n .query-content kendo-expansionpanel[aria-expanded=\"true\"] .k-expander-header {\n background: #5c6bc0 !important;\n color: white !important;\n border-radius: 8px 8px 0 0 !important;\n}\n\n .query-content .k-expander-content {\n padding: 0 !important;\n border: none !important;\n background: white !important;\n border-radius: 0 0 8px 8px !important;\n}\n\n\n\n\n\n\n.panel-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.panel-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n opacity: 0.7;\n}\n\n.sql-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-icon {\n color: rgba(255, 255, 255, 0.85) !important;\n opacity: 1;\n}\n\n.panel-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.panel-badge.defined[_ngcontent-%COMP%] {\n background: #28a745;\n color: white;\n}\n\n.panel-badge.count[_ngcontent-%COMP%] {\n background: #5c6bc0;\n color: white;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.count {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.defined {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.filters-help-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n font-size: 12px;\n}\n\n\n\n\n\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 16px 0;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n padding: 0 20px 12px;\n}\n\n\n\n\n\n\n.sql-panel-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.sql-editor[_ngcontent-%COMP%] {\n flex: 1;\n height: 400px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n margin: 16px;\n}\n\n\n\n.filters-help[_ngcontent-%COMP%] {\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 16px;\n margin: 0 16px 16px;\n}\n\n.filters-help-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: #333;\n font-weight: 600;\n font-size: 14px;\n}\n\n.filters-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 10px;\n}\n\n.filter-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 12px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.filter-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-name[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-weight: bold;\n color: #5c6bc0;\n margin-bottom: 4px;\n}\n\n.filter-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #555;\n margin-bottom: 6px;\n}\n\n.filter-syntax[_ngcontent-%COMP%] {\n font-family: 'Courier New', monospace;\n font-size: 11px;\n background: #f5f5f5;\n padding: 6px;\n border-radius: 4px;\n margin-bottom: 4px;\n}\n\n.filter-notes[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n font-style: italic;\n}\n\n\n\n\n\n\n.card-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 12px;\n padding: 0 20px 20px;\n}\n\n.item-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px;\n transition: all 0.15s ease;\n cursor: pointer;\n position: relative;\n}\n\n.item-card[_ngcontent-%COMP%]:hover {\n border-color: #5c6bc0;\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.12);\n}\n\n.item-card.required[_ngcontent-%COMP%] {\n border-left: 3px solid #f59e0b;\n}\n\n.item-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 10px;\n}\n\n.item-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.item-name-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.item-name-icon.param-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n.item-name-icon.field-icon[_ngcontent-%COMP%] {\n color: #5c6bc0;\n}\n\n.item-name-icon.entity-icon[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.item-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.item-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n color: white;\n}\n\n.item-badge.required[_ngcontent-%COMP%] {\n background: #f59e0b;\n}\n\n.item-badge.type[_ngcontent-%COMP%] {\n background: #e8eaf6;\n color: #3949ab;\n}\n\n.item-badge.sequence[_ngcontent-%COMP%] {\n background: #f3e5f5;\n color: #7b1fa2;\n}\n\n.item-card-body[_ngcontent-%COMP%] {\n color: #666;\n font-size: 13px;\n}\n\n.item-description[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.item-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n}\n\n.meta-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-code[_ngcontent-%COMP%] {\n background: #f5f5f5;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 11px;\n}\n\n\n\n.item-actions[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.item-card[_ngcontent-%COMP%]:hover .item-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.item-card-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-top: 8px;\n}\n\n.item-action-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n color: #888;\n transition: all 0.15s ease;\n}\n\n.item-action-btn[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n color: #5c6bc0;\n}\n\n.item-action-btn.delete[_ngcontent-%COMP%]:hover {\n background: #fff5f5;\n color: #dc3545;\n}\n\n\n\n.entity-dropdown-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n margin-left: 12px;\n}\n\n.entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n\n\n\n\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n padding: 16px 20px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #888;\n display: flex;\n align-items: center;\n gap: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n}\n\n.detail-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n}\n\n.detail-tag.positive[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.detail-tag.neutral[_ngcontent-%COMP%] {\n color: #888;\n}\n\n\n\n\n\n\n.permissions-list[_ngcontent-%COMP%] {\n padding: 0 20px;\n}\n\n.permission-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px 16px;\n margin-bottom: 8px;\n}\n\n.permission-icon[_ngcontent-%COMP%] {\n font-size: 1.3em;\n color: #5c6bc0;\n}\n\n.permission-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.permission-role[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #333;\n font-size: 14px;\n}\n\n.permission-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: #5c6bc0;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 20px;\n text-align: center;\n color: #888;\n}\n\n.empty-state-icon[_ngcontent-%COMP%] {\n font-size: 40px;\n margin-bottom: 14px;\n opacity: 0.25;\n color: #333;\n}\n\n.empty-state-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 6px;\n color: #555;\n}\n\n.empty-state-text[_ngcontent-%COMP%] {\n font-size: 13px;\n margin-bottom: 16px;\n color: #888;\n}\n\n\n\n\n\n\n.add-item-btn[_ngcontent-%COMP%] {\n background: #5c6bc0;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n font-size: 13px;\n}\n\n.add-item-btn[_ngcontent-%COMP%]:hover {\n background: #3949ab;\n box-shadow: 0 2px 6px rgba(92, 107, 192, 0.3);\n}\n\n\n\n\n\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n\n\n\n\n\n.technical-description-textarea[_ngcontent-%COMP%] {\n width: 100%;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n}\n\n.technical-description-preview[_ngcontent-%COMP%] {\n margin-top: 16px;\n border-top: 1px solid #e0e0e0;\n padding-top: 12px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.technical-description-view[_ngcontent-%COMP%] {\n max-height: 500px;\n overflow-y: auto;\n padding: 12px 16px;\n}\n\n\n\n.dependents-icon[_ngcontent-%COMP%] {\n color: #ef6c00;\n}\n\n.dependents-description[_ngcontent-%COMP%] {\n padding: 0 20px 12px;\n font-size: 13px;\n color: #666;\n}\n\n.dependents-description[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: #f0f0f0;\n padding: 1px 5px;\n border-radius: 3px;\n font-size: 12px;\n}\n\n.dependent-card[_ngcontent-%COMP%] {\n cursor: pointer;\n border-left: 3px solid #ef6c00 !important;\n}\n\n.dependent-card[_ngcontent-%COMP%]:hover {\n border-left-color: #e65100 !important;\n background: #fff8f0 !important;\n}\n\n.dependent-query-icon[_ngcontent-%COMP%] {\n color: #ef6c00 !important;\n}\n\n.item-card-footer[_ngcontent-%COMP%] {\n padding-top: 8px;\n border-top: 1px solid #f0f0f0;\n margin-top: 8px;\n}\n\n.open-link[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #5c6bc0;\n font-weight: 500;\n}\n\n.dependent-card[_ngcontent-%COMP%]:hover .open-link[_ngcontent-%COMP%] {\n color: #3949ab;\n}"] }); }
|
|
1649
1809
|
};
|
|
1650
1810
|
MJQueryFormComponentExtended = __decorate([
|
|
1651
1811
|
RegisterClass(BaseFormComponent, 'MJ: Queries')
|
|
@@ -1653,10 +1813,10 @@ MJQueryFormComponentExtended = __decorate([
|
|
|
1653
1813
|
export { MJQueryFormComponentExtended };
|
|
1654
1814
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJQueryFormComponentExtended, [{
|
|
1655
1815
|
type: Component,
|
|
1656
|
-
args: [{ standalone: false, selector: 'mj-query-form', template: "<div class=\"record-form-container\" style=\"height: 100%; display: flex; flex-direction: column;\">\n @if (record) {\n <form class=\"record-form\" #form=\"ngForm\" style=\"display: flex; flex-direction: column; height: 100%; overflow: hidden;\">\n <mj-form-toolbar [Form]=\"this\"></mj-form-toolbar>\n\n <!-- Header Section -->\n <div class=\"query-header\">\n <div class=\"query-header-content\">\n <!-- Top Row: Name and Run Button -->\n <div class=\"query-header-top\">\n <!-- Left: Query Name -->\n <div class=\"query-name-section\">\n <i class=\"fa-solid fa-database query-title-icon\"></i>\n @if (EditMode) {\n <kendo-textbox [(ngModel)]=\"record.Name\"\n name=\"queryName\"\n placeholder=\"Enter query name...\"\n class=\"query-name-input\">\n </kendo-textbox>\n } @else {\n <h4 class=\"query-name-display\">{{ record.Name || 'Untitled Query' }}</h4>\n }\n </div>\n\n <!-- Right: Action Buttons -->\n <div class=\"query-header-actions\">\n @if (record.ID) {\n <button kendoButton\n [themeColor]=\"'primary'\"\n [size]=\"'large'\"\n [disabled]=\"EditMode || !record.SQL || record.SQL.trim().length === 0\"\n (click)=\"runQuery()\"\n title=\"Run Query\"\n class=\"run-query-btn\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n }\n </div>\n </div>\n\n <!-- Second Row: Category and Status -->\n <div class=\"query-meta-row\">\n <!-- Category -->\n <div class=\"query-meta-item\">\n <label class=\"meta-label\">Category</label>\n @if (EditMode) {\n <kendo-dropdownlist\n [(ngModel)]=\"record.CategoryID\"\n name=\"categoryId\"\n [data]=\"categoryOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n placeholder=\"Select category...\"\n class=\"meta-dropdown\">\n </kendo-dropdownlist>\n } @else {\n <span class=\"meta-value\">{{ getCategoryPath() || 'Uncategorized' }}</span>\n }\n </div>\n\n <!-- Status -->\n <div class=\"query-meta-item\">\n <label class=\"meta-label\">Status</label>\n @if (EditMode) {\n <kendo-dropdownlist\n [(ngModel)]=\"record.Status\"\n name=\"status\"\n [data]=\"statusOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n class=\"meta-dropdown status-dropdown\">\n </kendo-dropdownlist>\n } @else {\n <span class=\"status-pill\"\n [style.background]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid\" [class]=\"getStatusBannerIcon()\"></i>\n {{ record.Status || 'Unknown' }}\n </span>\n }\n </div>\n </div>\n\n <!-- Third Row: Description -->\n @if (EditMode || record.Description) {\n <div class=\"query-description-row\">\n @if (EditMode) {\n <kendo-textarea [(ngModel)]=\"record.Description\"\n name=\"description\"\n [rows]=\"2\"\n placeholder=\"Enter query description...\"\n class=\"query-description-input\">\n </kendo-textarea>\n } @else {\n <p class=\"query-description-text\">{{ record.Description }}</p>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Status Warning Banner for Non-Approved Queries -->\n @if (record.Status && record.Status !== 'Approved' && !EditMode) {\n <div class=\"status-warning-banner\" [style.border-left-color]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid\" [class]=\"getStatusBannerIcon()\"\n [style.color]=\"getStatusBadgeColor()\"></i>\n <span>\n This query has status <strong>{{ record.Status }}</strong>. {{ getStatusBannerMessage() }}\n </span>\n </div>\n }\n\n <!-- Main Content Area with Expansion Panels -->\n <div class=\"query-content\">\n\n <!-- SQL Query Panel -->\n <kendo-expansionpanel\n [(expanded)]=\"sqlPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title-row\">\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-code panel-icon sql-icon\"></i>\n SQL\n @if (record.SQL) {\n <span class=\"panel-badge defined\">\n <i class=\"fa-solid fa-check\"></i> Defined\n </span>\n }\n </span>\n <button type=\"button\"\n kendoButton\n fillMode=\"flat\"\n size=\"small\"\n (click)=\"toggleFiltersHelp(); $event.stopPropagation()\"\n title=\"Show/hide SQL filters help\"\n class=\"filters-help-btn\">\n <i class=\"fa-solid fa-question-circle\"></i>\n <span>Filters Help</span>\n <i class=\"fa-solid\" [ngClass]=\"showFiltersHelp ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </button>\n </span>\n </ng-template>\n\n <div class=\"sql-panel-content\">\n <!-- Code Editor -->\n <mj-code-editor #sqlEditor\n (change)=\"onSQLChange($event)\"\n [language]=\"'sql'\"\n class=\"sql-editor\">\n </mj-code-editor>\n\n <!-- SQL Filters Help (Below Editor) -->\n @if (showFiltersHelp) {\n <div class=\"filters-help\">\n <h6 class=\"filters-help-title\">\n <i class=\"fa-solid fa-filter\"></i> Available SQL Filters for Parameterized Queries\n </h6>\n <div class=\"filters-grid\">\n @for (filter of sqlFilters; track filter.name) {\n <div class=\"filter-card\">\n <div class=\"filter-name\">{{ filter.name }}</div>\n <div class=\"filter-description\">{{ filter.description }}</div>\n <div class=\"filter-syntax\">{{ filter.exampleSyntax }}</div>\n @if (filter.notes) {\n <div class=\"filter-notes\">{{ filter.notes }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n\n <!-- Technical Description Panel -->\n @if (record.TechnicalDescription || EditMode) {\n <kendo-expansionpanel\n [(expanded)]=\"technicalDescriptionPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-book panel-icon\"></i>\n Technical Description\n @if (record.TechnicalDescription) {\n <span class=\"panel-badge defined\">\n <i class=\"fa-solid fa-check\"></i> Documented\n </span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (EditMode) {\n <kendo-textarea [(ngModel)]=\"record.TechnicalDescription\"\n name=\"technicalDescription\"\n [rows]=\"8\"\n placeholder=\"Technical documentation of the query logic, performance considerations, and parameter usage. Supports markdown and mermaid diagrams.\"\n class=\"technical-description-textarea\">\n </kendo-textarea>\n @if (record.TechnicalDescription) {\n <div class=\"technical-description-preview\">\n <div class=\"preview-label\">\n <i class=\"fa-solid fa-eye\"></i> Preview\n </div>\n <mj-markdown\n [data]=\"record.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n } @else {\n <div class=\"technical-description-view\">\n <mj-markdown\n [data]=\"record.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Parameters Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"parametersPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-sliders panel-icon\"></i>\n Query Parameters\n @if (queryParameters.length > 0) {\n <span class=\"panel-badge count\">{{ queryParameters.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingParameters) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading parameters...\"></mj-loading>\n </div>\n } @else {\n @if (queryParameters.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sliders empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Parameters Defined</div>\n <div class=\"empty-state-text\">\n Add parameters to make your query dynamic and reusable.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addParameter()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Parameter\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addParameter()\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (param of queryParameters; track param.ID || $index) {\n <div class=\"item-card\" [class.required]=\"param.IsRequired\" (click)=\"editParameter(param)\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-at item-name-icon param-icon\"></i>\n {{ param.Name }}\n </div>\n <div class=\"item-badges\">\n @if (param.IsRequired) {\n <span class=\"item-badge required\">Required</span>\n }\n </div>\n </div>\n <div class=\"item-card-body\">\n @if (param.Description) {\n <div class=\"item-description\">{{ param.Description }}</div>\n }\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <strong>Type:</strong> {{ param.Type || 'Text' }}\n </span>\n @if (param.DefaultValue) {\n <span class=\"meta-tag\">\n <strong>Default:</strong>\n <code class=\"meta-code\">{{ param.DefaultValue }}</code>\n </span>\n }\n </div>\n </div>\n @if (EditMode) {\n <div class=\"item-actions\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"item-action-btn\" (click)=\"editParameter(param)\" title=\"Edit parameter\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteParameter(param)\" title=\"Delete parameter\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Query Fields Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"fieldsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-table panel-icon\"></i>\n Query Fields\n @if (queryFields.length > 0) {\n <span class=\"panel-badge count\">{{ queryFields.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingFields) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading fields...\"></mj-loading>\n </div>\n } @else {\n @if (queryFields.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-table empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Fields Defined</div>\n <div class=\"empty-state-text\">\n Define output fields for your query results.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addField()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Field\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addField()\">\n <i class=\"fa-solid fa-plus\"></i> Add Field\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (field of queryFields; track field.ID) {\n <div class=\"item-card\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-columns item-name-icon field-icon\"></i>\n {{ field.Name }}\n </div>\n <div class=\"item-badges\">\n <span class=\"item-badge type\">{{ field.SQLBaseType }}</span>\n @if (field.Sequence) {\n <span class=\"item-badge sequence\">#{{ field.Sequence }}</span>\n }\n </div>\n </div>\n <div class=\"item-card-body\">\n @if (field.Description) {\n <div class=\"item-description\">{{ field.Description }}</div>\n }\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-code\"></i> {{ field.SQLFullType || field.SQLBaseType }}\n </span>\n </div>\n </div>\n @if (EditMode) {\n <div class=\"item-card-actions\">\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteField(field)\" title=\"Delete field\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Query Entities Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"entitiesPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-database panel-icon\"></i>\n Query Entities\n @if (queryEntities.length > 0) {\n <span class=\"panel-badge count\">{{ queryEntities.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingEntities) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading entities...\"></mj-loading>\n </div>\n } @else {\n @if (queryEntities.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Entities Tracked</div>\n <div class=\"empty-state-text\">\n Track which entities this query uses for documentation.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addEntity()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Entity\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addEntity()\">\n <i class=\"fa-solid fa-plus\"></i> Add Entity\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (entity of queryEntities; track entity.ID) {\n <div class=\"item-card\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-table item-name-icon entity-icon\"></i>\n {{ entity.Entity || 'Select Entity...' }}\n </div>\n @if (EditMode) {\n <div class=\"entity-dropdown-wrapper\">\n <kendo-dropdownlist\n [(ngModel)]=\"entity.EntityID\"\n [name]=\"'entity_' + entity.ID\"\n [data]=\"getEntityOptions()\"\n textField=\"text\"\n valueField=\"id\"\n [valuePrimitive]=\"true\"\n placeholder=\"Select entity...\"\n class=\"entity-dropdown\">\n </kendo-dropdownlist>\n </div>\n }\n </div>\n @if (!EditMode && entity.Entity) {\n <div class=\"item-card-body\">\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-database\"></i> Data Source\n </span>\n </div>\n </div>\n }\n @if (EditMode) {\n <div class=\"item-card-actions\">\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteEntity(entity)\" title=\"Delete entity\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Details Panel -->\n <kendo-expansionpanel\n [(expanded)]=\"detailsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-info-circle panel-icon\"></i>\n Query Details\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n <div class=\"details-grid\">\n <!-- Uses Template -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-file-code\"></i> Template Usage\n </label>\n @if (EditMode) {\n <kendo-switch [(ngModel)]=\"record.UsesTemplate\" name=\"usesTemplate\"></kendo-switch>\n } @else {\n <div class=\"detail-value\">\n @if (record.UsesTemplate) {\n <span class=\"detail-tag positive\"><i class=\"fa-solid fa-check\"></i> Uses Templates</span>\n } @else {\n <span class=\"detail-tag neutral\"><i class=\"fa-solid fa-times\"></i> No Templates</span>\n }\n </div>\n }\n </div>\n\n <!-- Created Date -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-calendar-plus\"></i> Created\n </label>\n <div class=\"detail-value\">{{ formatDate(record.__mj_CreatedAt) }}</div>\n </div>\n\n <!-- Updated Date -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-calendar-check\"></i> Last Updated\n </label>\n <div class=\"detail-value\">{{ formatDate(record.__mj_UpdatedAt) }}</div>\n </div>\n\n <!-- Quality Rank -->\n @if (record.QualityRank != null) {\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-star\"></i> Quality Rank\n </label>\n <div class=\"detail-value\">{{ record.QualityRank }}/10</div>\n </div>\n }\n </div>\n </div>\n </kendo-expansionpanel>\n\n <!-- Permissions Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"permissionsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-shield-alt panel-icon\"></i>\n Query Permissions\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingPermissions) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading permissions...\"></mj-loading>\n </div>\n } @else {\n @if (queryPermissions.length === 0 && !EditMode) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shield-alt empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Permissions Set</div>\n <div class=\"empty-state-text\">\n This query uses default permissions.\n </div>\n </div>\n } @else {\n @if (EditMode) {\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Query Permissions','QueryID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Query Permissions')\"\n [AllowLoad]=\"true\"\n [ShowToolbar]=\"false\">\n </mj-explorer-entity-data-grid>\n } @else {\n <div class=\"permissions-list\">\n @for (permission of queryPermissions; track permission.ID) {\n <div class=\"permission-card\">\n <i class=\"fa-solid fa-users permission-icon\"></i>\n <div class=\"permission-info\">\n <div class=\"permission-role\">{{ permission.Role }}</div>\n <div class=\"permission-type\">Role Permission</div>\n </div>\n <span class=\"permission-badge\">\n <i class=\"fa-solid fa-play\"></i> Can Execute\n </span>\n </div>\n }\n </div>\n }\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n </div>\n </form>\n\n <!-- Query Run Dialog -->\n <mj-query-run-dialog\n [query]=\"record\"\n [parameters]=\"queryParameters\"\n [(isVisible)]=\"showRunDialog\"\n (onClose)=\"onRunDialogClose()\">\n </mj-query-run-dialog>\n\n <!-- Category Creation Dialog -->\n <mj-query-category-dialog\n [(isVisible)]=\"showCategoryDialog\"\n (onCategoryCreated)=\"onCategoryCreated($event)\">\n </mj-query-category-dialog>\n }\n</div>\n", styles: [".k-pane {\n background-color: #F5F6FA;\n}\n\n.content-margin {\n margin: 10px;\n} \n\n\na {\n font-size: 14px;\n font-weight: bolder;\n}\n\n.tab-header-icon {\n margin-right: 5px;\n}\n\n.record-form {\n display: block;\n flex-direction: column;\n background-color: #F5F6FA;\n padding: 0;\n min-height: 100vh;\n}\n\n.record-form-group {\n margin-top: 0px;\n background-color: #F5F6FA;\n}\n\nbutton {\n margin-right: 5px;\n}\n\n.record-form h2 {\n margin-bottom: 10px;\n}\n\n.k-splitter {\n border-width: 0px;\n}\n\n.record-form-row {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n}\n\n\n/* .record-form .record-form-row:nth-child(odd) {\n background-color: #f2f2f2; \n} */\n\n/* \n.record-form .record-form-row:nth-child(even) {\n background-color: #ffffff; \n} */\n\n.record-form .record-form-row > :first-child {\n font-weight: bold;\n padding-right: 10px;\n} \n\n.record-form .record-form-row > span {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n \n\n@media (min-width: 768px) {\n .record-form-row {\n flex-direction: row;\n align-items: center;\n }\n\n .record-form-row label {\n width: 240px;\n margin-bottom: 0;\n }\n}\n\n/* Collapsible Panel Styles */\n.form-panels-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n background-color: #F5F6FA;\n}\n\n/* All field sections take full width */\n.form-panels-container > .form-card {\n width: 100%;\n}\n\n/* Related entity grid container - responsive layout */\n.form-panels-container .related-entity-grid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 16px;\n width: 100%;\n}\n\n/* Responsive multi-column layout for related entities on wider screens */\n@media (min-width: 1400px) {\n .form-panels-container .related-entity-grid {\n grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));\n }\n}\n\n.form-card {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n}\n\n.collapsible-card {\n overflow: hidden;\n}\n\n.collapsible-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.collapsible-header:hover {\n background: linear-gradient(135deg, #f3f4f6 0%, #f9fafb 100%);\n border-bottom-color: #667eea;\n}\n\n.collapsible-title {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.collapsible-title i {\n font-size: 20px;\n color: #667eea;\n}\n\n.collapsible-title h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.collapsible-header .collapse-icon {\n color: #6b7280;\n transition: transform 0.3s ease;\n}\n\n.collapsible-body {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.collapsible-body.collapsed {\n max-height: 0;\n padding: 0;\n opacity: 0;\n}\n\n.form-body {\n padding: 24px;\n}\n\n/* Related Entity Sections - Visual Distinction */\n.form-card.related-entity {\n background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%);\n border-left: 3px solid #3b82f6;\n}\n\n.form-card.related-entity .collapsible-header {\n background: linear-gradient(135deg, #e0f2fe 0%, #f0f9ff 100%);\n}\n\n.form-card.related-entity .collapsible-header:hover {\n background: linear-gradient(135deg, #bfdbfe 0%, #e0f2fe 100%);\n border-bottom-color: #3b82f6;\n}\n\n.form-card.related-entity .collapsible-title i {\n color: #3b82f6;\n}\n\n/* Section Controls */\n.form-section-controls {\n display: flex;\n gap: 10px;\n padding: 14px 18px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n align-items: center;\n flex-wrap: wrap;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.form-section-controls .control-group {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.form-section-controls button {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n background: white;\n color: #374151;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n margin-right: 0;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n}\n\n.form-section-controls button:hover {\n background: #667eea;\n color: white;\n border-color: #667eea;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);\n}\n\n.form-section-controls button:active {\n transform: translateY(0);\n}\n\n.form-section-controls button i {\n margin-right: 0;\n font-size: 14px;\n}\n\n.form-section-controls .section-search {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n width: 240px;\n transition: all 0.2s;\n background: white;\n}\n\n.form-section-controls .section-search:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n}\n\n.form-section-controls .section-search::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n.form-section-controls .section-count {\n font-size: 13px;\n color: #6b7280;\n margin-left: auto;\n font-weight: 500;\n}\n\n/* Hidden sections for search filter */\n.form-card.search-hidden {\n display: none;\n}\n\n/* Section count badge */\n.section-count-badge {\n background: #667eea;\n color: white;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Search highlighting in section names */\n.collapsible-title h3 .search-highlight {\n background-color: #fef08a;\n color: #854d0e;\n padding: 2px 4px;\n border-radius: 3px;\n font-weight: 700;\n}\n\n/* Row count badge in section headers */\n.collapsible-title .row-count-badge {\n background: #10b981;\n color: white;\n padding: 3px 6px 2px 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n vertical-align: middle;\n position: relative;\n top: -2px;\n display: inline-block;\n line-height: 1;\n}\n\n/* Gray badge for zero rows (loaded but empty) */\n.collapsible-title .row-count-badge.zero-rows {\n background: #9ca3af;\n}\n", "/* Override shared form-styles to enable flex layout */\n:host {\n display: block;\n height: 100%;\n}\n\n/* Override the shared record-form min-height so flex layout works properly */\n.record-form {\n min-height: 0 !important;\n}\n\n/* ========================================\n Header Section \u2014 matches Query Browser gradient\n ======================================== */\n\n.query-header {\n flex-shrink: 0;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n border-bottom: none;\n padding: 0;\n}\n\n.query-header-content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px 20px;\n}\n\n.query-header-top {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.query-name-section {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-title-icon {\n color: rgba(255, 255, 255, 0.85);\n font-size: 1.3em;\n flex-shrink: 0;\n}\n\n.query-name-input {\n font-size: 1.2em;\n font-weight: 600;\n min-width: 300px;\n flex: 1;\n}\n\n.query-name-display {\n margin: 0;\n color: #fff;\n font-weight: 600;\n font-size: 1.2em;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.run-query-btn {\n white-space: nowrap;\n}\n\n/* Meta row (category + status) */\n.query-meta-row {\n display: flex;\n gap: 24px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.query-meta-item {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.meta-label {\n font-weight: 500;\n color: rgba(255, 255, 255, 0.75);\n font-size: 13px;\n min-width: 60px;\n}\n\n.meta-value {\n color: rgba(255, 255, 255, 0.95);\n font-size: 14px;\n}\n\n.meta-dropdown {\n min-width: 200px;\n}\n\n.status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-pill i {\n font-size: 12px;\n}\n\n/* Description row */\n.query-description-row {\n margin-top: 2px;\n}\n\n.query-description-input {\n width: 100%;\n}\n\n.query-description-text {\n margin: 0;\n color: rgba(255, 255, 255, 0.8);\n font-size: 13px;\n line-height: 1.4;\n}\n\n/* ========================================\n Status Warning Banner\n ======================================== */\n\n.status-warning-banner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px;\n margin: 0;\n background: #fff8e1;\n border-left: 4px solid #f59e0b;\n font-size: 13px;\n color: #5d4037;\n flex-shrink: 0;\n}\n\n.status-warning-banner i {\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.status-warning-banner strong {\n font-weight: 600;\n}\n\n/* ========================================\n Main Content Area\n ======================================== */\n\n.query-content {\n flex: 1;\n min-height: 0;\n padding: 16px;\n overflow-y: auto;\n background: #f5f5f5;\n}\n\n/* ========================================\n Expansion Panel Overrides \u2014 Modern Style\n ======================================== */\n\n.query-panel {\n margin-bottom: 12px;\n}\n\n::ng-deep .query-content kendo-expansionpanel {\n border: none !important;\n border-radius: 8px !important;\n margin-bottom: 12px !important;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important;\n background: white !important;\n overflow: hidden !important;\n}\n\n::ng-deep .query-content .k-expander-header {\n background: white !important;\n border: none !important;\n padding: 14px 18px !important;\n border-radius: 8px !important;\n color: #333 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n transition: background 0.15s ease !important;\n}\n\n::ng-deep .query-content .k-expander-header:hover {\n background: #f8f9fa !important;\n}\n\n::ng-deep .query-content kendo-expansionpanel[aria-expanded=\"true\"] .k-expander-header {\n background: #5c6bc0 !important;\n color: white !important;\n border-radius: 8px 8px 0 0 !important;\n}\n\n::ng-deep .query-content .k-expander-content {\n padding: 0 !important;\n border: none !important;\n background: white !important;\n border-radius: 0 0 8px 8px !important;\n}\n\n/* ========================================\n Panel Title & Badges\n ======================================== */\n\n.panel-title-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.panel-icon {\n font-size: 14px;\n opacity: 0.7;\n}\n\n.sql-icon {\n color: #5c6bc0;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-icon {\n color: rgba(255, 255, 255, 0.85) !important;\n opacity: 1;\n}\n\n.panel-badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.panel-badge.defined {\n background: #28a745;\n color: white;\n}\n\n.panel-badge.count {\n background: #5c6bc0;\n color: white;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.count {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.defined {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.filters-help-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n font-size: 12px;\n}\n\n/* ========================================\n Panel Body & Loading\n ======================================== */\n\n.panel-body {\n padding: 16px 0;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-toolbar {\n display: flex;\n justify-content: flex-end;\n padding: 0 20px 12px;\n}\n\n/* ========================================\n SQL Panel\n ======================================== */\n\n.sql-panel-content {\n display: flex;\n flex-direction: column;\n}\n\n.sql-editor {\n flex: 1;\n height: 400px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n margin: 16px;\n}\n\n/* Filters Help */\n.filters-help {\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 16px;\n margin: 0 16px 16px;\n}\n\n.filters-help-title {\n margin: 0 0 12px 0;\n color: #333;\n font-weight: 600;\n font-size: 14px;\n}\n\n.filters-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 10px;\n}\n\n.filter-card {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 12px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.filter-card:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-name {\n font-family: 'Courier New', monospace;\n font-weight: bold;\n color: #5c6bc0;\n margin-bottom: 4px;\n}\n\n.filter-description {\n font-size: 12px;\n color: #555;\n margin-bottom: 6px;\n}\n\n.filter-syntax {\n font-family: 'Courier New', monospace;\n font-size: 11px;\n background: #f5f5f5;\n padding: 6px;\n border-radius: 4px;\n margin-bottom: 4px;\n}\n\n.filter-notes {\n font-size: 11px;\n color: #888;\n font-style: italic;\n}\n\n/* ========================================\n Card Grid (Parameters, Fields, Entities)\n ======================================== */\n\n.card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 12px;\n padding: 0 20px 20px;\n}\n\n.item-card {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px;\n transition: all 0.15s ease;\n cursor: pointer;\n position: relative;\n}\n\n.item-card:hover {\n border-color: #5c6bc0;\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.12);\n}\n\n.item-card.required {\n border-left: 3px solid #f59e0b;\n}\n\n.item-card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 10px;\n}\n\n.item-name {\n font-weight: 600;\n font-size: 14px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.item-name-icon {\n font-size: 14px;\n}\n\n.item-name-icon.param-icon {\n color: #5c6bc0;\n}\n\n.item-name-icon.field-icon {\n color: #5c6bc0;\n}\n\n.item-name-icon.entity-icon {\n color: #28a745;\n}\n\n.item-badges {\n display: flex;\n gap: 6px;\n}\n\n.item-badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n color: white;\n}\n\n.item-badge.required {\n background: #f59e0b;\n}\n\n.item-badge.type {\n background: #e8eaf6;\n color: #3949ab;\n}\n\n.item-badge.sequence {\n background: #f3e5f5;\n color: #7b1fa2;\n}\n\n.item-card-body {\n color: #666;\n font-size: 13px;\n}\n\n.item-description {\n margin-bottom: 8px;\n}\n\n.item-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n}\n\n.meta-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-code {\n background: #f5f5f5;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 11px;\n}\n\n/* Card actions (edit/delete) */\n.item-actions {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.item-card:hover .item-actions {\n opacity: 1;\n}\n\n.item-card-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 8px;\n}\n\n.item-action-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n color: #888;\n transition: all 0.15s ease;\n}\n\n.item-action-btn:hover {\n background: #f0f0f0;\n color: #5c6bc0;\n}\n\n.item-action-btn.delete:hover {\n background: #fff5f5;\n color: #dc3545;\n}\n\n/* Entity dropdown in card */\n.entity-dropdown-wrapper {\n flex: 1;\n margin-left: 12px;\n}\n\n.entity-dropdown {\n width: 100%;\n}\n\n/* ========================================\n Details Grid\n ======================================== */\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n padding: 16px 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n color: #888;\n display: flex;\n align-items: center;\n gap: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #333;\n}\n\n.detail-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n}\n\n.detail-tag.positive {\n color: #28a745;\n}\n\n.detail-tag.neutral {\n color: #888;\n}\n\n/* ========================================\n Permissions\n ======================================== */\n\n.permissions-list {\n padding: 0 20px;\n}\n\n.permission-card {\n display: flex;\n align-items: center;\n gap: 14px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px 16px;\n margin-bottom: 8px;\n}\n\n.permission-icon {\n font-size: 1.3em;\n color: #5c6bc0;\n}\n\n.permission-info {\n flex: 1;\n}\n\n.permission-role {\n font-weight: 600;\n color: #333;\n font-size: 14px;\n}\n\n.permission-type {\n font-size: 12px;\n color: #888;\n}\n\n.permission-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: #5c6bc0;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 20px;\n text-align: center;\n color: #888;\n}\n\n.empty-state-icon {\n font-size: 40px;\n margin-bottom: 14px;\n opacity: 0.25;\n color: #333;\n}\n\n.empty-state-title {\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 6px;\n color: #555;\n}\n\n.empty-state-text {\n font-size: 13px;\n margin-bottom: 16px;\n color: #888;\n}\n\n/* ========================================\n Buttons\n ======================================== */\n\n.add-item-btn {\n background: #5c6bc0;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n font-size: 13px;\n}\n\n.add-item-btn:hover {\n background: #3949ab;\n box-shadow: 0 2px 6px rgba(92, 107, 192, 0.3);\n}\n\n/* ========================================\n Badge (reused across components)\n ======================================== */\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n/* ========================================\n Technical Description Panel\n ======================================== */\n\n.technical-description-textarea {\n width: 100%;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n}\n\n.technical-description-preview {\n margin-top: 16px;\n border-top: 1px solid #e0e0e0;\n padding-top: 12px;\n}\n\n.preview-label {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.technical-description-view {\n max-height: 500px;\n overflow-y: auto;\n padding: 12px 16px;\n}\n"] }]
|
|
1816
|
+
args: [{ standalone: false, selector: 'mj-query-form', template: "<div class=\"record-form-container\" style=\"height: 100%; display: flex; flex-direction: column;\">\n @if (record) {\n <form class=\"record-form\" #form=\"ngForm\" style=\"display: flex; flex-direction: column; height: 100%; overflow: hidden;\">\n <mj-form-toolbar [Form]=\"this\" [Config]=\"ToolbarConfig\"></mj-form-toolbar>\n\n <!-- Header Section -->\n <div class=\"query-header\">\n <div class=\"query-header-content\">\n <!-- Top Row: Name and Run Button -->\n <div class=\"query-header-top\">\n <!-- Left: Query Name -->\n <div class=\"query-name-section\">\n <i class=\"fa-solid fa-database query-title-icon\"></i>\n @if (EditMode) {\n <kendo-textbox [(ngModel)]=\"record.Name\"\n name=\"queryName\"\n placeholder=\"Enter query name...\"\n class=\"query-name-input\">\n </kendo-textbox>\n } @else {\n <h4 class=\"query-name-display\">{{ record.Name || 'Untitled Query' }}</h4>\n }\n </div>\n\n <!-- Right: Action Buttons -->\n <div class=\"query-header-actions\">\n @if (record.ID) {\n <button kendoButton\n [themeColor]=\"'primary'\"\n [size]=\"'large'\"\n [disabled]=\"EditMode || !record.SQL || record.SQL.trim().length === 0\"\n (click)=\"runQuery()\"\n title=\"Run Query\"\n class=\"run-query-btn\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n }\n </div>\n </div>\n\n <!-- Second Row: Category and Status -->\n <div class=\"query-meta-row\">\n <!-- Category -->\n <div class=\"query-meta-item\">\n <label class=\"meta-label\">Category</label>\n @if (EditMode) {\n <kendo-dropdownlist\n [(ngModel)]=\"record.CategoryID\"\n name=\"categoryId\"\n [data]=\"categoryOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n placeholder=\"Select category...\"\n class=\"meta-dropdown\">\n </kendo-dropdownlist>\n } @else {\n <span class=\"meta-value\">{{ categoryPathDisplay || 'Uncategorized' }}</span>\n }\n </div>\n\n <!-- Status -->\n <div class=\"query-meta-item\">\n <label class=\"meta-label\">Status</label>\n @if (EditMode) {\n <kendo-dropdownlist\n [(ngModel)]=\"record.Status\"\n name=\"status\"\n [data]=\"statusOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n class=\"meta-dropdown status-dropdown\">\n </kendo-dropdownlist>\n } @else {\n <span class=\"status-pill\"\n [style.background]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid\" [class]=\"getStatusBannerIcon()\"></i>\n {{ record.Status || 'Unknown' }}\n </span>\n }\n </div>\n </div>\n\n <!-- Third Row: Description -->\n @if (EditMode || record.Description) {\n <div class=\"query-description-row\">\n @if (EditMode) {\n <kendo-textarea [(ngModel)]=\"record.Description\"\n name=\"description\"\n [rows]=\"2\"\n placeholder=\"Enter query description...\"\n class=\"query-description-input\">\n </kendo-textarea>\n } @else {\n <p class=\"query-description-text\">{{ record.Description }}</p>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Status Warning Banner for Non-Approved Queries -->\n @if (record.Status && record.Status !== 'Approved' && !EditMode) {\n <div class=\"status-warning-banner\" [style.border-left-color]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid\" [class]=\"getStatusBannerIcon()\"\n [style.color]=\"getStatusBadgeColor()\"></i>\n <span>\n This query has status <strong>{{ record.Status }}</strong>. {{ getStatusBannerMessage() }}\n </span>\n </div>\n }\n\n <!-- Main Content Area with Expansion Panels -->\n <div class=\"query-content\">\n\n <!-- SQL Query Panel -->\n <kendo-expansionpanel\n [(expanded)]=\"sqlPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title-row\">\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-code panel-icon sql-icon\"></i>\n SQL\n @if (record.SQL) {\n <span class=\"panel-badge defined\">\n <i class=\"fa-solid fa-check\"></i> Defined\n </span>\n }\n </span>\n <button type=\"button\"\n kendoButton\n fillMode=\"flat\"\n size=\"small\"\n (click)=\"toggleFiltersHelp(); $event.stopPropagation()\"\n title=\"Show/hide SQL filters help\"\n class=\"filters-help-btn\">\n <i class=\"fa-solid fa-question-circle\"></i>\n <span>Filters Help</span>\n <i class=\"fa-solid\" [ngClass]=\"showFiltersHelp ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </button>\n </span>\n </ng-template>\n\n <div class=\"sql-panel-content\">\n <!-- Code Editor -->\n <mj-code-editor #sqlEditor\n (change)=\"onSQLChange($event)\"\n (CompositionTokenClick)=\"onCompositionTokenClick($event)\"\n [language]=\"'sql'\"\n class=\"sql-editor\">\n </mj-code-editor>\n\n <!-- SQL Filters Help (Below Editor) -->\n @if (showFiltersHelp) {\n <div class=\"filters-help\">\n <h6 class=\"filters-help-title\">\n <i class=\"fa-solid fa-filter\"></i> Available SQL Filters for Parameterized Queries\n </h6>\n <div class=\"filters-grid\">\n @for (filter of sqlFilters; track filter.name) {\n <div class=\"filter-card\">\n <div class=\"filter-name\">{{ filter.name }}</div>\n <div class=\"filter-description\">{{ filter.description }}</div>\n <div class=\"filter-syntax\">{{ filter.exampleSyntax }}</div>\n @if (filter.notes) {\n <div class=\"filter-notes\">{{ filter.notes }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n\n <!-- Technical Description Panel -->\n @if (record.TechnicalDescription || EditMode) {\n <kendo-expansionpanel\n [(expanded)]=\"technicalDescriptionPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-book panel-icon\"></i>\n Technical Description\n @if (record.TechnicalDescription) {\n <span class=\"panel-badge defined\">\n <i class=\"fa-solid fa-check\"></i> Documented\n </span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (EditMode) {\n <kendo-textarea [(ngModel)]=\"record.TechnicalDescription\"\n name=\"technicalDescription\"\n [rows]=\"8\"\n placeholder=\"Technical documentation of the query logic, performance considerations, and parameter usage. Supports markdown and mermaid diagrams.\"\n class=\"technical-description-textarea\">\n </kendo-textarea>\n @if (record.TechnicalDescription) {\n <div class=\"technical-description-preview\">\n <div class=\"preview-label\">\n <i class=\"fa-solid fa-eye\"></i> Preview\n </div>\n <mj-markdown\n [data]=\"record.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n } @else {\n <div class=\"technical-description-view\">\n <mj-markdown\n [data]=\"record.TechnicalDescription || ''\"\n [enableMermaid]=\"true\"\n [enableHighlight]=\"true\"\n [enableCollapsibleHeadings]=\"false\"\n [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Parameters Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"parametersPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-sliders panel-icon\"></i>\n Parameters\n @if (queryParameters.length > 0) {\n <span class=\"panel-badge count\">{{ queryParameters.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingParameters) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading parameters...\"></mj-loading>\n </div>\n } @else {\n @if (queryParameters.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sliders empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Parameters Defined</div>\n <div class=\"empty-state-text\">\n Add parameters to make your query dynamic and reusable.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addParameter()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Parameter\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addParameter()\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (param of queryParameters; track param.ID || $index) {\n <div class=\"item-card\" [class.required]=\"param.IsRequired\" (click)=\"editParameter(param)\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-at item-name-icon param-icon\"></i>\n {{ param.Name }}\n </div>\n <div class=\"item-badges\">\n @if (param.IsRequired) {\n <span class=\"item-badge required\">Required</span>\n }\n </div>\n </div>\n <div class=\"item-card-body\">\n @if (param.Description) {\n <div class=\"item-description\">{{ param.Description }}</div>\n }\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <strong>Type:</strong> {{ param.Type || 'Text' }}\n </span>\n @if (param.DefaultValue) {\n <span class=\"meta-tag\">\n <strong>Default:</strong>\n <code class=\"meta-code\">{{ param.DefaultValue }}</code>\n </span>\n }\n </div>\n </div>\n @if (EditMode) {\n <div class=\"item-actions\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"item-action-btn\" (click)=\"editParameter(param)\" title=\"Edit parameter\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteParameter(param)\" title=\"Delete parameter\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Query Fields Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"fieldsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-table panel-icon\"></i>\n Fields\n @if (queryFields.length > 0) {\n <span class=\"panel-badge count\">{{ queryFields.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingFields) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading fields...\"></mj-loading>\n </div>\n } @else {\n @if (queryFields.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-table empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Fields Defined</div>\n <div class=\"empty-state-text\">\n Define output fields for your query results.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addField()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Field\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addField()\">\n <i class=\"fa-solid fa-plus\"></i> Add Field\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (field of queryFields; track field.ID) {\n <div class=\"item-card\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-columns item-name-icon field-icon\"></i>\n {{ field.Name }}\n </div>\n <div class=\"item-badges\">\n <span class=\"item-badge type\">{{ field.SQLBaseType }}</span>\n @if (field.Sequence) {\n <span class=\"item-badge sequence\">#{{ field.Sequence }}</span>\n }\n </div>\n </div>\n <div class=\"item-card-body\">\n @if (field.Description) {\n <div class=\"item-description\">{{ field.Description }}</div>\n }\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-code\"></i> {{ field.SQLFullType || field.SQLBaseType }}\n </span>\n </div>\n </div>\n @if (EditMode) {\n <div class=\"item-card-actions\">\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteField(field)\" title=\"Delete field\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Dependent Queries Panel -->\n @if (record.IsSaved && DependentQueries.length > 0) {\n <kendo-expansionpanel\n [(expanded)]=\"dependentsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-arrow-left panel-icon dependents-icon\"></i>\n Dependent Queries\n <span class=\"panel-badge count\">{{ DependentQueries.length }}</span>\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n <div class=\"dependents-description\">\n These queries reference this query via <code>{{\"{{query:\\\"...\\\"}}\"}} </code> composition syntax.\n </div>\n <div class=\"card-grid\">\n @for (dep of DependentQueries; track dep.ID) {\n <div class=\"item-card dependent-card\" (click)=\"onDependentQueryClick(dep)\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-arrow-left item-name-icon dependent-query-icon\"></i>\n {{ dep.Query }}\n </div>\n </div>\n <div class=\"item-card-body\">\n @if (dep.ReferencePath) {\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-link\"></i> {{ dep.ReferencePath }}\n </span>\n </div>\n }\n @if (dep.Alias) {\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <strong>Alias:</strong> <code class=\"meta-code\">{{ dep.Alias }}</code>\n </span>\n </div>\n }\n </div>\n <div class=\"item-card-footer\">\n <span class=\"open-link\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Query Entities Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"entitiesPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-database panel-icon\"></i>\n Entities\n @if (queryEntities.length > 0) {\n <span class=\"panel-badge count\">{{ queryEntities.length }}</span>\n }\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingEntities) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading entities...\"></mj-loading>\n </div>\n } @else {\n @if (queryEntities.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Entities Tracked</div>\n <div class=\"empty-state-text\">\n Track which entities this query uses for documentation.\n </div>\n @if (EditMode) {\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addEntity()\">\n <i class=\"fa-solid fa-plus\"></i> Add First Entity\n </button>\n }\n </div>\n } @else {\n @if (EditMode) {\n <div class=\"panel-toolbar\">\n <button type=\"button\" class=\"add-item-btn\" (click)=\"addEntity()\">\n <i class=\"fa-solid fa-plus\"></i> Add Entity\n </button>\n </div>\n }\n <div class=\"card-grid\">\n @for (entity of queryEntities; track entity.ID) {\n <div class=\"item-card\">\n <div class=\"item-card-header\">\n <div class=\"item-name\">\n <i class=\"fa-solid fa-table item-name-icon entity-icon\"></i>\n {{ entity.Entity || 'Select Entity...' }}\n </div>\n @if (EditMode) {\n <div class=\"entity-dropdown-wrapper\">\n <kendo-dropdownlist\n [(ngModel)]=\"entity.EntityID\"\n [name]=\"'entity_' + entity.ID\"\n [data]=\"getEntityOptions()\"\n textField=\"text\"\n valueField=\"id\"\n [valuePrimitive]=\"true\"\n placeholder=\"Select entity...\"\n class=\"entity-dropdown\">\n </kendo-dropdownlist>\n </div>\n }\n </div>\n @if (!EditMode && entity.Entity) {\n <div class=\"item-card-body\">\n <div class=\"item-meta\">\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-database\"></i> Data Source\n </span>\n </div>\n </div>\n }\n @if (EditMode) {\n <div class=\"item-card-actions\">\n <button type=\"button\" class=\"item-action-btn delete\" (click)=\"deleteEntity(entity)\" title=\"Delete entity\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n <!-- Details Panel -->\n <kendo-expansionpanel\n [(expanded)]=\"detailsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-info-circle panel-icon\"></i>\n Details\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n <div class=\"details-grid\">\n <!-- Uses Template -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-file-code\"></i> Template Usage\n </label>\n @if (EditMode) {\n <kendo-switch [(ngModel)]=\"record.UsesTemplate\" name=\"usesTemplate\"></kendo-switch>\n } @else {\n <div class=\"detail-value\">\n @if (record.UsesTemplate) {\n <span class=\"detail-tag positive\"><i class=\"fa-solid fa-check\"></i> Uses Templates</span>\n } @else {\n <span class=\"detail-tag neutral\"><i class=\"fa-solid fa-times\"></i> No Templates</span>\n }\n </div>\n }\n </div>\n\n <!-- Created Date -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-calendar-plus\"></i> Created\n </label>\n <div class=\"detail-value\">{{ formatDate(record.__mj_CreatedAt) }}</div>\n </div>\n\n <!-- Updated Date -->\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-calendar-check\"></i> Last Updated\n </label>\n <div class=\"detail-value\">{{ formatDate(record.__mj_UpdatedAt) }}</div>\n </div>\n\n <!-- Quality Rank -->\n @if (record.QualityRank != null) {\n <div class=\"detail-item\">\n <label class=\"detail-label\">\n <i class=\"fa-solid fa-star\"></i> Quality Rank\n </label>\n <div class=\"detail-value\">{{ record.QualityRank }}/10</div>\n </div>\n }\n </div>\n </div>\n </kendo-expansionpanel>\n\n <!-- Permissions Panel -->\n @if (record.IsSaved) {\n <kendo-expansionpanel\n [(expanded)]=\"permissionsPanelExpanded\"\n class=\"query-panel\">\n <ng-template kendoExpansionPanelTitleDirective>\n <span class=\"panel-title\">\n <i class=\"fa-solid fa-shield-alt panel-icon\"></i>\n Permissions\n </span>\n </ng-template>\n\n <div class=\"panel-body\">\n @if (isLoadingPermissions) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading permissions...\"></mj-loading>\n </div>\n } @else {\n @if (queryPermissions.length === 0 && !EditMode) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-shield-alt empty-state-icon\"></i>\n <div class=\"empty-state-title\">No Permissions Set</div>\n <div class=\"empty-state-text\">\n This query uses default permissions.\n </div>\n </div>\n } @else {\n @if (EditMode) {\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Query Permissions','QueryID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Query Permissions')\"\n [AllowLoad]=\"true\"\n [ShowToolbar]=\"false\">\n </mj-explorer-entity-data-grid>\n } @else {\n <div class=\"permissions-list\">\n @for (permission of queryPermissions; track permission.ID) {\n <div class=\"permission-card\">\n <i class=\"fa-solid fa-users permission-icon\"></i>\n <div class=\"permission-info\">\n <div class=\"permission-role\">{{ permission.Role }}</div>\n <div class=\"permission-type\">Role Permission</div>\n </div>\n <span class=\"permission-badge\">\n <i class=\"fa-solid fa-play\"></i> Can Execute\n </span>\n </div>\n }\n </div>\n }\n }\n }\n </div>\n </kendo-expansionpanel>\n }\n\n </div>\n </form>\n\n <!-- Query Run Dialog -->\n <mj-query-run-dialog\n [query]=\"record\"\n [parameters]=\"queryParameters\"\n [(isVisible)]=\"showRunDialog\"\n (onClose)=\"onRunDialogClose()\">\n </mj-query-run-dialog>\n\n <!-- Category Creation Dialog -->\n <mj-query-category-dialog\n [(isVisible)]=\"showCategoryDialog\"\n (onCategoryCreated)=\"onCategoryCreated($event)\">\n </mj-query-category-dialog>\n }\n</div>\n", styles: [".k-pane {\n background-color: #F5F6FA;\n}\n\n.content-margin {\n margin: 10px;\n} \n\n\na {\n font-size: 14px;\n font-weight: bolder;\n}\n\n.tab-header-icon {\n margin-right: 5px;\n}\n\n.record-form {\n display: block;\n flex-direction: column;\n background-color: #F5F6FA;\n padding: 0;\n min-height: 100vh;\n}\n\n.record-form-group {\n margin-top: 0px;\n background-color: #F5F6FA;\n}\n\nbutton {\n margin-right: 5px;\n}\n\n.record-form h2 {\n margin-bottom: 10px;\n}\n\n.k-splitter {\n border-width: 0px;\n}\n\n.record-form-row {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n}\n\n\n/* .record-form .record-form-row:nth-child(odd) {\n background-color: #f2f2f2; \n} */\n\n/* \n.record-form .record-form-row:nth-child(even) {\n background-color: #ffffff; \n} */\n\n.record-form .record-form-row > :first-child {\n font-weight: bold;\n padding-right: 10px;\n} \n\n.record-form .record-form-row > span {\n white-space: pre-line;\n max-height: 300px;\n overflow: auto;\n}\n\n \n\n@media (min-width: 768px) {\n .record-form-row {\n flex-direction: row;\n align-items: center;\n }\n\n .record-form-row label {\n width: 240px;\n margin-bottom: 0;\n }\n}\n\n/* Collapsible Panel Styles */\n.form-panels-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n background-color: #F5F6FA;\n}\n\n/* All field sections take full width */\n.form-panels-container > .form-card {\n width: 100%;\n}\n\n/* Related entity grid container - responsive layout */\n.form-panels-container .related-entity-grid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 16px;\n width: 100%;\n}\n\n/* Responsive multi-column layout for related entities on wider screens */\n@media (min-width: 1400px) {\n .form-panels-container .related-entity-grid {\n grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));\n }\n}\n\n.form-card {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n}\n\n.collapsible-card {\n overflow: hidden;\n}\n\n.collapsible-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.collapsible-header:hover {\n background: linear-gradient(135deg, #f3f4f6 0%, #f9fafb 100%);\n border-bottom-color: #667eea;\n}\n\n.collapsible-title {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.collapsible-title i {\n font-size: 20px;\n color: #667eea;\n}\n\n.collapsible-title h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.collapsible-header .collapse-icon {\n color: #6b7280;\n transition: transform 0.3s ease;\n}\n\n.collapsible-body {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.collapsible-body.collapsed {\n max-height: 0;\n padding: 0;\n opacity: 0;\n}\n\n.form-body {\n padding: 24px;\n}\n\n/* Related Entity Sections - Visual Distinction */\n.form-card.related-entity {\n background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%);\n border-left: 3px solid #3b82f6;\n}\n\n.form-card.related-entity .collapsible-header {\n background: linear-gradient(135deg, #e0f2fe 0%, #f0f9ff 100%);\n}\n\n.form-card.related-entity .collapsible-header:hover {\n background: linear-gradient(135deg, #bfdbfe 0%, #e0f2fe 100%);\n border-bottom-color: #3b82f6;\n}\n\n.form-card.related-entity .collapsible-title i {\n color: #3b82f6;\n}\n\n/* Section Controls */\n.form-section-controls {\n display: flex;\n gap: 10px;\n padding: 14px 18px;\n background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);\n border-bottom: 2px solid #e5e7eb;\n align-items: center;\n flex-wrap: wrap;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.form-section-controls .control-group {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.form-section-controls button {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n background: white;\n color: #374151;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n margin-right: 0;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n}\n\n.form-section-controls button:hover {\n background: #667eea;\n color: white;\n border-color: #667eea;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);\n}\n\n.form-section-controls button:active {\n transform: translateY(0);\n}\n\n.form-section-controls button i {\n margin-right: 0;\n font-size: 14px;\n}\n\n.form-section-controls .section-search {\n padding: 8px 14px;\n font-size: 13px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n width: 240px;\n transition: all 0.2s;\n background: white;\n}\n\n.form-section-controls .section-search:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n}\n\n.form-section-controls .section-search::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n.form-section-controls .section-count {\n font-size: 13px;\n color: #6b7280;\n margin-left: auto;\n font-weight: 500;\n}\n\n/* Hidden sections for search filter */\n.form-card.search-hidden {\n display: none;\n}\n\n/* Section count badge */\n.section-count-badge {\n background: #667eea;\n color: white;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n/* Search highlighting in section names */\n.collapsible-title h3 .search-highlight {\n background-color: #fef08a;\n color: #854d0e;\n padding: 2px 4px;\n border-radius: 3px;\n font-weight: 700;\n}\n\n/* Row count badge in section headers */\n.collapsible-title .row-count-badge {\n background: #10b981;\n color: white;\n padding: 3px 6px 2px 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n vertical-align: middle;\n position: relative;\n top: -2px;\n display: inline-block;\n line-height: 1;\n}\n\n/* Gray badge for zero rows (loaded but empty) */\n.collapsible-title .row-count-badge.zero-rows {\n background: #9ca3af;\n}\n", "/* Override shared form-styles to enable flex layout */\n:host {\n display: block;\n height: 100%;\n}\n\n/* Override the shared record-form min-height so flex layout works properly */\n.record-form {\n min-height: 0 !important;\n}\n\n/* ========================================\n Header Section \u2014 matches Query Browser gradient\n ======================================== */\n\n.query-header {\n flex-shrink: 0;\n background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);\n border-bottom: none;\n padding: 0;\n}\n\n.query-header-content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px 20px;\n}\n\n.query-header-top {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n}\n\n.query-name-section {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-title-icon {\n color: rgba(255, 255, 255, 0.85);\n font-size: 1.3em;\n flex-shrink: 0;\n}\n\n.query-name-input {\n font-size: 1.2em;\n font-weight: 600;\n min-width: 300px;\n flex: 1;\n}\n\n.query-name-display {\n margin: 0;\n color: #fff;\n font-weight: 600;\n font-size: 1.2em;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.query-header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.run-query-btn {\n white-space: nowrap;\n}\n\n/* Meta row (category + status) */\n.query-meta-row {\n display: flex;\n gap: 24px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.query-meta-item {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.meta-label {\n font-weight: 500;\n color: rgba(255, 255, 255, 0.75);\n font-size: 13px;\n min-width: 60px;\n}\n\n.meta-value {\n color: rgba(255, 255, 255, 0.95);\n font-size: 14px;\n}\n\n.meta-dropdown {\n min-width: 200px;\n}\n\n.status-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 14px;\n color: #fff;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-pill i {\n font-size: 12px;\n}\n\n/* Description row */\n.query-description-row {\n margin-top: 2px;\n}\n\n.query-description-input {\n width: 100%;\n}\n\n.query-description-text {\n margin: 0;\n color: rgba(255, 255, 255, 0.8);\n font-size: 13px;\n line-height: 1.4;\n}\n\n/* ========================================\n Status Warning Banner\n ======================================== */\n\n.status-warning-banner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 16px;\n margin: 0;\n background: #fff8e1;\n border-left: 4px solid #f59e0b;\n font-size: 13px;\n color: #5d4037;\n flex-shrink: 0;\n}\n\n.status-warning-banner i {\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.status-warning-banner strong {\n font-weight: 600;\n}\n\n/* ========================================\n Main Content Area\n ======================================== */\n\n.query-content {\n flex: 1;\n min-height: 0;\n padding: 16px;\n overflow-y: auto;\n background: #f5f5f5;\n}\n\n/* ========================================\n Expansion Panel Overrides \u2014 Modern Style\n ======================================== */\n\n.query-panel {\n margin-bottom: 12px;\n}\n\n::ng-deep .query-content kendo-expansionpanel {\n border: none !important;\n border-radius: 8px !important;\n margin-bottom: 12px !important;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08) !important;\n background: white !important;\n overflow: hidden !important;\n}\n\n::ng-deep .query-content .k-expander-header {\n background: white !important;\n border: none !important;\n padding: 14px 18px !important;\n border-radius: 8px !important;\n color: #333 !important;\n font-weight: 600 !important;\n font-size: 14px !important;\n transition: background 0.15s ease !important;\n}\n\n::ng-deep .query-content .k-expander-header:hover {\n background: #f8f9fa !important;\n}\n\n::ng-deep .query-content kendo-expansionpanel[aria-expanded=\"true\"] .k-expander-header {\n background: #5c6bc0 !important;\n color: white !important;\n border-radius: 8px 8px 0 0 !important;\n}\n\n::ng-deep .query-content .k-expander-content {\n padding: 0 !important;\n border: none !important;\n background: white !important;\n border-radius: 0 0 8px 8px !important;\n}\n\n/* ========================================\n Panel Title & Badges\n ======================================== */\n\n.panel-title-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.panel-icon {\n font-size: 14px;\n opacity: 0.7;\n}\n\n.sql-icon {\n color: #5c6bc0;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-icon {\n color: rgba(255, 255, 255, 0.85) !important;\n opacity: 1;\n}\n\n.panel-badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.panel-badge.defined {\n background: #28a745;\n color: white;\n}\n\n.panel-badge.count {\n background: #5c6bc0;\n color: white;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.count {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n::ng-deep kendo-expansionpanel[aria-expanded=\"true\"] .panel-badge.defined {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.filters-help-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n font-size: 12px;\n}\n\n/* ========================================\n Panel Body & Loading\n ======================================== */\n\n.panel-body {\n padding: 16px 0;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-toolbar {\n display: flex;\n justify-content: flex-end;\n padding: 0 20px 12px;\n}\n\n/* ========================================\n SQL Panel\n ======================================== */\n\n.sql-panel-content {\n display: flex;\n flex-direction: column;\n}\n\n.sql-editor {\n flex: 1;\n height: 400px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n margin: 16px;\n}\n\n/* Filters Help */\n.filters-help {\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 16px;\n margin: 0 16px 16px;\n}\n\n.filters-help-title {\n margin: 0 0 12px 0;\n color: #333;\n font-weight: 600;\n font-size: 14px;\n}\n\n.filters-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 10px;\n}\n\n.filter-card {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 12px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.filter-card:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-name {\n font-family: 'Courier New', monospace;\n font-weight: bold;\n color: #5c6bc0;\n margin-bottom: 4px;\n}\n\n.filter-description {\n font-size: 12px;\n color: #555;\n margin-bottom: 6px;\n}\n\n.filter-syntax {\n font-family: 'Courier New', monospace;\n font-size: 11px;\n background: #f5f5f5;\n padding: 6px;\n border-radius: 4px;\n margin-bottom: 4px;\n}\n\n.filter-notes {\n font-size: 11px;\n color: #888;\n font-style: italic;\n}\n\n/* ========================================\n Card Grid (Parameters, Fields, Entities)\n ======================================== */\n\n.card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: 12px;\n padding: 0 20px 20px;\n}\n\n.item-card {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px;\n transition: all 0.15s ease;\n cursor: pointer;\n position: relative;\n}\n\n.item-card:hover {\n border-color: #5c6bc0;\n box-shadow: 0 2px 8px rgba(92, 107, 192, 0.12);\n}\n\n.item-card.required {\n border-left: 3px solid #f59e0b;\n}\n\n.item-card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 10px;\n}\n\n.item-name {\n font-weight: 600;\n font-size: 14px;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.item-name-icon {\n font-size: 14px;\n}\n\n.item-name-icon.param-icon {\n color: #5c6bc0;\n}\n\n.item-name-icon.field-icon {\n color: #5c6bc0;\n}\n\n.item-name-icon.entity-icon {\n color: #28a745;\n}\n\n.item-badges {\n display: flex;\n gap: 6px;\n}\n\n.item-badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n color: white;\n}\n\n.item-badge.required {\n background: #f59e0b;\n}\n\n.item-badge.type {\n background: #e8eaf6;\n color: #3949ab;\n}\n\n.item-badge.sequence {\n background: #f3e5f5;\n color: #7b1fa2;\n}\n\n.item-card-body {\n color: #666;\n font-size: 13px;\n}\n\n.item-description {\n margin-bottom: 8px;\n}\n\n.item-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n}\n\n.meta-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-code {\n background: #f5f5f5;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 11px;\n}\n\n/* Card actions (edit/delete) */\n.item-actions {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.item-card:hover .item-actions {\n opacity: 1;\n}\n\n.item-card-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 8px;\n}\n\n.item-action-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n color: #888;\n transition: all 0.15s ease;\n}\n\n.item-action-btn:hover {\n background: #f0f0f0;\n color: #5c6bc0;\n}\n\n.item-action-btn.delete:hover {\n background: #fff5f5;\n color: #dc3545;\n}\n\n/* Entity dropdown in card */\n.entity-dropdown-wrapper {\n flex: 1;\n margin-left: 12px;\n}\n\n.entity-dropdown {\n width: 100%;\n}\n\n/* ========================================\n Details Grid\n ======================================== */\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 16px;\n padding: 16px 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n color: #888;\n display: flex;\n align-items: center;\n gap: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #333;\n}\n\n.detail-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n}\n\n.detail-tag.positive {\n color: #28a745;\n}\n\n.detail-tag.neutral {\n color: #888;\n}\n\n/* ========================================\n Permissions\n ======================================== */\n\n.permissions-list {\n padding: 0 20px;\n}\n\n.permission-card {\n display: flex;\n align-items: center;\n gap: 14px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 14px 16px;\n margin-bottom: 8px;\n}\n\n.permission-icon {\n font-size: 1.3em;\n color: #5c6bc0;\n}\n\n.permission-info {\n flex: 1;\n}\n\n.permission-role {\n font-weight: 600;\n color: #333;\n font-size: 14px;\n}\n\n.permission-type {\n font-size: 12px;\n color: #888;\n}\n\n.permission-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: #5c6bc0;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ========================================\n Empty State\n ======================================== */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 20px;\n text-align: center;\n color: #888;\n}\n\n.empty-state-icon {\n font-size: 40px;\n margin-bottom: 14px;\n opacity: 0.25;\n color: #333;\n}\n\n.empty-state-title {\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 6px;\n color: #555;\n}\n\n.empty-state-text {\n font-size: 13px;\n margin-bottom: 16px;\n color: #888;\n}\n\n/* ========================================\n Buttons\n ======================================== */\n\n.add-item-btn {\n background: #5c6bc0;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-weight: 500;\n font-size: 13px;\n}\n\n.add-item-btn:hover {\n background: #3949ab;\n box-shadow: 0 2px 6px rgba(92, 107, 192, 0.3);\n}\n\n/* ========================================\n Badge (reused across components)\n ======================================== */\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n/* ========================================\n Technical Description Panel\n ======================================== */\n\n.technical-description-textarea {\n width: 100%;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n}\n\n.technical-description-preview {\n margin-top: 16px;\n border-top: 1px solid #e0e0e0;\n padding-top: 12px;\n}\n\n.preview-label {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.technical-description-view {\n max-height: 500px;\n overflow-y: auto;\n padding: 12px 16px;\n}\n\n/* Dependent Queries */\n.dependents-icon {\n color: #ef6c00;\n}\n\n.dependents-description {\n padding: 0 20px 12px;\n font-size: 13px;\n color: #666;\n}\n\n.dependents-description code {\n background: #f0f0f0;\n padding: 1px 5px;\n border-radius: 3px;\n font-size: 12px;\n}\n\n.dependent-card {\n cursor: pointer;\n border-left: 3px solid #ef6c00 !important;\n}\n\n.dependent-card:hover {\n border-left-color: #e65100 !important;\n background: #fff8f0 !important;\n}\n\n.dependent-query-icon {\n color: #ef6c00 !important;\n}\n\n.item-card-footer {\n padding-top: 8px;\n border-top: 1px solid #f0f0f0;\n margin-top: 8px;\n}\n\n.open-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #5c6bc0;\n font-weight: 500;\n}\n\n.dependent-card:hover .open-link {\n color: #3949ab;\n}\n"] }]
|
|
1657
1817
|
}], null, { sqlEditor: [{
|
|
1658
1818
|
type: ViewChild,
|
|
1659
1819
|
args: ['sqlEditor']
|
|
1660
1820
|
}] }); })();
|
|
1661
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJQueryFormComponentExtended, { className: "MJQueryFormComponentExtended", filePath: "src/lib/custom/Queries/query-form.component.ts", lineNumber:
|
|
1821
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJQueryFormComponentExtended, { className: "MJQueryFormComponentExtended", filePath: "src/lib/custom/Queries/query-form.component.ts", lineNumber: 25 }); })();
|
|
1662
1822
|
//# sourceMappingURL=query-form.component.js.map
|