@memberjunction/ng-core-entity-forms 5.22.0 → 5.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts +4 -5
  2. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +55 -59
  4. package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
  5. package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js +0 -1
  6. package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js.map +1 -1
  7. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts +4 -5
  8. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
  9. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +54 -71
  10. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
  11. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  12. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +1053 -1096
  13. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  14. package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts +2 -3
  15. package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts.map +1 -1
  16. package/dist/lib/custom/AIAgents/ai-agent-management.service.js +39 -82
  17. package/dist/lib/custom/AIAgents/ai-agent-management.service.js.map +1 -1
  18. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts +4 -5
  19. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
  20. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +28 -31
  21. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
  22. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts +4 -5
  23. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +15 -14
  25. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
  26. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts +4 -7
  27. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts.map +1 -1
  28. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +77 -124
  29. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
  30. package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts +2 -2
  31. package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts.map +1 -1
  32. package/dist/lib/custom/AIAgents/new-agent-dialog.service.js +10 -11
  33. package/dist/lib/custom/AIAgents/new-agent-dialog.service.js.map +1 -1
  34. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts +4 -5
  35. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
  36. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +18 -18
  37. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
  38. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts +4 -5
  39. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
  40. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +59 -80
  41. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
  42. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +4 -5
  43. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
  44. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +23 -24
  45. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
  46. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
  47. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +862 -906
  48. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  49. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +4 -5
  50. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
  51. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +448 -499
  52. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  53. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts +2 -2
  54. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts.map +1 -1
  55. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js +6 -11
  56. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js.map +1 -1
  57. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts +4 -5
  58. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
  59. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +16 -15
  60. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
  61. package/dist/lib/custom/Actions/action-execution-log-form.component.js +160 -166
  62. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  63. package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
  64. package/dist/lib/custom/Actions/action-form.component.js +93 -94
  65. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  66. package/dist/lib/custom/Entities/entity-form.component.js +2 -2
  67. package/dist/lib/custom/Lists/list-form.component.js +61 -63
  68. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  69. package/dist/lib/custom/Queries/query-category-dialog.component.js +33 -59
  70. package/dist/lib/custom/Queries/query-category-dialog.component.js.map +1 -1
  71. package/dist/lib/custom/Queries/query-form.component.js +354 -360
  72. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  73. package/dist/lib/custom/Queries/query-run-dialog.component.js +62 -71
  74. package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
  75. package/dist/lib/custom/Templates/template-param-dialog.component.js +128 -124
  76. package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
  77. package/dist/lib/custom/Templates/template-params-grid.component.d.ts +45 -22
  78. package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
  79. package/dist/lib/custom/Templates/template-params-grid.component.js +380 -384
  80. package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
  81. package/dist/lib/custom/Templates/templates-form.component.js +34 -36
  82. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  83. package/dist/lib/custom/Tests/test-form.component.js +8 -9
  84. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  85. package/dist/lib/custom/Tests/test-run-feedback-form.component.js +4 -4
  86. package/dist/lib/custom/Tests/test-run-feedback-form.component.js.map +1 -1
  87. package/dist/lib/custom/Tests/test-run-form.component.js +7 -7
  88. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  89. package/dist/lib/custom/Tests/test-suite-form.component.js +6 -7
  90. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  91. package/dist/lib/custom/Tests/test-suite-run-form.component.js +6 -7
  92. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  93. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +381 -409
  94. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  95. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
  96. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +1 -1
  97. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
  98. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
  99. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +74 -63
  100. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  101. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +10 -10
  102. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +1 -1
  103. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  104. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +352 -332
  105. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  106. package/dist/lib/custom/custom-forms.module.d.ts +22 -27
  107. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  108. package/dist/lib/custom/custom-forms.module.js +51 -81
  109. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  110. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +4 -5
  111. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
  112. package/dist/lib/custom/shared/entity-selector-dialog.component.js +59 -66
  113. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  114. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  115. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +176 -156
  116. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  117. package/dist/lib/generated/Entities/MJAIAgentClientTool/mjaiagentclienttool.form.component.d.ts +10 -0
  118. package/dist/lib/generated/Entities/MJAIAgentClientTool/mjaiagentclienttool.form.component.d.ts.map +1 -0
  119. package/dist/lib/generated/Entities/MJAIAgentClientTool/mjaiagentclienttool.form.component.js +65 -0
  120. package/dist/lib/generated/Entities/MJAIAgentClientTool/mjaiagentclienttool.form.component.js.map +1 -0
  121. package/dist/lib/generated/Entities/MJAIClientToolDefinition/mjaiclienttooldefinition.form.component.d.ts +10 -0
  122. package/dist/lib/generated/Entities/MJAIClientToolDefinition/mjaiclienttooldefinition.form.component.d.ts.map +1 -0
  123. package/dist/lib/generated/Entities/MJAIClientToolDefinition/mjaiclienttooldefinition.form.component.js +89 -0
  124. package/dist/lib/generated/Entities/MJAIClientToolDefinition/mjaiclienttooldefinition.form.component.js.map +1 -0
  125. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.d.ts.map +1 -1
  126. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +80 -44
  127. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  128. package/dist/lib/generated/Entities/MJContentItemTag/mjcontentitemtag.form.component.js +11 -8
  129. package/dist/lib/generated/Entities/MJContentItemTag/mjcontentitemtag.form.component.js.map +1 -1
  130. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.d.ts.map +1 -1
  131. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +39 -24
  132. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  133. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.d.ts.map +1 -1
  134. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js +35 -17
  135. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js.map +1 -1
  136. package/dist/lib/generated/Entities/MJDuplicateRunDetail/mjduplicaterundetail.form.component.js +15 -13
  137. package/dist/lib/generated/Entities/MJDuplicateRunDetail/mjduplicaterundetail.form.component.js.map +1 -1
  138. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
  139. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +7 -9
  140. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
  141. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.d.ts.map +1 -1
  142. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +21 -9
  143. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  144. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.d.ts.map +1 -1
  145. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js +41 -5
  146. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js.map +1 -1
  147. package/dist/lib/generated/generated-forms.module.d.ts +280 -279
  148. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  149. package/dist/lib/generated/generated-forms.module.js +102 -142
  150. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  151. package/dist/lib/shared/components/template-editor.component.js +14 -15
  152. package/dist/lib/shared/components/template-editor.component.js.map +1 -1
  153. package/package.json +34 -41
@@ -1,209 +1,21 @@
1
- import { Component, Input, ViewChild } from '@angular/core';
1
+ import { Component, Input } from '@angular/core';
2
2
  import { Metadata, RunView } from '@memberjunction/core';
3
3
  import { MJNotificationService } from '@memberjunction/ng-notifications';
4
- import { GridComponent } from '@progress/kendo-angular-grid';
5
- import { FormGroup, FormControl, Validators } from '@angular/forms';
4
+ import { ModuleRegistry, AllCommunityModule, themeAlpine, colorSchemeVariable } from 'ag-grid-community';
6
5
  import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/forms";
8
- import * as i2 from "@progress/kendo-angular-grid";
9
- import * as i3 from "@progress/kendo-angular-inputs";
10
- import * as i4 from "@progress/kendo-angular-dropdowns";
11
- function TemplateParamsGridComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
12
- i0.ɵɵelementStart(0, "kendo-grid-toolbar")(1, "button", 15);
13
- i0.ɵɵelement(2, "i", 16);
6
+ import * as i1 from "ag-grid-angular";
7
+ import * as i2 from "@memberjunction/ng-ui-components";
8
+ function TemplateParamsGridComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
9
+ const _r1 = i0.ɵɵgetCurrentView();
10
+ i0.ɵɵelementStart(0, "div", 4)(1, "button", 7);
11
+ i0.ɵɵlistener("click", function TemplateParamsGridComponent_Conditional_7_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addNewParam()); });
12
+ i0.ɵɵelement(2, "i", 8);
14
13
  i0.ɵɵtext(3, " Add Parameter ");
15
14
  i0.ɵɵelementEnd()();
16
15
  } }
17
- function TemplateParamsGridComponent_ng_template_10_Conditional_3_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "span", 18);
19
- i0.ɵɵelement(1, "i", 19);
20
- i0.ɵɵtext(2, " Required ");
21
- i0.ɵɵelementEnd();
22
- } }
23
- function TemplateParamsGridComponent_ng_template_10_Template(rf, ctx) { if (rf & 1) {
24
- i0.ɵɵelementStart(0, "div", 17)(1, "strong");
25
- i0.ɵɵtext(2);
26
- i0.ɵɵelementEnd();
27
- i0.ɵɵconditionalCreate(3, TemplateParamsGridComponent_ng_template_10_Conditional_3_Template, 3, 0, "span", 18);
28
- i0.ɵɵelementEnd();
29
- } if (rf & 2) {
30
- const dataItem_r1 = ctx.$implicit;
31
- i0.ɵɵadvance(2);
32
- i0.ɵɵtextInterpolate(dataItem_r1.Name);
33
- i0.ɵɵadvance();
34
- i0.ɵɵconditional(dataItem_r1.IsRequired ? 3 : -1);
35
- } }
36
- function TemplateParamsGridComponent_ng_template_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
37
- i0.ɵɵelementStart(0, "span", 21);
38
- i0.ɵɵtext(1, " Parameter name is required ");
39
- i0.ɵɵelementEnd();
40
- } }
41
- function TemplateParamsGridComponent_ng_template_11_Template(rf, ctx) { if (rf & 1) {
42
- i0.ɵɵelement(0, "kendo-textbox", 20);
43
- i0.ɵɵconditionalCreate(1, TemplateParamsGridComponent_ng_template_11_Conditional_1_Template, 2, 0, "span", 21);
44
- } if (rf & 2) {
45
- let tmp_5_0;
46
- const formGroup_r2 = ctx.formGroup;
47
- i0.ɵɵstyleProp("width", 100, "%");
48
- i0.ɵɵproperty("formControl", formGroup_r2.get("name"));
49
- i0.ɵɵadvance();
50
- i0.ɵɵconditional(((tmp_5_0 = formGroup_r2.get("name")) == null ? null : tmp_5_0.touched) && ((tmp_5_0 = formGroup_r2.get("name")) == null ? null : tmp_5_0.errors == null ? null : tmp_5_0.errors["required"]) ? 1 : -1);
51
- } }
52
- function TemplateParamsGridComponent_ng_template_13_Template(rf, ctx) { if (rf & 1) {
53
- i0.ɵɵelementStart(0, "div", 22);
54
- i0.ɵɵelement(1, "i");
55
- i0.ɵɵtext(2);
56
- i0.ɵɵelementEnd();
57
- } if (rf & 2) {
58
- const dataItem_r3 = ctx.$implicit;
59
- const ctx_r3 = i0.ɵɵnextContext();
60
- i0.ɵɵadvance();
61
- i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", ctx_r3.getTypeIcon(dataItem_r3.Type)));
62
- i0.ɵɵadvance();
63
- i0.ɵɵtextInterpolate1(" ", dataItem_r3.Type, " ");
64
- } }
65
- function TemplateParamsGridComponent_ng_template_14_Template(rf, ctx) { if (rf & 1) {
66
- i0.ɵɵelement(0, "kendo-dropdownlist", 23);
67
- } if (rf & 2) {
68
- const formGroup_r5 = ctx.formGroup;
69
- const ctx_r3 = i0.ɵɵnextContext();
70
- i0.ɵɵstyleProp("width", 100, "%");
71
- i0.ɵɵproperty("formControl", formGroup_r5.get("type"))("data", ctx_r3.typeOptions)("valuePrimitive", true);
72
- } }
73
- function TemplateParamsGridComponent_ng_template_16_Conditional_1_Template(rf, ctx) { if (rf & 1) {
74
- i0.ɵɵelement(0, "i", 25);
75
- } }
76
- function TemplateParamsGridComponent_ng_template_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
77
- i0.ɵɵelement(0, "i", 26);
78
- } }
79
- function TemplateParamsGridComponent_ng_template_16_Template(rf, ctx) { if (rf & 1) {
80
- i0.ɵɵelementStart(0, "div", 24);
81
- i0.ɵɵconditionalCreate(1, TemplateParamsGridComponent_ng_template_16_Conditional_1_Template, 1, 0, "i", 25);
82
- i0.ɵɵconditionalCreate(2, TemplateParamsGridComponent_ng_template_16_Conditional_2_Template, 1, 0, "i", 26);
83
- i0.ɵɵelementEnd();
84
- } if (rf & 2) {
85
- const dataItem_r6 = ctx.$implicit;
86
- i0.ɵɵadvance();
87
- i0.ɵɵconditional(dataItem_r6.IsRequired ? 1 : -1);
88
- i0.ɵɵadvance();
89
- i0.ɵɵconditional(!dataItem_r6.IsRequired ? 2 : -1);
90
- } }
91
- function TemplateParamsGridComponent_ng_template_17_Template(rf, ctx) { if (rf & 1) {
92
- i0.ɵɵelement(0, "kendo-switch", 27);
93
- } if (rf & 2) {
94
- const formGroup_r7 = ctx.formGroup;
95
- i0.ɵɵproperty("formControl", formGroup_r7.get("isRequired"));
96
- } }
97
- function TemplateParamsGridComponent_ng_template_19_Template(rf, ctx) { if (rf & 1) {
98
- i0.ɵɵelementStart(0, "div", 28);
99
- i0.ɵɵtext(1);
100
- i0.ɵɵelementEnd();
101
- } if (rf & 2) {
102
- const dataItem_r8 = ctx.$implicit;
103
- i0.ɵɵadvance();
104
- i0.ɵɵtextInterpolate1(" ", dataItem_r8.Description || "(No description)", " ");
105
- } }
106
- function TemplateParamsGridComponent_ng_template_20_Template(rf, ctx) { if (rf & 1) {
107
- i0.ɵɵelement(0, "kendo-textarea", 29);
108
- } if (rf & 2) {
109
- const formGroup_r9 = ctx.formGroup;
110
- i0.ɵɵstyleProp("width", 100, "%");
111
- i0.ɵɵproperty("formControl", formGroup_r9.get("description"))("rows", 2);
112
- } }
113
- function TemplateParamsGridComponent_ng_template_22_Conditional_0_Template(rf, ctx) { if (rf & 1) {
114
- i0.ɵɵelementStart(0, "code", 30);
115
- i0.ɵɵtext(1);
116
- i0.ɵɵelementEnd();
117
- } if (rf & 2) {
118
- const dataItem_r10 = i0.ɵɵnextContext().$implicit;
119
- i0.ɵɵadvance();
120
- i0.ɵɵtextInterpolate(dataItem_r10.DefaultValue);
121
- } }
122
- function TemplateParamsGridComponent_ng_template_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
123
- i0.ɵɵelementStart(0, "span", 31);
124
- i0.ɵɵtext(1, "(No default)");
125
- i0.ɵɵelementEnd();
126
- } }
127
- function TemplateParamsGridComponent_ng_template_22_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵconditionalCreate(0, TemplateParamsGridComponent_ng_template_22_Conditional_0_Template, 2, 1, "code", 30);
129
- i0.ɵɵconditionalCreate(1, TemplateParamsGridComponent_ng_template_22_Conditional_1_Template, 2, 0, "span", 31);
130
- } if (rf & 2) {
131
- const dataItem_r10 = ctx.$implicit;
132
- i0.ɵɵconditional(dataItem_r10.DefaultValue ? 0 : -1);
133
- i0.ɵɵadvance();
134
- i0.ɵɵconditional(!dataItem_r10.DefaultValue ? 1 : -1);
135
- } }
136
- function TemplateParamsGridComponent_ng_template_23_Template(rf, ctx) { if (rf & 1) {
137
- i0.ɵɵelement(0, "kendo-textarea", 32);
138
- } if (rf & 2) {
139
- const formGroup_r11 = ctx.formGroup;
140
- i0.ɵɵstyleProp("width", 100, "%");
141
- i0.ɵɵproperty("formControl", formGroup_r11.get("defaultValue"))("rows", 2);
142
- } }
143
- function TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
144
- i0.ɵɵelementStart(0, "button", 33);
145
- i0.ɵɵelement(1, "i", 37);
146
- i0.ɵɵelementEnd();
147
- } }
148
- function TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
149
- i0.ɵɵelementStart(0, "button", 34);
150
- i0.ɵɵelement(1, "i", 38);
151
- i0.ɵɵelementEnd();
152
- } }
153
- function TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
154
- i0.ɵɵelementStart(0, "button", 35);
155
- i0.ɵɵelement(1, "i", 39);
156
- i0.ɵɵelementEnd();
157
- } }
158
- function TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
159
- i0.ɵɵelementStart(0, "button", 36);
160
- i0.ɵɵelement(1, "i", 40);
161
- i0.ɵɵelementEnd();
162
- } }
163
- function TemplateParamsGridComponent_Conditional_24_ng_template_1_Template(rf, ctx) { if (rf & 1) {
164
- i0.ɵɵconditionalCreate(0, TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_0_Template, 2, 0, "button", 33);
165
- i0.ɵɵconditionalCreate(1, TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_1_Template, 2, 0, "button", 34);
166
- i0.ɵɵconditionalCreate(2, TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_2_Template, 2, 0, "button", 35);
167
- i0.ɵɵconditionalCreate(3, TemplateParamsGridComponent_Conditional_24_ng_template_1_Conditional_3_Template, 2, 0, "button", 36);
168
- } if (rf & 2) {
169
- const rowIndex_r12 = ctx.rowIndex;
170
- const ctx_r3 = i0.ɵɵnextContext(2);
171
- i0.ɵɵconditional(!ctx_r3.isInEditMode(rowIndex_r12) ? 0 : -1);
172
- i0.ɵɵadvance();
173
- i0.ɵɵconditional(!ctx_r3.isInEditMode(rowIndex_r12) ? 1 : -1);
174
- i0.ɵɵadvance();
175
- i0.ɵɵconditional(ctx_r3.isInEditMode(rowIndex_r12) ? 2 : -1);
176
- i0.ɵɵadvance();
177
- i0.ɵɵconditional(ctx_r3.isInEditMode(rowIndex_r12) ? 3 : -1);
178
- } }
179
- function TemplateParamsGridComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
180
- i0.ɵɵelementStart(0, "kendo-grid-column", 12);
181
- i0.ɵɵtemplate(1, TemplateParamsGridComponent_Conditional_24_ng_template_1_Template, 4, 4, "ng-template", 6);
182
- i0.ɵɵelementEnd();
183
- } if (rf & 2) {
184
- i0.ɵɵproperty("width", 120);
185
- } }
186
- function TemplateParamsGridComponent_ng_template_25_Conditional_4_Template(rf, ctx) { if (rf & 1) {
187
- i0.ɵɵelementStart(0, "p");
188
- i0.ɵɵtext(1, "Click \"Add Parameter\" to create your first parameter.");
189
- i0.ɵɵelementEnd();
190
- } }
191
- function TemplateParamsGridComponent_ng_template_25_Template(rf, ctx) { if (rf & 1) {
192
- i0.ɵɵelementStart(0, "div", 41);
193
- i0.ɵɵelement(1, "i", 42);
194
- i0.ɵɵelementStart(2, "p");
195
- i0.ɵɵtext(3, "No parameters defined for this template.");
196
- i0.ɵɵelementEnd();
197
- i0.ɵɵconditionalCreate(4, TemplateParamsGridComponent_ng_template_25_Conditional_4_Template, 2, 0, "p");
198
- i0.ɵɵelementEnd();
199
- } if (rf & 2) {
200
- const ctx_r3 = i0.ɵɵnextContext();
201
- i0.ɵɵadvance(4);
202
- i0.ɵɵconditional(ctx_r3.editMode ? 4 : -1);
203
- } }
204
- function TemplateParamsGridComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
205
- i0.ɵɵelementStart(0, "div", 14)(1, "h4");
206
- i0.ɵɵelement(2, "i", 43);
16
+ function TemplateParamsGridComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "div", 6)(1, "h4");
18
+ i0.ɵɵelement(2, "i", 9);
207
19
  i0.ɵɵtext(3, " Parameter Types");
208
20
  i0.ɵɵelementEnd();
209
21
  i0.ɵɵelementStart(4, "ul")(5, "li")(6, "strong");
@@ -231,8 +43,8 @@ function TemplateParamsGridComponent_Conditional_26_Template(rf, ctx) { if (rf &
231
43
  i0.ɵɵelementEnd();
232
44
  i0.ɵɵtext(24, " Multiple records from a MemberJunction entity (can be filtered)");
233
45
  i0.ɵɵelementEnd()();
234
- i0.ɵɵelementStart(25, "p", 44);
235
- i0.ɵɵelement(26, "i", 45);
46
+ i0.ɵɵelementStart(25, "p", 10);
47
+ i0.ɵɵelement(26, "i", 11);
236
48
  i0.ɵɵtext(27, " Use parameters in your template with the syntax: ");
237
49
  i0.ɵɵelementStart(28, "code");
238
50
  i0.ɵɵtext(29);
@@ -241,25 +53,42 @@ function TemplateParamsGridComponent_Conditional_26_Template(rf, ctx) { if (rf &
241
53
  i0.ɵɵadvance(29);
242
54
  i0.ɵɵtextInterpolate2("", "{{", " parameterName ", "}}");
243
55
  } }
56
+ // Register AG Grid modules
57
+ ModuleRegistry.registerModules([AllCommunityModule]);
244
58
  export class TemplateParamsGridComponent {
245
59
  constructor() {
246
60
  this.template = null;
247
61
  this.editMode = false;
248
62
  this.templateParams = [];
249
63
  this.isLoading = false;
250
- // Grid editing
251
- this.editedRowIndex = undefined;
252
- this.editedParam = null;
253
64
  // Type options for dropdown
254
- this.typeOptions = [
255
- { text: 'Scalar', value: 'Scalar' },
256
- { text: 'Array', value: 'Array' },
257
- { text: 'Object', value: 'Object' },
258
- { text: 'Record', value: 'Record' },
259
- { text: 'Entity', value: 'Entity' }
260
- ];
65
+ this.typeOptions = ['Scalar', 'Array', 'Object', 'Record', 'Entity'];
66
+ // AG Grid configuration
67
+ this.ColumnDefs = [];
68
+ this.DefaultColDef = {
69
+ sortable: true,
70
+ resizable: true,
71
+ filter: false,
72
+ flex: 1
73
+ };
74
+ this.GridTheme = themeAlpine.withPart(colorSchemeVariable);
75
+ this.gridApi = null;
76
+ /** Row currently being edited (for cancel/revert) */
77
+ this.editingRowBackup = null;
78
+ this.editingRowId = null;
79
+ this.noRowsTemplate = `
80
+ <div style="text-align: center; padding: 40px 20px; color: var(--mj-text-muted);">
81
+ <i class="fa-solid fa-info-circle" style="font-size: 2em; margin-bottom: 10px;"></i>
82
+ <p>No parameters defined for this template.</p>
83
+ </div>
84
+ `;
85
+ this.getRowId = (params) => {
86
+ // Use entity ID if saved, otherwise use a temporary key
87
+ return params.data.ID || `new_${params.data.Name}_${Date.now()}`;
88
+ };
261
89
  }
262
90
  ngOnInit() {
91
+ this.buildColumnDefs();
263
92
  if (this.template?.ID) {
264
93
  this.loadTemplateParams();
265
94
  }
@@ -268,6 +97,12 @@ export class TemplateParamsGridComponent {
268
97
  if (changes['template'] && this.template?.ID) {
269
98
  this.loadTemplateParams();
270
99
  }
100
+ if (changes['editMode']) {
101
+ this.buildColumnDefs();
102
+ }
103
+ }
104
+ onGridReady(event) {
105
+ this.gridApi = event.api;
271
106
  }
272
107
  async loadTemplateParams() {
273
108
  if (!this.template?.ID)
@@ -278,10 +113,12 @@ export class TemplateParamsGridComponent {
278
113
  const results = await rv.RunView({
279
114
  EntityName: 'MJ: Template Params',
280
115
  ExtraFilter: `TemplateID='${this.template.ID}'`,
281
- OrderBy: 'Name ASC'
116
+ OrderBy: 'Name ASC',
117
+ ResultType: 'entity_object'
282
118
  });
283
119
  if (results.Success) {
284
- this.templateParams = results.Results || [];
120
+ const entities = results.Results || [];
121
+ this.templateParams = entities.map(e => this.entityToRowData(e));
285
122
  }
286
123
  else {
287
124
  console.error('Failed to load template params:', results.ErrorMessage);
@@ -296,138 +133,177 @@ export class TemplateParamsGridComponent {
296
133
  this.isLoading = false;
297
134
  }
298
135
  }
299
- // Grid editing handlers
300
- addHandler(args) {
136
+ // -- Grid editing lifecycle --
137
+ async addNewParam() {
301
138
  if (!this.editMode || !this.template?.ID)
302
139
  return;
303
- // Create new parameter entity
304
- this.createNewParam().then(newParam => {
305
- if (newParam) {
306
- // Close any existing edits
307
- this.closeEditor();
308
- // Add to array at the beginning
309
- this.templateParams = [newParam, ...this.templateParams];
310
- // Enter edit mode for the new row
311
- this.editedRowIndex = 0;
312
- this.editedParam = newParam;
313
- this.formGroup = this.createFormGroup(newParam);
314
- // Close the add new row
315
- this.grid.closeRow(args.rowIndex);
316
- // Edit the newly added row
317
- this.grid.editRow(0, this.formGroup);
140
+ // Cancel any in-progress edit first
141
+ this.cancelCurrentEdit();
142
+ const newEntity = await this.createNewParamEntity();
143
+ if (!newEntity)
144
+ return;
145
+ const newRow = this.entityToRowData(newEntity);
146
+ newRow.IsNew = true;
147
+ // Prepend the new row
148
+ this.templateParams = [newRow, ...this.templateParams];
149
+ // Wait for grid to process the new row, then start editing it
150
+ setTimeout(() => {
151
+ if (!this.gridApi)
152
+ return;
153
+ const rowNode = this.gridApi.getDisplayedRowAtIndex(0);
154
+ if (rowNode) {
155
+ this.editingRowId = rowNode.id ?? null;
156
+ this.editingRowBackup = { ...newRow };
157
+ this.gridApi.startEditingCell({
158
+ rowIndex: 0,
159
+ colKey: 'Name'
160
+ });
161
+ this.gridApi.refreshCells({ columns: ['actions'], force: true });
318
162
  }
319
163
  });
320
164
  }
321
- editHandler(args) {
322
- if (!this.editMode)
165
+ startEditRow(params) {
166
+ if (!this.gridApi || !this.editMode)
323
167
  return;
324
- const { dataItem, rowIndex } = args;
325
- // Close any existing edits
326
- this.closeEditor();
327
- // Set up editing
328
- this.editedRowIndex = rowIndex;
329
- this.editedParam = dataItem;
330
- this.formGroup = this.createFormGroup(dataItem);
168
+ // Cancel any in-progress edit first
169
+ this.cancelCurrentEdit();
170
+ const rowIndex = params.node.rowIndex;
171
+ if (rowIndex == null)
172
+ return;
173
+ this.editingRowId = params.node.id ?? null;
174
+ this.editingRowBackup = { ...params.data };
175
+ this.gridApi.startEditingCell({
176
+ rowIndex,
177
+ colKey: 'Name'
178
+ });
179
+ this.gridApi.refreshCells({ columns: ['actions'], force: true });
331
180
  }
332
- cancelHandler(args) {
333
- const { rowIndex, dataItem } = args;
334
- // If this is a new unsaved parameter, remove it
335
- if (!dataItem.ID && rowIndex !== undefined) {
336
- this.templateParams.splice(rowIndex, 1);
337
- this.templateParams = [...this.templateParams];
338
- }
339
- this.closeEditor();
181
+ cancelEditRow() {
182
+ this.cancelCurrentEdit();
340
183
  }
341
- async saveHandler(args) {
342
- if (!this.formGroup || !this.formGroup.valid)
184
+ saveEditRow() {
185
+ if (!this.gridApi)
343
186
  return;
344
- const { dataItem, rowIndex } = args;
345
- const formValue = this.formGroup.value;
346
- // Update the entity with form values
347
- dataItem.Name = formValue.name;
348
- dataItem.Type = formValue.type;
349
- dataItem.IsRequired = formValue.isRequired;
350
- dataItem.Description = formValue.description;
351
- dataItem.DefaultValue = formValue.defaultValue;
352
- // Handle linked parameter fields for Entity type
353
- if (formValue.type === 'Entity') {
354
- dataItem.LinkedParameterName = formValue.linkedParameterName;
355
- dataItem.LinkedParameterField = formValue.linkedParameterField;
356
- }
357
- else {
358
- dataItem.LinkedParameterName = null;
359
- dataItem.LinkedParameterField = null;
360
- }
361
- try {
362
- const saved = await dataItem.Save();
363
- if (saved) {
364
- MJNotificationService.Instance.CreateSimpleNotification(`Parameter "${dataItem.Name}" saved successfully`, 'success');
365
- // Update the array to trigger change detection
366
- this.templateParams = [...this.templateParams];
187
+ // stopEditing triggers onRowEditingStopped, which handles the save
188
+ this.gridApi.stopEditing(false);
189
+ this.gridApi.refreshCells({ columns: ['actions'], force: true });
190
+ }
191
+ async onRowEditingStopped(event) {
192
+ const rowData = event.data;
193
+ if (!rowData)
194
+ return;
195
+ // If the user cancelled (via Escape or cancel button backup restore), skip save
196
+ if (this.editingRowBackup === null)
197
+ return;
198
+ // Validate: Name is required
199
+ if (!rowData.Name || rowData.Name.trim().length === 0) {
200
+ MJNotificationService.Instance.CreateSimpleNotification('Parameter name is required', 'error');
201
+ // If it was a new unsaved row, remove it
202
+ if (rowData.IsNew) {
203
+ this.templateParams = this.templateParams.filter(p => p !== rowData);
367
204
  }
368
- else {
369
- MJNotificationService.Instance.CreateSimpleNotification(`Failed to save parameter: ${dataItem.LatestResult?.Message || 'Unknown error'}`, 'error');
370
- // Reload to revert changes
371
- await this.loadTemplateParams();
205
+ else if (this.editingRowBackup) {
206
+ // Revert to backup
207
+ this.revertRow(event.node, this.editingRowBackup);
372
208
  }
209
+ this.clearEditState();
210
+ return;
373
211
  }
374
- catch (error) {
375
- console.error('Error saving parameter:', error);
376
- MJNotificationService.Instance.CreateSimpleNotification('Error saving parameter', 'error');
377
- // Reload to revert changes
378
- await this.loadTemplateParams();
379
- }
380
- this.closeEditor();
212
+ await this.saveParamRow(rowData);
213
+ this.clearEditState();
381
214
  }
382
- async removeHandler(args) {
215
+ async deleteRow(params) {
383
216
  if (!this.editMode)
384
217
  return;
385
- const param = args.dataItem;
386
- if (!confirm(`Are you sure you want to delete the parameter "${param.Name}"?`)) {
218
+ const rowData = params.data;
219
+ const entity = rowData.Entity;
220
+ if (!confirm(`Are you sure you want to delete the parameter "${rowData.Name}"?`)) {
387
221
  return;
388
222
  }
389
223
  try {
390
- if (param.ID) {
391
- const deleted = await param.Delete();
224
+ if (entity.ID) {
225
+ const deleted = await entity.Delete();
392
226
  if (deleted) {
393
- MJNotificationService.Instance.CreateSimpleNotification(`Parameter "${param.Name}" deleted successfully`, 'success');
394
- // Remove from array
395
- const index = this.templateParams.indexOf(param);
396
- if (index > -1) {
397
- this.templateParams.splice(index, 1);
398
- this.templateParams = [...this.templateParams];
399
- }
227
+ MJNotificationService.Instance.CreateSimpleNotification(`Parameter "${rowData.Name}" deleted successfully`, 'success');
228
+ this.templateParams = this.templateParams.filter(p => p !== rowData);
400
229
  }
401
230
  else {
402
- MJNotificationService.Instance.CreateSimpleNotification(`Failed to delete parameter: ${param.LatestResult?.Message || 'Unknown error'}`, 'error');
231
+ MJNotificationService.Instance.CreateSimpleNotification(`Failed to delete parameter: ${entity.LatestResult?.Message || 'Unknown error'}`, 'error');
403
232
  }
404
233
  }
234
+ else {
235
+ // Not yet saved -- just remove from the array
236
+ this.templateParams = this.templateParams.filter(p => p !== rowData);
237
+ }
405
238
  }
406
239
  catch (error) {
407
240
  console.error('Error deleting parameter:', error);
408
241
  MJNotificationService.Instance.CreateSimpleNotification('Error deleting parameter', 'error');
409
242
  }
410
243
  }
411
- createFormGroup(param) {
412
- return new FormGroup({
413
- name: new FormControl(param.Name, Validators.required),
414
- type: new FormControl(param.Type || 'Scalar', Validators.required),
415
- isRequired: new FormControl(param.IsRequired || false),
416
- description: new FormControl(param.Description),
417
- defaultValue: new FormControl(param.DefaultValue),
418
- linkedParameterName: new FormControl(param.LinkedParameterName),
419
- linkedParameterField: new FormControl(param.LinkedParameterField)
420
- });
244
+ // -- Helpers --
245
+ getTypeIcon(type) {
246
+ switch (type) {
247
+ case 'Scalar': return 'fa-font';
248
+ case 'Array': return 'fa-list';
249
+ case 'Object': return 'fa-cube';
250
+ case 'Record': return 'fa-file';
251
+ case 'Entity': return 'fa-table';
252
+ default: return 'fa-question';
253
+ }
254
+ }
255
+ entityToRowData(entity) {
256
+ return {
257
+ Entity: entity,
258
+ ID: entity.ID || '',
259
+ Name: entity.Name || '',
260
+ Type: entity.Type || 'Scalar',
261
+ IsRequired: entity.IsRequired || false,
262
+ Description: entity.Description || '',
263
+ DefaultValue: entity.DefaultValue || '',
264
+ LinkedParameterName: entity.LinkedParameterName || '',
265
+ LinkedParameterField: entity.LinkedParameterField || '',
266
+ IsNew: false
267
+ };
421
268
  }
422
- closeEditor() {
423
- if (this.editedRowIndex !== undefined) {
424
- this.grid.closeRow(this.editedRowIndex);
269
+ async saveParamRow(rowData) {
270
+ const entity = rowData.Entity;
271
+ entity.Name = rowData.Name;
272
+ entity.Type = rowData.Type;
273
+ entity.IsRequired = rowData.IsRequired;
274
+ entity.Description = rowData.Description;
275
+ entity.DefaultValue = rowData.DefaultValue;
276
+ // Handle linked parameter fields for Entity type
277
+ if (rowData.Type === 'Entity') {
278
+ entity.LinkedParameterName = rowData.LinkedParameterName;
279
+ entity.LinkedParameterField = rowData.LinkedParameterField;
280
+ }
281
+ else {
282
+ entity.LinkedParameterName = null;
283
+ entity.LinkedParameterField = null;
284
+ }
285
+ try {
286
+ const saved = await entity.Save();
287
+ if (saved) {
288
+ MJNotificationService.Instance.CreateSimpleNotification(`Parameter "${entity.Name}" saved successfully`, 'success');
289
+ // Update the row data with the saved entity ID
290
+ rowData.ID = entity.ID;
291
+ rowData.IsNew = false;
292
+ // Refresh the grid to pick up the new ID
293
+ this.templateParams = [...this.templateParams];
294
+ }
295
+ else {
296
+ MJNotificationService.Instance.CreateSimpleNotification(`Failed to save parameter: ${entity.LatestResult?.Message || 'Unknown error'}`, 'error');
297
+ await this.loadTemplateParams();
298
+ }
299
+ }
300
+ catch (error) {
301
+ console.error('Error saving parameter:', error);
302
+ MJNotificationService.Instance.CreateSimpleNotification('Error saving parameter', 'error');
303
+ await this.loadTemplateParams();
425
304
  }
426
- this.editedRowIndex = undefined;
427
- this.editedParam = null;
428
- this.formGroup = undefined;
429
305
  }
430
- async createNewParam() {
306
+ async createNewParamEntity() {
431
307
  if (!this.template?.ID)
432
308
  return null;
433
309
  try {
@@ -443,38 +319,122 @@ export class TemplateParamsGridComponent {
443
319
  return null;
444
320
  }
445
321
  }
446
- isInEditMode(rowIndex) {
447
- return this.editedRowIndex === rowIndex;
448
- }
449
- // Helper for displaying type with icon
450
- getTypeIcon(type) {
451
- switch (type) {
452
- case 'Scalar': return 'fa-font';
453
- case 'Array': return 'fa-list';
454
- case 'Object': return 'fa-cube';
455
- case 'Record': return 'fa-file';
456
- case 'Entity': return 'fa-table';
457
- default: return 'fa-question';
322
+ cancelCurrentEdit() {
323
+ if (!this.gridApi)
324
+ return;
325
+ if (this.editingRowBackup && this.editingRowId) {
326
+ const rowNode = this.gridApi.getRowNode(this.editingRowId);
327
+ if (rowNode) {
328
+ // If the row was new and unsaved, remove it
329
+ if (this.editingRowBackup.IsNew) {
330
+ const backup = this.editingRowBackup;
331
+ this.clearEditState();
332
+ this.gridApi.stopEditing(true);
333
+ this.templateParams = this.templateParams.filter(p => p.Entity !== backup.Entity);
334
+ return;
335
+ }
336
+ // Revert to backup
337
+ this.revertRow(rowNode, this.editingRowBackup);
338
+ }
458
339
  }
340
+ this.clearEditState();
341
+ this.gridApi.stopEditing(true);
342
+ this.gridApi.refreshCells({ columns: ['actions'], force: true });
459
343
  }
460
- // Helper for type descriptions
461
- getTypeDescription(type) {
462
- switch (type) {
463
- case 'Scalar': return 'Single value (text, number, etc.)';
464
- case 'Array': return 'List of values';
465
- case 'Object': return 'JSON object';
466
- case 'Record': return 'Single record from an entity';
467
- case 'Entity': return 'Multiple records from an entity';
468
- default: return '';
344
+ revertRow(rowNode, backup) {
345
+ rowNode.setData(backup);
346
+ }
347
+ clearEditState() {
348
+ this.editingRowBackup = null;
349
+ this.editingRowId = null;
350
+ }
351
+ buildColumnDefs() {
352
+ const self = this;
353
+ const cols = [
354
+ {
355
+ field: 'Name',
356
+ headerName: 'Parameter Name',
357
+ width: 200,
358
+ editable: this.editMode,
359
+ cellRenderer: (params) => {
360
+ if (!params.value)
361
+ return '';
362
+ const row = params.data;
363
+ let html = `<strong>${params.value}</strong>`;
364
+ if (row.IsRequired) {
365
+ html += ` <span style="display: inline-flex; align-items: center; gap: 4px; background-color: var(--mj-status-error); color: var(--mj-text-inverse); padding: 2px 8px; border-radius: 12px; font-size: 0.75em; font-weight: 500;"><i class="fa-solid fa-asterisk" style="font-size: 0.6em;"></i> Required</span>`;
366
+ }
367
+ return html;
368
+ }
369
+ },
370
+ {
371
+ field: 'Type',
372
+ headerName: 'Type',
373
+ width: 140,
374
+ editable: this.editMode,
375
+ cellEditor: 'agSelectCellEditor',
376
+ cellEditorParams: {
377
+ values: this.typeOptions
378
+ },
379
+ cellRenderer: (params) => {
380
+ if (!params.value)
381
+ return '';
382
+ const icon = self.getTypeIcon(params.value);
383
+ return `<span style="display: flex; align-items: center; gap: 6px; color: var(--mj-text-secondary);"><i class="fa-solid ${icon}" style="color: var(--mj-text-muted);"></i> ${params.value}</span>`;
384
+ }
385
+ },
386
+ {
387
+ field: 'IsRequired',
388
+ headerName: 'Required',
389
+ width: 100,
390
+ editable: this.editMode,
391
+ cellDataType: 'boolean',
392
+ cellRenderer: (params) => {
393
+ if (params.value) {
394
+ return `<div style="text-align: center;"><i class="fa-solid fa-check" style="color: var(--mj-status-success);"></i></div>`;
395
+ }
396
+ return `<div style="text-align: center;"><i class="fa-solid fa-times" style="color: var(--mj-text-muted);"></i></div>`;
397
+ }
398
+ },
399
+ {
400
+ field: 'Description',
401
+ headerName: 'Description',
402
+ width: 300,
403
+ editable: this.editMode,
404
+ cellRenderer: (params) => {
405
+ return params.value || '<span style="color: var(--mj-text-muted); font-style: italic; font-size: 0.9em;">(No description)</span>';
406
+ }
407
+ },
408
+ {
409
+ field: 'DefaultValue',
410
+ headerName: 'Default Value',
411
+ width: 200,
412
+ editable: this.editMode,
413
+ cellRenderer: (params) => {
414
+ if (params.value) {
415
+ return `<code style="background-color: var(--mj-bg-surface-card); padding: 2px 6px; border-radius: 3px; font-size: 0.85em; color: var(--mj-text-secondary);">${params.value}</code>`;
416
+ }
417
+ return '<span style="color: var(--mj-text-muted); font-style: italic; font-size: 0.9em;">(No default)</span>';
418
+ }
419
+ }
420
+ ];
421
+ if (this.editMode) {
422
+ cols.push({
423
+ headerName: 'Actions',
424
+ width: 120,
425
+ sortable: false,
426
+ resizable: false,
427
+ editable: false,
428
+ cellRenderer: ActionsCellRenderer,
429
+ cellRendererParams: {
430
+ componentRef: self
431
+ }
432
+ });
469
433
  }
434
+ this.ColumnDefs = cols;
470
435
  }
471
436
  static { this.ɵfac = function TemplateParamsGridComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TemplateParamsGridComponent)(); }; }
472
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TemplateParamsGridComponent, selectors: [["mj-template-params-grid"]], viewQuery: function TemplateParamsGridComponent_Query(rf, ctx) { if (rf & 1) {
473
- i0.ɵɵviewQuery(GridComponent, 5);
474
- } if (rf & 2) {
475
- let _t;
476
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.grid = _t.first);
477
- } }, inputs: { template: "template", editMode: "editMode" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 27, vars: 14, consts: [[1, "template-params-grid"], [1, "params-header"], [1, "fa-solid", "fa-sliders"], [1, "params-description"], [3, "add", "edit", "cancel", "save", "remove", "data", "loading", "height", "pageable", "sortable", "resizable"], ["field", "Name", "title", "Parameter Name", 3, "width"], ["kendoGridCellTemplate", ""], ["kendoGridEditTemplate", ""], ["field", "Type", "title", "Type", 3, "width"], ["field", "IsRequired", "title", "Required", 3, "width"], ["field", "Description", "title", "Description", 3, "width"], ["field", "DefaultValue", "title", "Default Value", 3, "width"], ["title", "Actions", 3, "width"], ["kendoGridNoRecordsTemplate", ""], [1, "params-help"], ["kendoGridAddCommand", "", "type", "button", 1, "k-button", "k-button-md", "k-rounded-md", "k-button-solid", "k-button-solid-primary"], [1, "fa-solid", "fa-plus"], [1, "param-name"], [1, "required-badge"], [1, "fa-solid", "fa-asterisk"], ["placeholder", "Enter parameter name...", 3, "formControl"], [1, "k-invalid-msg"], [1, "param-type"], ["textField", "text", "valueField", "value", 3, "formControl", "data", "valuePrimitive"], [1, "text-center"], [1, "fa-solid", "fa-check", "text-success"], [1, "fa-solid", "fa-times", "text-muted"], [3, "formControl"], [1, "param-description"], ["placeholder", "Enter parameter description...", 3, "formControl", "rows"], [1, "default-value"], [1, "text-muted"], ["placeholder", "Enter default value...", 3, "formControl", "rows"], ["kendoGridEditCommand", "", "type", "button", "title", "Edit parameter", 1, "k-button", "k-button-md", "k-rounded-md", "k-button-solid", "k-button-solid-base"], ["kendoGridRemoveCommand", "", "type", "button", "title", "Delete parameter", 1, "k-button", "k-button-md", "k-rounded-md", "k-button-solid", "k-button-solid-base"], ["kendoGridSaveCommand", "", "type", "button", "title", "Save changes", 1, "k-button", "k-button-md", "k-rounded-md", "k-button-solid", "k-button-solid-primary"], ["kendoGridCancelCommand", "", "type", "button", "title", "Cancel changes", 1, "k-button", "k-button-md", "k-rounded-md", "k-button-solid", "k-button-solid-base"], [1, "fa-solid", "fa-edit"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-check"], [1, "fa-solid", "fa-times"], [1, "no-params-message"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-question-circle"], [1, "help-note"], [1, "fa-solid", "fa-lightbulb"]], template: function TemplateParamsGridComponent_Template(rf, ctx) { if (rf & 1) {
437
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TemplateParamsGridComponent, selectors: [["mj-template-params-grid"]], inputs: { template: "template", editMode: "editMode" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 10, vars: 10, consts: [[1, "template-params-grid"], [1, "params-header"], [1, "fa-solid", "fa-sliders"], [1, "params-description"], [1, "params-toolbar"], [1, "params-ag-grid", 2, "width", "100%", "height", "400px", 3, "gridReady", "rowEditingStopped", "theme", "rowData", "columnDefs", "defaultColDef", "editType", "getRowId", "suppressClickEdit", "overlayNoRowsTemplate"], [1, "params-help"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-question-circle"], [1, "help-note"], [1, "fa-solid", "fa-lightbulb"]], template: function TemplateParamsGridComponent_Template(rf, ctx) { if (rf & 1) {
478
438
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "h3");
479
439
  i0.ɵɵelement(3, "i", 2);
480
440
  i0.ɵɵtext(4, " Template Parameters");
@@ -482,60 +442,96 @@ export class TemplateParamsGridComponent {
482
442
  i0.ɵɵelementStart(5, "p", 3);
483
443
  i0.ɵɵtext(6, " Define the parameters that can be used within this template. Parameters allow dynamic content injection at runtime. ");
484
444
  i0.ɵɵelementEnd()();
485
- i0.ɵɵelementStart(7, "kendo-grid", 4);
486
- i0.ɵɵlistener("add", function TemplateParamsGridComponent_Template_kendo_grid_add_7_listener($event) { return ctx.addHandler($event); })("edit", function TemplateParamsGridComponent_Template_kendo_grid_edit_7_listener($event) { return ctx.editHandler($event); })("cancel", function TemplateParamsGridComponent_Template_kendo_grid_cancel_7_listener($event) { return ctx.cancelHandler($event); })("save", function TemplateParamsGridComponent_Template_kendo_grid_save_7_listener($event) { return ctx.saveHandler($event); })("remove", function TemplateParamsGridComponent_Template_kendo_grid_remove_7_listener($event) { return ctx.removeHandler($event); });
487
- i0.ɵɵconditionalCreate(8, TemplateParamsGridComponent_Conditional_8_Template, 4, 0, "kendo-grid-toolbar");
488
- i0.ɵɵelementStart(9, "kendo-grid-column", 5);
489
- i0.ɵɵtemplate(10, TemplateParamsGridComponent_ng_template_10_Template, 4, 2, "ng-template", 6)(11, TemplateParamsGridComponent_ng_template_11_Template, 2, 4, "ng-template", 7);
490
- i0.ɵɵelementEnd();
491
- i0.ɵɵelementStart(12, "kendo-grid-column", 8);
492
- i0.ɵɵtemplate(13, TemplateParamsGridComponent_ng_template_13_Template, 3, 4, "ng-template", 6)(14, TemplateParamsGridComponent_ng_template_14_Template, 1, 5, "ng-template", 7);
493
- i0.ɵɵelementEnd();
494
- i0.ɵɵelementStart(15, "kendo-grid-column", 9);
495
- i0.ɵɵtemplate(16, TemplateParamsGridComponent_ng_template_16_Template, 3, 2, "ng-template", 6)(17, TemplateParamsGridComponent_ng_template_17_Template, 1, 1, "ng-template", 7);
496
- i0.ɵɵelementEnd();
497
- i0.ɵɵelementStart(18, "kendo-grid-column", 10);
498
- i0.ɵɵtemplate(19, TemplateParamsGridComponent_ng_template_19_Template, 2, 1, "ng-template", 6)(20, TemplateParamsGridComponent_ng_template_20_Template, 1, 4, "ng-template", 7);
499
- i0.ɵɵelementEnd();
500
- i0.ɵɵelementStart(21, "kendo-grid-column", 11);
501
- i0.ɵɵtemplate(22, TemplateParamsGridComponent_ng_template_22_Template, 2, 2, "ng-template", 6)(23, TemplateParamsGridComponent_ng_template_23_Template, 1, 4, "ng-template", 7);
445
+ i0.ɵɵconditionalCreate(7, TemplateParamsGridComponent_Conditional_7_Template, 4, 0, "div", 4);
446
+ i0.ɵɵelementStart(8, "ag-grid-angular", 5);
447
+ i0.ɵɵlistener("gridReady", function TemplateParamsGridComponent_Template_ag_grid_angular_gridReady_8_listener($event) { return ctx.onGridReady($event); })("rowEditingStopped", function TemplateParamsGridComponent_Template_ag_grid_angular_rowEditingStopped_8_listener($event) { return ctx.onRowEditingStopped($event); });
502
448
  i0.ɵɵelementEnd();
503
- i0.ɵɵconditionalCreate(24, TemplateParamsGridComponent_Conditional_24_Template, 2, 1, "kendo-grid-column", 12);
504
- i0.ɵɵtemplate(25, TemplateParamsGridComponent_ng_template_25_Template, 5, 1, "ng-template", 13);
505
- i0.ɵɵelementEnd();
506
- i0.ɵɵconditionalCreate(26, TemplateParamsGridComponent_Conditional_26_Template, 30, 2, "div", 14);
449
+ i0.ɵɵconditionalCreate(9, TemplateParamsGridComponent_Conditional_9_Template, 30, 2, "div", 6);
507
450
  i0.ɵɵelementEnd();
508
451
  } if (rf & 2) {
509
452
  i0.ɵɵadvance(7);
510
- i0.ɵɵproperty("data", ctx.templateParams)("loading", ctx.isLoading)("height", 400)("pageable", false)("sortable", true)("resizable", true);
453
+ i0.ɵɵconditional(ctx.editMode ? 7 : -1);
511
454
  i0.ɵɵadvance();
512
- i0.ɵɵconditional(ctx.editMode ? 8 : -1);
455
+ i0.ɵɵproperty("theme", ctx.GridTheme)("rowData", ctx.templateParams)("columnDefs", ctx.ColumnDefs)("defaultColDef", ctx.DefaultColDef)("editType", "fullRow")("getRowId", ctx.getRowId)("suppressClickEdit", true)("overlayNoRowsTemplate", ctx.noRowsTemplate);
513
456
  i0.ɵɵadvance();
514
- i0.ɵɵproperty("width", 200);
515
- i0.ɵɵadvance(3);
516
- i0.ɵɵproperty("width", 140);
517
- i0.ɵɵadvance(3);
518
- i0.ɵɵproperty("width", 100);
519
- i0.ɵɵadvance(3);
520
- i0.ɵɵproperty("width", 300);
521
- i0.ɵɵadvance(3);
522
- i0.ɵɵproperty("width", 200);
523
- i0.ɵɵadvance(3);
524
- i0.ɵɵconditional(ctx.editMode ? 24 : -1);
525
- i0.ɵɵadvance(2);
526
- i0.ɵɵconditional(ctx.editMode ? 26 : -1);
527
- } }, dependencies: [i1.NgControlStatus, i1.FormControlDirective, i2.GridComponent, i2.ToolbarComponent, i2.GridToolbarFocusableDirective, i2.ColumnComponent, i2.FocusableDirective, i2.CellTemplateDirective, i2.EditTemplateDirective, i2.NoRecordsTemplateDirective, i2.EditCommandDirective, i2.CancelCommandDirective, i2.SaveCommandDirective, i2.RemoveCommandDirective, i2.AddCommandDirective, i3.TextBoxComponent, i3.TextAreaComponent, i3.SwitchComponent, i4.DropDownListComponent], styles: [".template-params-grid[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.params-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.params-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n font-size: 1.2em;\n}\n\n.params-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.params-description[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.param-name[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.required-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 0.75em;\n font-weight: 500;\n}\n\n.required-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.6em;\n}\n\n.param-type[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-text-secondary);\n}\n\n.param-type[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.param-description[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n line-height: 1.4;\n}\n\n.default-value[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card);\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n word-break: break-word;\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-style: italic;\n font-size: 0.9em;\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.no-params-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.no-params-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2em;\n margin-bottom: 10px;\n color: var(--mj-text-muted);\n}\n\n.no-params-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 5px 0;\n}\n\n\n\n.params-help[_ngcontent-%COMP%] {\n margin-top: 30px;\n padding: 20px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.params-help[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n color: var(--mj-text-primary);\n font-size: 1em;\n}\n\n.params-help[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.params-help[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 10px 0;\n padding-left: 25px;\n}\n\n.params-help[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.params-help[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n.help-note[_ngcontent-%COMP%] {\n margin-top: 15px;\n padding: 10px 15px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-left: 4px solid var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 0.9em;\n}\n\n.help-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.help-note[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n color: var(--mj-status-error);\n}\n\n\n\n.k-grid-content[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.k-invalid-msg[_ngcontent-%COMP%] {\n display: block;\n color: var(--mj-status-error);\n font-size: 0.85em;\n margin-top: 4px;\n}\n\n\n\n.k-grid[_ngcontent-%COMP%] .k-toolbar[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px;\n}\n\n.k-grid-header[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card);\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n\n\n@media (max-width: 768px) {\n .template-params-grid[_ngcontent-%COMP%] {\n padding: 10px;\n }\n\n .params-help[_ngcontent-%COMP%] {\n padding: 15px;\n }\n}"] }); }
457
+ i0.ɵɵconditional(ctx.editMode ? 9 : -1);
458
+ } }, dependencies: [i1.AgGridAngular, i2.MJButtonDirective], styles: [".template-params-grid[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.params-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.params-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n font-size: 1.2em;\n}\n\n.params-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.params-description[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n\n\n.params-toolbar[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px 6px 0 0;\n}\n\n\n\n.params-ag-grid[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 6px 6px;\n}\n\n.params-toolbar[_ngcontent-%COMP%] + .params-ag-grid[_ngcontent-%COMP%] {\n border-top: none;\n}\n\n\n\n.params-help[_ngcontent-%COMP%] {\n margin-top: 30px;\n padding: 20px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.params-help[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n color: var(--mj-text-primary);\n font-size: 1em;\n}\n\n.params-help[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.params-help[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 10px 0;\n padding-left: 25px;\n}\n\n.params-help[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.params-help[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n.help-note[_ngcontent-%COMP%] {\n margin-top: 15px;\n padding: 10px 15px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-left: 4px solid var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 0.9em;\n}\n\n.help-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.help-note[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n color: var(--mj-status-error);\n}\n\n\n\n@media (max-width: 768px) {\n .template-params-grid[_ngcontent-%COMP%] {\n padding: 10px;\n }\n\n .params-help[_ngcontent-%COMP%] {\n padding: 15px;\n }\n}"] }); }
528
459
  }
529
460
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TemplateParamsGridComponent, [{
530
461
  type: Component,
531
- args: [{ standalone: false, selector: 'mj-template-params-grid', template: "<div class=\"template-params-grid\">\n <div class=\"params-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Template Parameters</h3>\n <p class=\"params-description\">\n Define the parameters that can be used within this template. Parameters allow dynamic content injection at runtime.\n </p>\n </div>\n\n <kendo-grid\n [data]=\"templateParams\"\n [loading]=\"isLoading\"\n [height]=\"400\"\n [pageable]=\"false\"\n [sortable]=\"true\"\n [resizable]=\"true\"\n (add)=\"addHandler($event)\"\n (edit)=\"editHandler($event)\"\n (cancel)=\"cancelHandler($event)\"\n (save)=\"saveHandler($event)\"\n (remove)=\"removeHandler($event)\">\n\n @if (editMode) {\n <kendo-grid-toolbar>\n <button kendoGridAddCommand type=\"button\" class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </kendo-grid-toolbar>\n }\n\n <kendo-grid-column field=\"Name\" title=\"Parameter Name\" [width]=\"200\">\n <ng-template kendoGridCellTemplate let-dataItem>\n <div class=\"param-name\">\n <strong>{{ dataItem.Name }}</strong>\n @if (dataItem.IsRequired) {\n <span class=\"required-badge\">\n <i class=\"fa-solid fa-asterisk\"></i> Required\n </span>\n }\n </div>\n </ng-template>\n <ng-template kendoGridEditTemplate let-dataItem=\"dataItem\" let-formGroup=\"formGroup\">\n <kendo-textbox\n [formControl]=\"formGroup.get('name')\"\n placeholder=\"Enter parameter name...\"\n [style.width.%]=\"100\">\n </kendo-textbox>\n @if (formGroup.get('name')?.touched && formGroup.get('name')?.errors?.['required']) {\n <span class=\"k-invalid-msg\">\n Parameter name is required\n </span>\n }\n </ng-template>\n </kendo-grid-column>\n\n <kendo-grid-column field=\"Type\" title=\"Type\" [width]=\"140\">\n <ng-template kendoGridCellTemplate let-dataItem>\n <div class=\"param-type\">\n <i class=\"fa-solid {{ getTypeIcon(dataItem.Type) }}\"></i>\n {{ dataItem.Type }}\n </div>\n </ng-template>\n <ng-template kendoGridEditTemplate let-dataItem=\"dataItem\" let-formGroup=\"formGroup\">\n <kendo-dropdownlist\n [formControl]=\"formGroup.get('type')\"\n [data]=\"typeOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n [style.width.%]=\"100\">\n </kendo-dropdownlist>\n </ng-template>\n </kendo-grid-column>\n\n <kendo-grid-column field=\"IsRequired\" title=\"Required\" [width]=\"100\">\n <ng-template kendoGridCellTemplate let-dataItem>\n <div class=\"text-center\">\n @if (dataItem.IsRequired) {\n <i class=\"fa-solid fa-check text-success\"></i>\n }\n @if (!dataItem.IsRequired) {\n <i class=\"fa-solid fa-times text-muted\"></i>\n }\n </div>\n </ng-template>\n <ng-template kendoGridEditTemplate let-dataItem=\"dataItem\" let-formGroup=\"formGroup\">\n <kendo-switch [formControl]=\"formGroup.get('isRequired')\"></kendo-switch>\n </ng-template>\n </kendo-grid-column>\n\n <kendo-grid-column field=\"Description\" title=\"Description\" [width]=\"300\">\n <ng-template kendoGridCellTemplate let-dataItem>\n <div class=\"param-description\">\n {{ dataItem.Description || '(No description)' }}\n </div>\n </ng-template>\n <ng-template kendoGridEditTemplate let-dataItem=\"dataItem\" let-formGroup=\"formGroup\">\n <kendo-textarea\n [formControl]=\"formGroup.get('description')\"\n placeholder=\"Enter parameter description...\"\n [rows]=\"2\"\n [style.width.%]=\"100\">\n </kendo-textarea>\n </ng-template>\n </kendo-grid-column>\n\n <kendo-grid-column field=\"DefaultValue\" title=\"Default Value\" [width]=\"200\">\n <ng-template kendoGridCellTemplate let-dataItem>\n @if (dataItem.DefaultValue) {\n <code class=\"default-value\">{{ dataItem.DefaultValue }}</code>\n }\n @if (!dataItem.DefaultValue) {\n <span class=\"text-muted\">(No default)</span>\n }\n </ng-template>\n <ng-template kendoGridEditTemplate let-dataItem=\"dataItem\" let-formGroup=\"formGroup\">\n <kendo-textarea\n [formControl]=\"formGroup.get('defaultValue')\"\n placeholder=\"Enter default value...\"\n [rows]=\"2\"\n [style.width.%]=\"100\">\n </kendo-textarea>\n </ng-template>\n </kendo-grid-column>\n\n @if (editMode) {\n <kendo-grid-column title=\"Actions\" [width]=\"120\">\n <ng-template kendoGridCellTemplate let-dataItem let-rowIndex=\"rowIndex\">\n @if (!isInEditMode(rowIndex)) {\n <button\n kendoGridEditCommand\n type=\"button\"\n class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-base\"\n title=\"Edit parameter\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n @if (!isInEditMode(rowIndex)) {\n <button\n kendoGridRemoveCommand\n type=\"button\"\n class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-base\"\n title=\"Delete parameter\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n @if (isInEditMode(rowIndex)) {\n <button\n kendoGridSaveCommand\n type=\"button\"\n class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary\"\n title=\"Save changes\">\n <i class=\"fa-solid fa-check\"></i>\n </button>\n }\n @if (isInEditMode(rowIndex)) {\n <button\n kendoGridCancelCommand\n type=\"button\"\n class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-base\"\n title=\"Cancel changes\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </ng-template>\n </kendo-grid-column>\n }\n\n <ng-template kendoGridNoRecordsTemplate>\n <div class=\"no-params-message\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No parameters defined for this template.</p>\n @if (editMode) {\n <p>Click \"Add Parameter\" to create your first parameter.</p>\n }\n </div>\n </ng-template>\n </kendo-grid>\n\n <!-- Help Section -->\n @if (editMode) {\n <div class=\"params-help\">\n <h4><i class=\"fa-solid fa-question-circle\"></i> Parameter Types</h4>\n <ul>\n <li><strong>Scalar:</strong> Single value like text, number, or boolean</li>\n <li><strong>Array:</strong> List of values</li>\n <li><strong>Object:</strong> JSON object with multiple properties</li>\n <li><strong>Record:</strong> Single record from a MemberJunction entity</li>\n <li><strong>Entity:</strong> Multiple records from a MemberJunction entity (can be filtered)</li>\n </ul>\n <p class=\"help-note\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n Use parameters in your template with the syntax: <code>{{ '{{' }} parameterName {{ '}}' }}</code>\n </p>\n </div>\n }\n</div>", styles: [".template-params-grid {\n padding: 20px;\n}\n\n.params-header {\n margin-bottom: 20px;\n}\n\n.params-header h3 {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n font-size: 1.2em;\n}\n\n.params-header h3 i {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.params-description {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.param-name {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.required-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 0.75em;\n font-weight: 500;\n}\n\n.required-badge i {\n font-size: 0.6em;\n}\n\n.param-type {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-text-secondary);\n}\n\n.param-type i {\n color: var(--mj-text-muted);\n}\n\n.param-description {\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n line-height: 1.4;\n}\n\n.default-value {\n background-color: var(--mj-bg-surface-card);\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 0.85em;\n color: var(--mj-text-secondary);\n word-break: break-word;\n}\n\n.text-muted {\n color: var(--mj-text-muted);\n font-style: italic;\n font-size: 0.9em;\n}\n\n.text-success {\n color: var(--mj-status-success);\n}\n\n.text-center {\n text-align: center;\n}\n\n.no-params-message {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.no-params-message i {\n font-size: 2em;\n margin-bottom: 10px;\n color: var(--mj-text-muted);\n}\n\n.no-params-message p {\n margin: 5px 0;\n}\n\n/* Help Section */\n.params-help {\n margin-top: 30px;\n padding: 20px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.params-help h4 {\n margin: 0 0 15px 0;\n color: var(--mj-text-primary);\n font-size: 1em;\n}\n\n.params-help h4 i {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.params-help ul {\n margin: 10px 0;\n padding-left: 25px;\n}\n\n.params-help li {\n margin-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.params-help strong {\n color: var(--mj-text-primary);\n}\n\n.help-note {\n margin-top: 15px;\n padding: 10px 15px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-left: 4px solid var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 0.9em;\n}\n\n.help-note i {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.help-note code {\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n color: var(--mj-status-error);\n}\n\n/* Grid action buttons */\n.k-grid-content button {\n margin-right: 4px;\n}\n\n/* Form validation */\n.k-invalid-msg {\n display: block;\n color: var(--mj-status-error);\n font-size: 0.85em;\n margin-top: 4px;\n}\n\n/* Kendo overrides for consistent styling */\n.k-grid .k-toolbar {\n background-color: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px;\n}\n\n.k-grid-header th {\n background-color: var(--mj-bg-surface-card);\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n/* Responsive adjustments */\n@media (max-width: 768px) {\n .template-params-grid {\n padding: 10px;\n }\n\n .params-help {\n padding: 15px;\n }\n}\n"] }]
532
- }], () => [], { template: [{
462
+ args: [{ standalone: false, selector: 'mj-template-params-grid', template: "<div class=\"template-params-grid\">\n <div class=\"params-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Template Parameters</h3>\n <p class=\"params-description\">\n Define the parameters that can be used within this template. Parameters allow dynamic content injection at runtime.\n </p>\n </div>\n\n @if (editMode) {\n <div class=\"params-toolbar\">\n <button mjButton variant=\"primary\" (click)=\"addNewParam()\">\n <i class=\"fa-solid fa-plus\"></i> Add Parameter\n </button>\n </div>\n }\n\n <ag-grid-angular\n class=\"params-ag-grid\"\n [theme]=\"GridTheme\"\n [rowData]=\"templateParams\"\n [columnDefs]=\"ColumnDefs\"\n [defaultColDef]=\"DefaultColDef\"\n [editType]=\"'fullRow'\"\n [getRowId]=\"getRowId\"\n [suppressClickEdit]=\"true\"\n [overlayNoRowsTemplate]=\"noRowsTemplate\"\n (gridReady)=\"onGridReady($event)\"\n (rowEditingStopped)=\"onRowEditingStopped($event)\"\n style=\"width: 100%; height: 400px;\">\n </ag-grid-angular>\n\n <!-- Help Section -->\n @if (editMode) {\n <div class=\"params-help\">\n <h4><i class=\"fa-solid fa-question-circle\"></i> Parameter Types</h4>\n <ul>\n <li><strong>Scalar:</strong> Single value like text, number, or boolean</li>\n <li><strong>Array:</strong> List of values</li>\n <li><strong>Object:</strong> JSON object with multiple properties</li>\n <li><strong>Record:</strong> Single record from a MemberJunction entity</li>\n <li><strong>Entity:</strong> Multiple records from a MemberJunction entity (can be filtered)</li>\n </ul>\n <p class=\"help-note\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n Use parameters in your template with the syntax: <code>{{ '{{' }} parameterName {{ '}}' }}</code>\n </p>\n </div>\n }\n</div>\n", styles: [".template-params-grid {\n padding: 20px;\n}\n\n.params-header {\n margin-bottom: 20px;\n}\n\n.params-header h3 {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n font-size: 1.2em;\n}\n\n.params-header h3 i {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.params-description {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n/* Toolbar */\n.params-toolbar {\n margin-bottom: 12px;\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px 6px 0 0;\n}\n\n/* AG Grid wrapper */\n.params-ag-grid {\n border: 1px solid var(--mj-border-default);\n border-radius: 0 0 6px 6px;\n}\n\n.params-toolbar + .params-ag-grid {\n border-top: none;\n}\n\n/* Help Section */\n.params-help {\n margin-top: 30px;\n padding: 20px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.params-help h4 {\n margin: 0 0 15px 0;\n color: var(--mj-text-primary);\n font-size: 1em;\n}\n\n.params-help h4 i {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.params-help ul {\n margin: 10px 0;\n padding-left: 25px;\n}\n\n.params-help li {\n margin-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.9em;\n}\n\n.params-help strong {\n color: var(--mj-text-primary);\n}\n\n.help-note {\n margin-top: 15px;\n padding: 10px 15px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-left: 4px solid var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 0.9em;\n}\n\n.help-note i {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n}\n\n.help-note code {\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n color: var(--mj-status-error);\n}\n\n/* Responsive adjustments */\n@media (max-width: 768px) {\n .template-params-grid {\n padding: 10px;\n }\n\n .params-help {\n padding: 15px;\n }\n}\n"] }]
463
+ }], null, { template: [{
533
464
  type: Input
534
465
  }], editMode: [{
535
466
  type: Input
536
- }], grid: [{
537
- type: ViewChild,
538
- args: [GridComponent]
539
467
  }] }); })();
540
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TemplateParamsGridComponent, { className: "TemplateParamsGridComponent", filePath: "src/lib/custom/Templates/template-params-grid.component.ts", lineNumber: 14 }); })();
468
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TemplateParamsGridComponent, { className: "TemplateParamsGridComponent", filePath: "src/lib/custom/Templates/template-params-grid.component.ts", lineNumber: 48 }); })();
469
+ /**
470
+ * Inline cell renderer for edit/delete/save/cancel action buttons.
471
+ * This is a plain-JS AG Grid cell renderer (not an Angular component)
472
+ * because the grid doesn't support Angular component renderers without
473
+ * the AG Grid Enterprise "Framework Components" feature.
474
+ */
475
+ function ActionsCellRenderer(params) {
476
+ const container = document.createElement('div');
477
+ container.style.display = 'flex';
478
+ container.style.gap = '4px';
479
+ container.style.alignItems = 'center';
480
+ const comp = params.componentRef;
481
+ const isEditing = params.node.rowIndex != null && params.api.getEditingCells().some(cell => cell.rowIndex === params.node.rowIndex);
482
+ if (isEditing) {
483
+ // Save button
484
+ const saveBtn = createActionButton('fa-check', 'Save changes', 'var(--mj-brand-primary)');
485
+ saveBtn.addEventListener('click', (e) => {
486
+ e.stopPropagation();
487
+ comp.saveEditRow();
488
+ });
489
+ container.appendChild(saveBtn);
490
+ // Cancel button
491
+ const cancelBtn = createActionButton('fa-times', 'Cancel changes', 'var(--mj-text-secondary)');
492
+ cancelBtn.addEventListener('click', (e) => {
493
+ e.stopPropagation();
494
+ comp.cancelEditRow();
495
+ });
496
+ container.appendChild(cancelBtn);
497
+ }
498
+ else {
499
+ // Edit button
500
+ const editBtn = createActionButton('fa-edit', 'Edit parameter', 'var(--mj-text-secondary)');
501
+ editBtn.addEventListener('click', (e) => {
502
+ e.stopPropagation();
503
+ comp.startEditRow(params);
504
+ });
505
+ container.appendChild(editBtn);
506
+ // Delete button
507
+ const deleteBtn = createActionButton('fa-trash', 'Delete parameter', 'var(--mj-status-error)');
508
+ deleteBtn.addEventListener('click', (e) => {
509
+ e.stopPropagation();
510
+ comp.deleteRow(params);
511
+ });
512
+ container.appendChild(deleteBtn);
513
+ }
514
+ return container;
515
+ }
516
+ function createActionButton(iconClass, title, color) {
517
+ const btn = document.createElement('button');
518
+ btn.type = 'button';
519
+ btn.title = title;
520
+ btn.style.cssText = `
521
+ border: 1px solid var(--mj-border-default);
522
+ background: var(--mj-bg-surface);
523
+ color: ${color};
524
+ border-radius: 4px;
525
+ padding: 4px 8px;
526
+ cursor: pointer;
527
+ display: inline-flex;
528
+ align-items: center;
529
+ justify-content: center;
530
+ font-size: 14px;
531
+ `;
532
+ const icon = document.createElement('i');
533
+ icon.className = `fa-solid ${iconClass}`;
534
+ btn.appendChild(icon);
535
+ return btn;
536
+ }
541
537
  //# sourceMappingURL=template-params-grid.component.js.map