@memberjunction/ng-dashboards 2.88.0 → 2.90.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 (38) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +8 -8
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/agents/agent-editor.component.d.ts +4 -4
  5. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  6. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  7. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +3 -3
  8. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
  9. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  11. package/dist/AI/components/models/model-management-v2.component.d.ts +4 -4
  12. package/dist/AI/components/models/model-management-v2.component.d.ts.map +1 -1
  13. package/dist/AI/components/models/model-management-v2.component.js +2 -2
  14. package/dist/AI/components/models/model-management-v2.component.js.map +1 -1
  15. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +7 -7
  16. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
  17. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  18. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts +4 -4
  19. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts.map +1 -1
  20. package/dist/AI/components/prompts/prompt-management-v2.component.js +1 -1
  21. package/dist/AI/components/prompts/prompt-management-v2.component.js.map +1 -1
  22. package/dist/AI/components/prompts/prompt-version-control.component.d.ts +6 -6
  23. package/dist/AI/components/prompts/prompt-version-control.component.d.ts.map +1 -1
  24. package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
  25. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  26. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +195 -12
  27. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  28. package/dist/ComponentStudio/component-studio-dashboard.component.js +1259 -180
  29. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  30. package/dist/ComponentStudio/components/text-import-dialog.component.d.ts +14 -0
  31. package/dist/ComponentStudio/components/text-import-dialog.component.d.ts.map +1 -0
  32. package/dist/ComponentStudio/components/text-import-dialog.component.js +121 -0
  33. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -0
  34. package/dist/module.d.ts +19 -18
  35. package/dist/module.d.ts.map +1 -1
  36. package/dist/module.js +15 -6
  37. package/dist/module.js.map +1 -1
  38. package/package.json +10 -10
@@ -4,230 +4,436 @@ 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 } from '@angular/core';
7
+ import { Component, ViewChild, HostListener } from '@angular/core';
8
8
  import { BaseDashboard } from '../generic/base-dashboard';
9
9
  import { RegisterClass } from '@memberjunction/global';
10
- import { RunView } from '@memberjunction/core';
10
+ import { RunView, CompositeKey, Metadata } from '@memberjunction/core';
11
11
  import { Subject } from 'rxjs';
12
12
  import { SharedService } from '@memberjunction/ng-shared';
13
+ import { ParseJSONRecursive } from '@memberjunction/global';
14
+ import { TextImportDialogComponent } from './components/text-import-dialog.component';
13
15
  import * as i0 from "@angular/core";
14
- import * as i1 from "@angular/common";
15
- import * as i2 from "@progress/kendo-angular-inputs";
16
- import * as i3 from "@progress/kendo-angular-layout";
17
- import * as i4 from "@progress/kendo-angular-buttons";
18
- import * as i5 from "@memberjunction/ng-react";
19
- const _forTrack0 = ($index, $item) => $item.ID;
20
- function ComponentStudioDashboardComponent_ng_template_20_Template(rf, ctx) { if (rf & 1) {
21
- i0.ɵɵelement(0, "i", 20);
22
- } }
23
- function ComponentStudioDashboardComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
24
- i0.ɵɵelementStart(0, "div", 15);
25
- i0.ɵɵelement(1, "i", 21);
16
+ import * as i1 from "@progress/kendo-angular-dialog";
17
+ import * as i2 from "@angular/common";
18
+ import * as i3 from "@angular/forms";
19
+ import * as i4 from "@progress/kendo-angular-inputs";
20
+ import * as i5 from "@progress/kendo-angular-layout";
21
+ import * as i6 from "@memberjunction/ng-code-editor";
22
+ import * as i7 from "@progress/kendo-angular-buttons";
23
+ import * as i8 from "@memberjunction/ng-react";
24
+ const _c0 = ["fileInput"];
25
+ const _forTrack0 = ($index, $item) => $item.name;
26
+ function _forTrack1($index, $item) { return this.getComponentId($item); }
27
+ const _forTrack2 = ($index, $item) => $item.title;
28
+ function ComponentStudioDashboardComponent_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
29
+ i0.ɵɵelement(0, "span", 35);
30
+ i0.ɵɵtext(1, " Show Details ");
31
+ } }
32
+ function ComponentStudioDashboardComponent_Conditional_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
33
+ i0.ɵɵelement(0, "span", 36);
34
+ i0.ɵɵtext(1, " Hide Details ");
35
+ } }
36
+ function ComponentStudioDashboardComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
37
+ const _r2 = i0.ɵɵgetCurrentView();
38
+ i0.ɵɵelementStart(0, "button", 9);
39
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleDetailsPane()); });
40
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_10_Conditional_1_Template, 2, 0)(2, ComponentStudioDashboardComponent_Conditional_10_Conditional_2_Template, 2, 0);
41
+ i0.ɵɵelementEnd();
42
+ } if (rf & 2) {
43
+ const ctx_r2 = i0.ɵɵnextContext();
44
+ i0.ɵɵproperty("themeColor", "base");
45
+ i0.ɵɵadvance();
46
+ i0.ɵɵconditional(ctx_r2.isDetailsPaneCollapsed ? 1 : 2);
47
+ } }
48
+ function ComponentStudioDashboardComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
49
+ const _r4 = i0.ɵɵgetCurrentView();
50
+ i0.ɵɵelementStart(0, "div", 12)(1, "button", 37);
51
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_16_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.importFromFile()); });
52
+ i0.ɵɵelement(2, "i", 38);
53
+ i0.ɵɵtext(3, " Import from File ");
54
+ i0.ɵɵelementEnd();
55
+ i0.ɵɵelementStart(4, "button", 37);
56
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_16_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.importFromText()); });
57
+ i0.ɵɵelement(5, "i", 39);
58
+ i0.ɵɵtext(6, " Import from Text ");
59
+ i0.ɵɵelementEnd()();
60
+ } }
61
+ function ComponentStudioDashboardComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
62
+ i0.ɵɵelement(0, "i", 40);
63
+ i0.ɵɵtext(1, " Favorites ");
64
+ } }
65
+ function ComponentStudioDashboardComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
66
+ i0.ɵɵelement(0, "i", 41);
67
+ i0.ɵɵtext(1, " All ");
68
+ } }
69
+ function ComponentStudioDashboardComponent_Conditional_36_For_2_Template(rf, ctx) { if (rf & 1) {
70
+ const _r5 = i0.ɵɵgetCurrentView();
71
+ i0.ɵɵelementStart(0, "button", 45);
72
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_36_For_2_Template_button_click_0_listener() { const category_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleCategory(category_r6.name)); });
73
+ i0.ɵɵelementStart(1, "span", 46);
74
+ i0.ɵɵtext(2);
75
+ i0.ɵɵelementEnd();
76
+ i0.ɵɵelementStart(3, "span", 47);
77
+ i0.ɵɵtext(4);
78
+ i0.ɵɵelementEnd()();
79
+ } if (rf & 2) {
80
+ const category_r6 = ctx.$implicit;
81
+ const ctx_r2 = i0.ɵɵnextContext(2);
82
+ i0.ɵɵstyleProp("--pill-color", category_r6.color);
83
+ i0.ɵɵclassProp("active", ctx_r2.isCategorySelected(category_r6.name));
84
+ i0.ɵɵadvance(2);
85
+ i0.ɵɵtextInterpolate(category_r6.name);
86
+ i0.ɵɵadvance(2);
87
+ i0.ɵɵtextInterpolate(category_r6.count);
88
+ } }
89
+ function ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵelement(0, "i", 49);
91
+ i0.ɵɵtext(1, " Less ");
92
+ } }
93
+ function ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
94
+ i0.ɵɵelement(0, "i", 50);
95
+ i0.ɵɵtext(1);
96
+ } if (rf & 2) {
97
+ const ctx_r2 = i0.ɵɵnextContext(3);
98
+ i0.ɵɵadvance();
99
+ i0.ɵɵtextInterpolate1(" +", ctx_r2.availableCategories.length - 5, " more ");
100
+ } }
101
+ function ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Template(rf, ctx) { if (rf & 1) {
102
+ const _r7 = i0.ɵɵgetCurrentView();
103
+ i0.ɵɵelementStart(0, "button", 48);
104
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleShowAllCategories()); });
105
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Conditional_1_Template, 2, 0)(2, ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Conditional_2_Template, 2, 1);
106
+ i0.ɵɵelementEnd();
107
+ } if (rf & 2) {
108
+ const ctx_r2 = i0.ɵɵnextContext(2);
109
+ i0.ɵɵadvance();
110
+ i0.ɵɵconditional(ctx_r2.showAllCategories ? 1 : 2);
111
+ } }
112
+ function ComponentStudioDashboardComponent_Conditional_36_Conditional_4_Template(rf, ctx) { if (rf & 1) {
113
+ const _r8 = i0.ɵɵgetCurrentView();
114
+ i0.ɵɵelementStart(0, "button", 51);
115
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_36_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.clearCategoryFilters()); });
116
+ i0.ɵɵelement(1, "i", 52);
117
+ i0.ɵɵtext(2, " Clear ");
118
+ i0.ɵɵelementEnd();
119
+ } }
120
+ function ComponentStudioDashboardComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
121
+ i0.ɵɵelementStart(0, "div", 25);
122
+ i0.ɵɵrepeaterCreate(1, ComponentStudioDashboardComponent_Conditional_36_For_2_Template, 5, 6, "button", 42, _forTrack0);
123
+ i0.ɵɵtemplate(3, ComponentStudioDashboardComponent_Conditional_36_Conditional_3_Template, 3, 1, "button", 43)(4, ComponentStudioDashboardComponent_Conditional_36_Conditional_4_Template, 3, 0, "button", 44);
124
+ i0.ɵɵelementEnd();
125
+ } if (rf & 2) {
126
+ const ctx_r2 = i0.ɵɵnextContext();
127
+ i0.ɵɵadvance();
128
+ i0.ɵɵrepeater(ctx_r2.getVisibleCategories());
129
+ i0.ɵɵadvance(2);
130
+ i0.ɵɵconditional(ctx_r2.availableCategories.length > 5 ? 3 : -1);
131
+ i0.ɵɵadvance();
132
+ i0.ɵɵconditional(ctx_r2.selectedCategories.size > 0 ? 4 : -1);
133
+ } }
134
+ function ComponentStudioDashboardComponent_ng_template_39_Template(rf, ctx) { if (rf & 1) {
135
+ i0.ɵɵelement(0, "i", 53);
136
+ } }
137
+ function ComponentStudioDashboardComponent_Conditional_41_Template(rf, ctx) { if (rf & 1) {
138
+ i0.ɵɵelementStart(0, "div", 30);
139
+ i0.ɵɵelement(1, "i", 54);
26
140
  i0.ɵɵtext(2, " Loading components... ");
27
141
  i0.ɵɵelementEnd();
28
142
  } }
29
- function ComponentStudioDashboardComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
30
- i0.ɵɵelementStart(0, "div", 16);
31
- i0.ɵɵelement(1, "i", 22);
32
- i0.ɵɵtext(2, " No components found without custom properties. ");
143
+ function ComponentStudioDashboardComponent_Conditional_42_Template(rf, ctx) { if (rf & 1) {
144
+ i0.ɵɵelementStart(0, "div", 31);
145
+ i0.ɵɵelement(1, "i", 55);
146
+ i0.ɵɵtext(2, " No components found without required custom properties. ");
33
147
  i0.ɵɵelement(3, "br");
34
148
  i0.ɵɵelementStart(4, "small");
35
- i0.ɵɵtext(5, "Only components that don't require custom props can be tested here.");
149
+ i0.ɵɵtext(5, "Components with optional custom props can be tested, but not those with required props.");
36
150
  i0.ɵɵelementEnd()();
37
151
  } }
38
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_12_Template(rf, ctx) { if (rf & 1) {
39
- i0.ɵɵelementStart(0, "span", 33);
152
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵelement(0, "i", 40);
154
+ } }
155
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵelement(0, "i", 41);
157
+ } }
158
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
159
+ const _r11 = i0.ɵɵgetCurrentView();
160
+ i0.ɵɵelementStart(0, "button", 75);
161
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r11); const component_r10 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleFavorite(component_r10, $event)); });
162
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Conditional_1_Template, 1, 0, "i", 40)(2, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Conditional_2_Template, 1, 0, "i", 41);
163
+ i0.ɵɵelementEnd();
164
+ } if (rf & 2) {
165
+ const component_r10 = i0.ɵɵnextContext().$implicit;
166
+ const ctx_r2 = i0.ɵɵnextContext(2);
167
+ i0.ɵɵclassProp("is-favorite", ctx_r2.isFavorite(component_r10));
168
+ i0.ɵɵproperty("title", ctx_r2.isFavorite(component_r10) ? "Remove from favorites" : "Add to favorites");
169
+ i0.ɵɵadvance();
170
+ i0.ɵɵconditional(ctx_r2.isFavorite(component_r10) ? 1 : 2);
171
+ } }
172
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
173
+ i0.ɵɵelement(0, "i", 39);
174
+ i0.ɵɵtext(1, " Text Import ");
175
+ } }
176
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
177
+ i0.ɵɵelement(0, "i", 38);
178
+ i0.ɵɵtext(1);
179
+ } if (rf & 2) {
180
+ const component_r10 = i0.ɵɵnextContext(2).$implicit;
181
+ const ctx_r2 = i0.ɵɵnextContext(2);
182
+ i0.ɵɵadvance();
183
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.getComponentFilename(component_r10), " ");
184
+ } }
185
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
186
+ i0.ɵɵelementStart(0, "span", 64);
187
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Conditional_1_Template, 2, 0)(2, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Conditional_2_Template, 2, 1);
188
+ i0.ɵɵelementEnd();
189
+ } if (rf & 2) {
190
+ const component_r10 = i0.ɵɵnextContext().$implicit;
191
+ const ctx_r2 = i0.ɵɵnextContext(2);
192
+ i0.ɵɵproperty("title", ctx_r2.getComponentStatus(component_r10) === "Text" ? "Imported from text input" : "Loaded from " + ctx_r2.getComponentFilename(component_r10));
193
+ i0.ɵɵadvance();
194
+ i0.ɵɵconditional(ctx_r2.getComponentStatus(component_r10) === "Text" ? 1 : 2);
195
+ } }
196
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Conditional_0_Template(rf, ctx) { if (rf & 1) {
197
+ i0.ɵɵelementStart(0, "span", 76);
198
+ i0.ɵɵtext(1, "Text");
199
+ i0.ɵɵelementEnd();
200
+ } }
201
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
202
+ i0.ɵɵelementStart(0, "span", 77);
203
+ i0.ɵɵtext(1, "File");
204
+ i0.ɵɵelementEnd();
205
+ } }
206
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
207
+ i0.ɵɵtemplate(0, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Conditional_0_Template, 2, 0, "span", 76)(1, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Conditional_1_Template, 2, 0, "span", 77);
208
+ } if (rf & 2) {
209
+ const component_r10 = i0.ɵɵnextContext().$implicit;
210
+ const ctx_r2 = i0.ɵɵnextContext(2);
211
+ i0.ɵɵconditional(ctx_r2.getComponentStatus(component_r10) === "Text" ? 0 : 1);
212
+ } }
213
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
214
+ i0.ɵɵelementStart(0, "span", 68);
40
215
  i0.ɵɵtext(1, "Published");
41
216
  i0.ɵɵelementEnd();
42
217
  } }
43
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
44
- i0.ɵɵelementStart(0, "span", 34);
218
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_16_Template(rf, ctx) { if (rf & 1) {
219
+ i0.ɵɵelementStart(0, "span", 69);
45
220
  i0.ɵɵtext(1, "Draft");
46
221
  i0.ɵɵelementEnd();
47
222
  } }
48
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
49
- i0.ɵɵelement(0, "i", 36);
223
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_22_Template(rf, ctx) { if (rf & 1) {
224
+ i0.ɵɵelement(0, "i", 49);
50
225
  } }
51
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_16_Template(rf, ctx) { if (rf & 1) {
52
- i0.ɵɵelement(0, "i", 37);
226
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_23_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵelement(0, "i", 50);
53
228
  } }
54
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_1_Template(rf, ctx) { if (rf & 1) {
55
- i0.ɵɵelementStart(0, "div", 39)(1, "label");
229
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
230
+ i0.ɵɵelementStart(0, "div", 78)(1, "label");
56
231
  i0.ɵɵtext(2, "Description");
57
232
  i0.ɵɵelementEnd();
58
233
  i0.ɵɵelementStart(3, "p");
59
234
  i0.ɵɵtext(4);
60
235
  i0.ɵɵelementEnd()();
61
236
  } if (rf & 2) {
62
- const component_r2 = i0.ɵɵnextContext(2).$implicit;
237
+ const component_r10 = i0.ɵɵnextContext(2).$implicit;
238
+ const ctx_r2 = i0.ɵɵnextContext(2);
63
239
  i0.ɵɵadvance(4);
64
- i0.ɵɵtextInterpolate(component_r2.Description);
240
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(component_r10));
65
241
  } }
66
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_21_Template(rf, ctx) { if (rf & 1) {
67
- i0.ɵɵelementStart(0, "div", 41)(1, "span", 42);
242
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_21_Template(rf, ctx) { if (rf & 1) {
243
+ i0.ɵɵelementStart(0, "div", 80)(1, "span", 81);
244
+ i0.ɵɵtext(2, "Loaded:");
245
+ i0.ɵɵelementEnd();
246
+ i0.ɵɵelementStart(3, "span", 82);
247
+ i0.ɵɵtext(4);
248
+ i0.ɵɵpipe(5, "date");
249
+ i0.ɵɵelementEnd()();
250
+ } if (rf & 2) {
251
+ const component_r10 = i0.ɵɵnextContext(2).$implicit;
252
+ const ctx_r2 = i0.ɵɵnextContext(2);
253
+ i0.ɵɵadvance(4);
254
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentLoadedAt(component_r10), "short"));
255
+ } }
256
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_22_Template(rf, ctx) { if (rf & 1) {
257
+ i0.ɵɵelementStart(0, "div", 80)(1, "span", 81);
68
258
  i0.ɵɵtext(2, "Updated:");
69
259
  i0.ɵɵelementEnd();
70
- i0.ɵɵelementStart(3, "span", 43);
260
+ i0.ɵɵelementStart(3, "span", 82);
71
261
  i0.ɵɵtext(4);
72
262
  i0.ɵɵpipe(5, "date");
73
263
  i0.ɵɵelementEnd()();
74
264
  } if (rf & 2) {
75
- const component_r2 = i0.ɵɵnextContext(2).$implicit;
265
+ const component_r10 = i0.ɵɵnextContext(2).$implicit;
266
+ const ctx_r2 = i0.ɵɵnextContext(2);
76
267
  i0.ɵɵadvance(4);
77
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, component_r2.__mj_UpdatedAt, "short"));
268
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentUpdatedAt(component_r10), "short"));
78
269
  } }
79
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_23_Template(rf, ctx) { if (rf & 1) {
80
- const _r4 = i0.ɵɵgetCurrentView();
81
- i0.ɵɵelementStart(0, "button", 47);
82
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_23_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.stopComponent(); return i0.ɵɵresetView($event.stopPropagation()); });
83
- i0.ɵɵelement(1, "span", 48);
270
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_24_Template(rf, ctx) { if (rf & 1) {
271
+ const _r12 = i0.ɵɵgetCurrentView();
272
+ i0.ɵɵelementStart(0, "button", 9);
273
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_24_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.stopComponent(); return i0.ɵɵresetView($event.stopPropagation()); });
274
+ i0.ɵɵelement(1, "span", 85);
84
275
  i0.ɵɵtext(2, " Stop Component ");
85
276
  i0.ɵɵelementEnd();
86
277
  } if (rf & 2) {
87
278
  i0.ɵɵproperty("themeColor", "error");
88
279
  } }
89
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_24_Template(rf, ctx) { if (rf & 1) {
90
- const _r5 = i0.ɵɵgetCurrentView();
91
- i0.ɵɵelementStart(0, "button", 49);
92
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_24_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const component_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r2); return i0.ɵɵresetView($event.stopPropagation()); });
93
- i0.ɵɵelement(1, "span", 50);
280
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_25_Template(rf, ctx) { if (rf & 1) {
281
+ const _r13 = i0.ɵɵgetCurrentView();
282
+ i0.ɵɵelementStart(0, "button", 86);
283
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_25_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r13); const component_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r10); return i0.ɵɵresetView($event.stopPropagation()); });
284
+ i0.ɵɵelement(1, "span", 87);
94
285
  i0.ɵɵtext(2, " Switch to This Component ");
95
286
  i0.ɵɵelementEnd();
96
287
  } if (rf & 2) {
97
288
  i0.ɵɵproperty("themeColor", "base");
98
289
  } }
99
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_25_Template(rf, ctx) { if (rf & 1) {
100
- const _r6 = i0.ɵɵgetCurrentView();
101
- i0.ɵɵelementStart(0, "button", 47);
102
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_25_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const component_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r2); return i0.ɵɵresetView($event.stopPropagation()); });
103
- i0.ɵɵelement(1, "span", 50);
290
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_26_Template(rf, ctx) { if (rf & 1) {
291
+ const _r14 = i0.ɵɵgetCurrentView();
292
+ i0.ɵɵelementStart(0, "button", 9);
293
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_26_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const component_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r10); return i0.ɵɵresetView($event.stopPropagation()); });
294
+ i0.ɵɵelement(1, "span", 87);
104
295
  i0.ɵɵtext(2, " Run Component ");
105
296
  i0.ɵɵelementEnd();
106
297
  } if (rf & 2) {
107
298
  i0.ɵɵproperty("themeColor", "primary");
108
299
  } }
109
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Template(rf, ctx) { if (rf & 1) {
110
- i0.ɵɵelementStart(0, "div", 38);
111
- i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_1_Template, 5, 1, "div", 39);
112
- i0.ɵɵelementStart(2, "div", 39)(3, "label");
300
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Template(rf, ctx) { if (rf & 1) {
301
+ i0.ɵɵelementStart(0, "div", 74);
302
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_1_Template, 5, 1, "div", 78);
303
+ i0.ɵɵelementStart(2, "div", 78)(3, "label");
113
304
  i0.ɵɵtext(4, "Component Info");
114
305
  i0.ɵɵelementEnd();
115
- i0.ɵɵelementStart(5, "div", 40)(6, "div", 41)(7, "span", 42);
306
+ i0.ɵɵelementStart(5, "div", 79)(6, "div", 80)(7, "span", 81);
116
307
  i0.ɵɵtext(8, "Type:");
117
308
  i0.ɵɵelementEnd();
118
- i0.ɵɵelementStart(9, "span", 43);
309
+ i0.ɵɵelementStart(9, "span", 82);
119
310
  i0.ɵɵtext(10);
120
311
  i0.ɵɵelementEnd()();
121
- i0.ɵɵelementStart(11, "div", 41)(12, "span", 42);
312
+ i0.ɵɵelementStart(11, "div", 80)(12, "span", 81);
122
313
  i0.ɵɵtext(13, "Version:");
123
314
  i0.ɵɵelementEnd();
124
- i0.ɵɵelementStart(14, "span", 43);
315
+ i0.ɵɵelementStart(14, "span", 82);
125
316
  i0.ɵɵtext(15);
126
317
  i0.ɵɵelementEnd()();
127
- i0.ɵɵelementStart(16, "div", 41)(17, "span", 42);
318
+ i0.ɵɵelementStart(16, "div", 80)(17, "span", 81);
128
319
  i0.ɵɵtext(18, "Status:");
129
320
  i0.ɵɵelementEnd();
130
- i0.ɵɵelementStart(19, "span", 43);
321
+ i0.ɵɵelementStart(19, "span", 82);
131
322
  i0.ɵɵtext(20);
132
323
  i0.ɵɵelementEnd()();
133
- i0.ɵɵtemplate(21, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_21_Template, 6, 4, "div", 41);
324
+ i0.ɵɵtemplate(21, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_21_Template, 6, 4, "div", 80)(22, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_22_Template, 6, 4, "div", 80);
134
325
  i0.ɵɵelementEnd()();
135
- i0.ɵɵelementStart(22, "div", 44);
136
- i0.ɵɵtemplate(23, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_23_Template, 3, 1, "button", 45)(24, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_24_Template, 3, 1, "button", 46)(25, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Conditional_25_Template, 3, 1, "button", 45);
326
+ i0.ɵɵelementStart(23, "div", 83);
327
+ i0.ɵɵtemplate(24, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_24_Template, 3, 1, "button", 7)(25, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_25_Template, 3, 1, "button", 84)(26, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Conditional_26_Template, 3, 1, "button", 7);
137
328
  i0.ɵɵelementEnd()();
138
329
  } if (rf & 2) {
139
- const component_r2 = i0.ɵɵnextContext().$implicit;
330
+ const component_r10 = i0.ɵɵnextContext().$implicit;
140
331
  const ctx_r2 = i0.ɵɵnextContext(2);
141
332
  i0.ɵɵadvance();
142
- i0.ɵɵconditional(component_r2.Description ? 1 : -1);
333
+ i0.ɵɵconditional(ctx_r2.getComponentDescription(component_r10) ? 1 : -1);
143
334
  i0.ɵɵadvance(9);
144
- i0.ɵɵtextInterpolate(component_r2.Type || "Unknown");
335
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r10) || "Unknown");
145
336
  i0.ɵɵadvance(5);
146
- i0.ɵɵtextInterpolate(component_r2.Version || "1.0.0");
337
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentVersion(component_r10));
147
338
  i0.ɵɵadvance(5);
148
- i0.ɵɵtextInterpolate(component_r2.Status || "Draft");
339
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentStatus(component_r10) || "Draft");
149
340
  i0.ɵɵadvance();
150
- i0.ɵɵconditional(component_r2.__mj_UpdatedAt ? 21 : -1);
151
- i0.ɵɵadvance(2);
152
- i0.ɵɵconditional((ctx_r2.selectedComponent == null ? null : ctx_r2.selectedComponent.ID) === component_r2.ID && ctx_r2.isRunning ? 23 : ctx_r2.isRunning && (ctx_r2.selectedComponent == null ? null : ctx_r2.selectedComponent.ID) !== component_r2.ID ? 24 : 25);
341
+ i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r10) ? 21 : !ctx_r2.isFileLoadedComponent(component_r10) && ctx_r2.getComponentUpdatedAt(component_r10) ? 22 : -1);
342
+ i0.ɵɵadvance(3);
343
+ i0.ɵɵconditional(ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) === ctx_r2.getComponentId(component_r10) && ctx_r2.isRunning ? 24 : ctx_r2.isRunning && ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) !== ctx_r2.getComponentId(component_r10) ? 25 : 26);
153
344
  } }
154
- function ComponentStudioDashboardComponent_Conditional_24_For_1_Template(rf, ctx) { if (rf & 1) {
155
- const _r1 = i0.ɵɵgetCurrentView();
156
- i0.ɵɵelementStart(0, "div", 24)(1, "div", 25);
157
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_For_1_Template_div_click_1_listener() { const component_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleComponentExpansion(component_r2)); });
158
- i0.ɵɵelementStart(2, "div", 26);
159
- i0.ɵɵelement(3, "i", 27);
160
- i0.ɵɵelementEnd();
161
- i0.ɵɵelementStart(4, "div", 28)(5, "div", 29);
162
- i0.ɵɵtext(6);
345
+ function ComponentStudioDashboardComponent_Conditional_43_For_1_Template(rf, ctx) { if (rf & 1) {
346
+ const _r9 = i0.ɵɵgetCurrentView();
347
+ i0.ɵɵelementStart(0, "div", 57)(1, "div", 58);
348
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_43_For_1_Template_div_click_1_listener() { const component_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleComponentExpansion(component_r10)); });
349
+ i0.ɵɵelementStart(2, "div", 59);
350
+ i0.ɵɵelement(3, "i", 60);
163
351
  i0.ɵɵelementEnd();
164
- i0.ɵɵelementStart(7, "div", 30)(8, "span", 31);
165
- i0.ɵɵtext(9);
352
+ i0.ɵɵtemplate(4, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_4_Template, 3, 4, "button", 61);
353
+ i0.ɵɵelementStart(5, "div", 62)(6, "div", 63);
354
+ i0.ɵɵtext(7);
355
+ i0.ɵɵtemplate(8, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_8_Template, 3, 2, "span", 64);
166
356
  i0.ɵɵelementEnd();
167
- i0.ɵɵelementStart(10, "span", 32);
357
+ i0.ɵɵelementStart(9, "div", 65)(10, "span", 66);
168
358
  i0.ɵɵtext(11);
169
359
  i0.ɵɵelementEnd();
170
- i0.ɵɵtemplate(12, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_12_Template, 2, 0, "span", 33)(13, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_13_Template, 2, 0, "span", 34);
171
- i0.ɵɵelementEnd()();
172
- i0.ɵɵelementStart(14, "div", 35);
173
- i0.ɵɵtemplate(15, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_15_Template, 1, 0, "i", 36)(16, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_16_Template, 1, 0, "i", 37);
360
+ i0.ɵɵelementStart(12, "span", 67);
361
+ i0.ɵɵtext(13);
362
+ i0.ɵɵelementEnd();
363
+ i0.ɵɵtemplate(14, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_14_Template, 2, 1)(15, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_15_Template, 2, 0, "span", 68)(16, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_16_Template, 2, 0, "span", 69);
364
+ i0.ɵɵelementEnd();
365
+ i0.ɵɵelementStart(17, "div", 70)(18, "span", 71);
366
+ i0.ɵɵelement(19, "i", 72);
367
+ i0.ɵɵtext(20);
368
+ i0.ɵɵelementEnd()()();
369
+ i0.ɵɵelementStart(21, "div", 73);
370
+ i0.ɵɵtemplate(22, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_22_Template, 1, 0, "i", 49)(23, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_23_Template, 1, 0, "i", 50);
174
371
  i0.ɵɵelementEnd()();
175
- i0.ɵɵtemplate(17, ComponentStudioDashboardComponent_Conditional_24_For_1_Conditional_17_Template, 26, 6, "div", 38);
372
+ i0.ɵɵtemplate(24, ComponentStudioDashboardComponent_Conditional_43_For_1_Conditional_24_Template, 27, 6, "div", 74);
176
373
  i0.ɵɵelementEnd();
177
374
  } if (rf & 2) {
178
- const component_r2 = ctx.$implicit;
375
+ const component_r10 = ctx.$implicit;
179
376
  const ctx_r2 = i0.ɵɵnextContext(2);
180
- i0.ɵɵclassProp("expanded", (ctx_r2.expandedComponent == null ? null : ctx_r2.expandedComponent.ID) === component_r2.ID)("running", (ctx_r2.selectedComponent == null ? null : ctx_r2.selectedComponent.ID) === component_r2.ID && ctx_r2.isRunning);
377
+ i0.ɵɵclassProp("expanded", ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r10))("running", ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) === ctx_r2.getComponentId(component_r10) && ctx_r2.isRunning)("file-loaded", ctx_r2.isFileLoadedComponent(component_r10));
181
378
  i0.ɵɵadvance(2);
182
- i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(component_r2.Type));
379
+ i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(ctx_r2.getComponentType(component_r10)));
183
380
  i0.ɵɵadvance();
184
- i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(component_r2.Type));
381
+ i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(ctx_r2.getComponentType(component_r10)));
382
+ i0.ɵɵadvance();
383
+ i0.ɵɵconditional(!ctx_r2.isFileLoadedComponent(component_r10) ? 4 : -1);
185
384
  i0.ɵɵadvance(3);
186
- i0.ɵɵtextInterpolate(component_r2.Name);
385
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.getComponentName(component_r10), " ");
386
+ i0.ɵɵadvance();
387
+ i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r10) ? 8 : -1);
187
388
  i0.ɵɵadvance(3);
188
- i0.ɵɵtextInterpolate(component_r2.Type || "Component");
389
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r10) || "Component");
189
390
  i0.ɵɵadvance(2);
190
- i0.ɵɵtextInterpolate1("v", component_r2.Version || "1.0.0", "");
391
+ i0.ɵɵtextInterpolate1("v", ctx_r2.getComponentVersion(component_r10), "");
191
392
  i0.ɵɵadvance();
192
- i0.ɵɵconditional(component_r2.Status === "Published" ? 12 : 13);
193
- i0.ɵɵadvance(3);
194
- i0.ɵɵconditional((ctx_r2.expandedComponent == null ? null : ctx_r2.expandedComponent.ID) === component_r2.ID ? 15 : 16);
393
+ i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r10) ? 14 : ctx_r2.getComponentStatus(component_r10) === "Published" ? 15 : 16);
394
+ i0.ɵɵadvance(4);
395
+ i0.ɵɵstyleProp("background-color", ctx_r2.getNamespaceColor(ctx_r2.getComponentNamespace(component_r10)));
396
+ i0.ɵɵproperty("title", ctx_r2.getComponentNamespace(component_r10) || "Uncategorized");
397
+ i0.ɵɵadvance(2);
398
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.formatNamespace(ctx_r2.getComponentNamespace(component_r10)), " ");
399
+ i0.ɵɵadvance(2);
400
+ i0.ɵɵconditional(ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r10) ? 22 : 23);
195
401
  i0.ɵɵadvance(2);
196
- i0.ɵɵconditional((ctx_r2.expandedComponent == null ? null : ctx_r2.expandedComponent.ID) === component_r2.ID ? 17 : -1);
402
+ i0.ɵɵconditional(ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r10) ? 24 : -1);
197
403
  } }
198
- function ComponentStudioDashboardComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
199
- i0.ɵɵrepeaterCreate(0, ComponentStudioDashboardComponent_Conditional_24_For_1_Template, 18, 13, "div", 23, _forTrack0);
404
+ function ComponentStudioDashboardComponent_Conditional_43_Template(rf, ctx) { if (rf & 1) {
405
+ i0.ɵɵrepeaterCreate(0, ComponentStudioDashboardComponent_Conditional_43_For_1_Template, 25, 21, "div", 56, _forTrack1, true);
200
406
  } if (rf & 2) {
201
407
  const ctx_r2 = i0.ɵɵnextContext();
202
408
  i0.ɵɵrepeater(ctx_r2.filteredComponents);
203
409
  } }
204
- function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
205
- i0.ɵɵelementStart(0, "details", 60)(1, "summary");
410
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
411
+ i0.ɵɵelementStart(0, "details", 103)(1, "summary");
206
412
  i0.ɵɵtext(2, "Technical Details (click to expand)");
207
413
  i0.ɵɵelementEnd();
208
414
  i0.ɵɵelementStart(3, "pre");
209
415
  i0.ɵɵtext(4);
210
416
  i0.ɵɵelementEnd()();
211
417
  } if (rf & 2) {
212
- const ctx_r2 = i0.ɵɵnextContext(3);
418
+ const ctx_r2 = i0.ɵɵnextContext(4);
213
419
  i0.ɵɵadvance(4);
214
420
  i0.ɵɵtextInterpolate(ctx_r2.formatTechnicalDetails(ctx_r2.currentError.technicalDetails));
215
421
  } }
216
- function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template(rf, ctx) { if (rf & 1) {
217
- const _r7 = i0.ɵɵgetCurrentView();
218
- i0.ɵɵelementStart(0, "div", 51)(1, "div", 53)(2, "div", 54);
219
- i0.ɵɵelement(3, "i", 55);
422
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
423
+ const _r16 = i0.ɵɵgetCurrentView();
424
+ i0.ɵɵelementStart(0, "div", 94)(1, "div", 96)(2, "div", 97);
425
+ i0.ɵɵelement(3, "i", 98);
220
426
  i0.ɵɵelementStart(4, "h3");
221
427
  i0.ɵɵtext(5, "Component Error");
222
428
  i0.ɵɵelementEnd();
223
- i0.ɵɵelementStart(6, "button", 56);
224
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.copyErrorToClipboard()); });
225
- i0.ɵɵelement(7, "i", 57);
429
+ i0.ɵɵelementStart(6, "button", 99);
430
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.copyErrorToClipboard()); });
431
+ i0.ɵɵelement(7, "i", 100);
226
432
  i0.ɵɵelementEnd()();
227
- i0.ɵɵelementStart(8, "p", 58);
433
+ i0.ɵɵelementStart(8, "p", 101);
228
434
  i0.ɵɵtext(9, " The component could not be rendered due to the following error: ");
229
435
  i0.ɵɵelementEnd();
230
- i0.ɵɵelementStart(10, "div", 59)(11, "strong");
436
+ i0.ɵɵelementStart(10, "div", 102)(11, "strong");
231
437
  i0.ɵɵtext(12, "Error Type:");
232
438
  i0.ɵɵelementEnd();
233
439
  i0.ɵɵtext(13);
@@ -236,9 +442,9 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
236
442
  i0.ɵɵtext(16, "Message:");
237
443
  i0.ɵɵelementEnd();
238
444
  i0.ɵɵtext(17);
239
- i0.ɵɵtemplate(18, ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Conditional_18_Template, 5, 1, "details", 60);
445
+ i0.ɵɵtemplate(18, ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Conditional_18_Template, 5, 1, "details", 103);
240
446
  i0.ɵɵelementEnd();
241
- i0.ɵɵelementStart(19, "div", 61)(20, "strong");
447
+ i0.ɵɵelementStart(19, "div", 104)(20, "strong");
242
448
  i0.ɵɵtext(21, "What to do:");
243
449
  i0.ɵɵelementEnd();
244
450
  i0.ɵɵelementStart(22, "ol")(23, "li");
@@ -253,18 +459,18 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
253
459
  i0.ɵɵelementStart(29, "li");
254
460
  i0.ɵɵtext(30, "Contact your system administrator if the issue persists");
255
461
  i0.ɵɵelementEnd()()();
256
- i0.ɵɵelementStart(31, "div", 62)(32, "button", 63);
257
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.retryComponent()); });
258
- i0.ɵɵelement(33, "span", 64);
462
+ i0.ɵɵelementStart(31, "div", 105)(32, "button", 106);
463
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.retryComponent()); });
464
+ i0.ɵɵelement(33, "span", 107);
259
465
  i0.ɵɵtext(34, " Retry ");
260
466
  i0.ɵɵelementEnd();
261
- i0.ɵɵelementStart(35, "button", 47);
262
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.stopComponent()); });
263
- i0.ɵɵelement(36, "span", 48);
467
+ i0.ɵɵelementStart(35, "button", 9);
468
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.stopComponent()); });
469
+ i0.ɵɵelement(36, "span", 85);
264
470
  i0.ɵɵtext(37, " Stop ");
265
471
  i0.ɵɵelementEnd()()()();
266
472
  } if (rf & 2) {
267
- const ctx_r2 = i0.ɵɵnextContext(2);
473
+ const ctx_r2 = i0.ɵɵnextContext(3);
268
474
  i0.ɵɵadvance(13);
269
475
  i0.ɵɵtextInterpolate1(" ", ctx_r2.currentError.type, "");
270
476
  i0.ɵɵadvance(4);
@@ -274,35 +480,203 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
274
480
  i0.ɵɵadvance(17);
275
481
  i0.ɵɵproperty("themeColor", "error");
276
482
  } }
277
- function ComponentStudioDashboardComponent_Conditional_27_Conditional_1_Template(rf, ctx) { if (rf & 1) {
278
- const _r8 = i0.ɵɵgetCurrentView();
279
- i0.ɵɵelementStart(0, "mj-react-component", 65);
280
- i0.ɵɵlistener("componentEvent", function ComponentStudioDashboardComponent_Conditional_27_Conditional_1_Template_mj_react_component_componentEvent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onComponentEvent($event)); })("openEntityRecord", function ComponentStudioDashboardComponent_Conditional_27_Conditional_1_Template_mj_react_component_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
483
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
484
+ const _r17 = i0.ɵɵgetCurrentView();
485
+ i0.ɵɵelementStart(0, "mj-react-component", 108);
486
+ i0.ɵɵlistener("componentEvent", function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_1_Template_mj_react_component_componentEvent_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onComponentEvent($event)); })("openEntityRecord", function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_1_Template_mj_react_component_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
281
487
  i0.ɵɵelementEnd();
282
488
  } if (rf & 2) {
283
- const ctx_r2 = i0.ɵɵnextContext(2);
489
+ const ctx_r2 = i0.ɵɵnextContext(3);
284
490
  i0.ɵɵproperty("component", ctx_r2.componentSpec);
285
491
  } }
286
- function ComponentStudioDashboardComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
287
- i0.ɵɵtemplate(0, ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template, 38, 4, "div", 51)(1, ComponentStudioDashboardComponent_Conditional_27_Conditional_1_Template, 1, 1, "mj-react-component", 52);
492
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Template(rf, ctx) { if (rf & 1) {
493
+ i0.ɵɵtemplate(0, ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_0_Template, 38, 4, "div", 94)(1, ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Conditional_1_Template, 1, 1, "mj-react-component", 95);
288
494
  } if (rf & 2) {
289
- const ctx_r2 = i0.ɵɵnextContext();
495
+ const ctx_r2 = i0.ɵɵnextContext(2);
290
496
  i0.ɵɵconditional(ctx_r2.currentError ? 0 : 1);
291
497
  } }
292
- function ComponentStudioDashboardComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
293
- i0.ɵɵelementStart(0, "div", 19);
294
- i0.ɵɵelement(1, "i", 66);
498
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
499
+ const _r18 = i0.ɵɵgetCurrentView();
500
+ i0.ɵɵelementStart(0, "div", 90);
501
+ i0.ɵɵelement(1, "i", 109);
502
+ i0.ɵɵelementStart(2, "h3");
503
+ i0.ɵɵtext(3);
504
+ i0.ɵɵelementEnd();
505
+ i0.ɵɵelementStart(4, "p");
506
+ i0.ɵɵtext(5);
507
+ i0.ɵɵelementEnd();
508
+ i0.ɵɵelementStart(6, "button", 110);
509
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_Conditional_4_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.runComponent(ctx_r2.selectedComponent)); });
510
+ i0.ɵɵelement(7, "span", 87);
511
+ i0.ɵɵtext(8, " Run Component ");
512
+ i0.ɵɵelementEnd()();
513
+ } if (rf & 2) {
514
+ const ctx_r2 = i0.ɵɵnextContext(2);
515
+ i0.ɵɵadvance(3);
516
+ i0.ɵɵtextInterpolate1("Component: ", ctx_r2.getComponentName(ctx_r2.selectedComponent), "");
517
+ i0.ɵɵadvance(2);
518
+ i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(ctx_r2.selectedComponent) || "No description available");
519
+ i0.ɵɵadvance();
520
+ i0.ɵɵproperty("themeColor", "primary")("size", "large");
521
+ } }
522
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_6_Template(rf, ctx) { if (rf & 1) {
523
+ const _r20 = i0.ɵɵgetCurrentView();
524
+ i0.ɵɵelementStart(0, "button", 9);
525
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.applySpecChanges()); });
526
+ i0.ɵɵelement(1, "span", 117);
527
+ i0.ɵɵtext(2, " Apply Changes ");
528
+ i0.ɵɵelementEnd();
529
+ i0.ɵɵelementStart(3, "button", 106);
530
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.initializeEditors()); });
531
+ i0.ɵɵelement(4, "span", 52);
532
+ i0.ɵɵtext(5, " Cancel ");
533
+ i0.ɵɵelementEnd();
534
+ } if (rf & 2) {
535
+ i0.ɵɵproperty("themeColor", "primary");
536
+ } }
537
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_7_Template(rf, ctx) { if (rf & 1) {
538
+ const _r21 = i0.ɵɵgetCurrentView();
539
+ i0.ɵɵelementStart(0, "button", 9);
540
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.refreshComponent()); });
541
+ i0.ɵɵelement(1, "span", 14);
542
+ i0.ɵɵtext(2, " Refresh Component ");
543
+ i0.ɵɵelementEnd();
544
+ } if (rf & 2) {
545
+ i0.ɵɵproperty("themeColor", "info");
546
+ } }
547
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Template(rf, ctx) { if (rf & 1) {
548
+ const _r19 = i0.ɵɵgetCurrentView();
549
+ i0.ɵɵelementStart(0, "div", 111)(1, "div", 112)(2, "h4");
550
+ i0.ɵɵelement(3, "i", 113);
551
+ i0.ɵɵtext(4, " Component Specification (JSON)");
552
+ i0.ɵɵelementEnd();
553
+ i0.ɵɵelementStart(5, "div", 114);
554
+ i0.ɵɵtemplate(6, ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_6_Template, 6, 1)(7, ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Conditional_7_Template, 3, 1, "button", 7);
555
+ i0.ɵɵelementEnd()();
556
+ i0.ɵɵelementStart(8, "div", 115)(9, "mj-code-editor", 116);
557
+ i0.ɵɵtwoWayListener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Template_mj_code_editor_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.editableSpec, $event) || (ctx_r2.editableSpec = $event); return i0.ɵɵresetView($event); });
558
+ i0.ɵɵlistener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Template_mj_code_editor_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onSpecChange($event)); });
559
+ i0.ɵɵelementEnd()()();
560
+ } if (rf & 2) {
561
+ const ctx_r2 = i0.ɵɵnextContext(2);
562
+ i0.ɵɵadvance(6);
563
+ i0.ɵɵconditional(ctx_r2.isEditingSpec ? 6 : -1);
564
+ i0.ɵɵadvance();
565
+ i0.ɵɵconditional(ctx_r2.isRunning ? 7 : -1);
566
+ i0.ɵɵadvance(2);
567
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r2.editableSpec);
568
+ i0.ɵɵproperty("language", "json")("readonly", false);
569
+ } }
570
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_6_Template(rf, ctx) { if (rf & 1) {
571
+ const _r22 = i0.ɵɵgetCurrentView();
572
+ i0.ɵɵelementStart(0, "button", 9);
573
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.applyCodeChanges()); });
574
+ i0.ɵɵelement(1, "span", 117);
575
+ i0.ɵɵtext(2, " Apply Changes ");
576
+ i0.ɵɵelementEnd();
577
+ i0.ɵɵelementStart(3, "button", 106);
578
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.initializeEditors()); });
579
+ i0.ɵɵelement(4, "span", 52);
580
+ i0.ɵɵtext(5, " Cancel ");
581
+ i0.ɵɵelementEnd();
582
+ } if (rf & 2) {
583
+ i0.ɵɵproperty("themeColor", "primary");
584
+ } }
585
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_7_Template(rf, ctx) { if (rf & 1) {
586
+ const _r23 = i0.ɵɵgetCurrentView();
587
+ i0.ɵɵelementStart(0, "button", 9);
588
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.refreshComponent()); });
589
+ i0.ɵɵelement(1, "span", 14);
590
+ i0.ɵɵtext(2, " Refresh Component ");
591
+ i0.ɵɵelementEnd();
592
+ } if (rf & 2) {
593
+ i0.ɵɵproperty("themeColor", "info");
594
+ } }
595
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_For_11_ng_template_1_Template(rf, ctx) { if (rf & 1) {
596
+ const _r24 = i0.ɵɵgetCurrentView();
597
+ i0.ɵɵelementStart(0, "mj-code-editor", 123);
598
+ i0.ɵɵlistener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_For_11_ng_template_1_Template_mj_code_editor_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r24); const ɵ$index_483_r25 = i0.ɵɵnextContext().$index; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onCodeSectionChange($event, ɵ$index_483_r25)); });
599
+ i0.ɵɵelementEnd();
600
+ } if (rf & 2) {
601
+ const section_r26 = i0.ɵɵnextContext().$implicit;
602
+ i0.ɵɵproperty("ngModel", section_r26.code)("language", "javascript")("readonly", false);
603
+ } }
604
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_For_11_Template(rf, ctx) { if (rf & 1) {
605
+ i0.ɵɵelementStart(0, "kendo-panelbar-item", 121);
606
+ i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_46_ng_template_11_For_11_ng_template_1_Template, 1, 3, "ng-template", 122);
607
+ i0.ɵɵelementEnd();
608
+ } if (rf & 2) {
609
+ const section_r26 = ctx.$implicit;
610
+ i0.ɵɵproperty("title", section_r26.title)("expanded", section_r26.expanded);
611
+ } }
612
+ function ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Template(rf, ctx) { if (rf & 1) {
613
+ i0.ɵɵelementStart(0, "div", 118)(1, "div", 112)(2, "h4");
614
+ i0.ɵɵelement(3, "i", 119);
615
+ i0.ɵɵtext(4, " Component Code (JavaScript/React)");
616
+ i0.ɵɵelementEnd();
617
+ i0.ɵɵelementStart(5, "div", 114);
618
+ i0.ɵɵtemplate(6, ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_6_Template, 6, 1)(7, ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Conditional_7_Template, 3, 1, "button", 7);
619
+ i0.ɵɵelementEnd()();
620
+ i0.ɵɵelementStart(8, "div", 115)(9, "kendo-panelbar", 120);
621
+ i0.ɵɵrepeaterCreate(10, ComponentStudioDashboardComponent_Conditional_46_ng_template_11_For_11_Template, 2, 2, "kendo-panelbar-item", 121, _forTrack2);
622
+ i0.ɵɵelementEnd()()();
623
+ } if (rf & 2) {
624
+ const ctx_r2 = i0.ɵɵnextContext(2);
625
+ i0.ɵɵadvance(6);
626
+ i0.ɵɵconditional(ctx_r2.isEditingCode ? 6 : -1);
627
+ i0.ɵɵadvance();
628
+ i0.ɵɵconditional(ctx_r2.isRunning ? 7 : -1);
629
+ i0.ɵɵadvance(3);
630
+ i0.ɵɵrepeater(ctx_r2.getComponentCodeSections());
631
+ } }
632
+ function ComponentStudioDashboardComponent_Conditional_46_Conditional_12_Template(rf, ctx) { }
633
+ function ComponentStudioDashboardComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
634
+ const _r15 = i0.ɵɵgetCurrentView();
635
+ i0.ɵɵelementStart(0, "kendo-splitter", 16)(1, "kendo-splitter-pane", 88)(2, "div", 89);
636
+ i0.ɵɵtemplate(3, ComponentStudioDashboardComponent_Conditional_46_Conditional_3_Template, 2, 1)(4, ComponentStudioDashboardComponent_Conditional_46_Conditional_4_Template, 9, 4, "div", 90);
637
+ i0.ɵɵelementEnd()();
638
+ i0.ɵɵelementStart(5, "kendo-splitter-pane", 88)(6, "div")(7, "kendo-tabstrip", 91);
639
+ i0.ɵɵlistener("tabSelect", function ComponentStudioDashboardComponent_Conditional_46_Template_kendo_tabstrip_tabSelect_7_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTabSelect($event)); });
640
+ i0.ɵɵelementStart(8, "kendo-tabstrip-tab", 92);
641
+ i0.ɵɵtemplate(9, ComponentStudioDashboardComponent_Conditional_46_ng_template_9_Template, 10, 5, "ng-template", 93);
642
+ i0.ɵɵelementEnd();
643
+ i0.ɵɵelementStart(10, "kendo-tabstrip-tab", 92);
644
+ i0.ɵɵtemplate(11, ComponentStudioDashboardComponent_Conditional_46_ng_template_11_Template, 12, 2, "ng-template", 93);
645
+ i0.ɵɵelementEnd()()()()();
646
+ i0.ɵɵtemplate(12, ComponentStudioDashboardComponent_Conditional_46_Conditional_12_Template, 0, 0);
647
+ } if (rf & 2) {
648
+ const ctx_r2 = i0.ɵɵnextContext();
649
+ i0.ɵɵadvance();
650
+ i0.ɵɵproperty("size", ctx_r2.isDetailsPaneCollapsed ? "100%" : "50%");
651
+ i0.ɵɵadvance(2);
652
+ i0.ɵɵconditional(ctx_r2.isRunning && ctx_r2.componentSpec ? 3 : 4);
653
+ i0.ɵɵadvance(2);
654
+ i0.ɵɵproperty("size", ctx_r2.isDetailsPaneCollapsed ? "0px" : "50%");
655
+ i0.ɵɵadvance(3);
656
+ i0.ɵɵproperty("title", "Spec")("selected", ctx_r2.activeTab === 0);
657
+ i0.ɵɵadvance(2);
658
+ i0.ɵɵproperty("title", "Code")("selected", ctx_r2.activeTab === 1);
659
+ i0.ɵɵadvance(2);
660
+ i0.ɵɵconditional(!ctx_r2.isDetailsPaneCollapsed ? 12 : -1);
661
+ } }
662
+ function ComponentStudioDashboardComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
663
+ i0.ɵɵelementStart(0, "div", 34);
664
+ i0.ɵɵelement(1, "i", 124);
295
665
  i0.ɵɵelementStart(2, "h2");
296
666
  i0.ɵɵtext(3, "Ready to Test Components");
297
667
  i0.ɵɵelementEnd();
298
668
  i0.ɵɵelementStart(4, "p");
299
- i0.ɵɵtext(5, "Select a component from the list and click \"Run Component\" to see it in action");
669
+ i0.ɵɵtext(5, "Select a component from the list to view its details and run it");
300
670
  i0.ɵɵelementEnd()();
301
671
  } }
302
672
  let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent extends BaseDashboard {
303
673
  cdr;
674
+ dialogService;
675
+ viewContainerRef;
304
676
  // Component data
305
677
  components = [];
678
+ fileLoadedComponents = []; // Components loaded from files
679
+ allComponents = []; // Combined list
306
680
  filteredComponents = [];
307
681
  selectedComponent = null;
308
682
  expandedComponent = null; // Track which card is expanded
@@ -310,12 +684,39 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
310
684
  isLoading = false;
311
685
  searchQuery = '';
312
686
  isRunning = false; // Track if component is currently running
687
+ // View and filtering
688
+ selectedCategories = new Set();
689
+ availableCategories = [];
690
+ showAllCategories = false; // Show only top categories by default
691
+ // Favorites
692
+ favoriteComponents = new Set(); // Set of component IDs
693
+ showOnlyFavorites = false; // Filter to show only favorites
694
+ metadata = new Metadata();
313
695
  // Error handling
314
696
  currentError = null;
697
+ // Tab management
698
+ activeTab = 0; // 0 = Spec, 1 = Code
699
+ // Splitter state
700
+ isDetailsPaneCollapsed = true; // Start with details collapsed
701
+ // Editor content
702
+ editableSpec = ''; // JSON string for spec editor
703
+ editableCode = ''; // JavaScript code for code editor
704
+ codeSections = [];
705
+ isEditingSpec = false;
706
+ isEditingCode = false;
707
+ lastEditSource = null;
708
+ // File input element reference
709
+ fileInput;
710
+ // Import dropdown state
711
+ importDropdownOpen = false;
712
+ // Text import dialog reference
713
+ textImportDialog;
315
714
  destroy$ = new Subject();
316
- constructor(cdr) {
715
+ constructor(cdr, dialogService, viewContainerRef) {
317
716
  super();
318
717
  this.cdr = cdr;
718
+ this.dialogService = dialogService;
719
+ this.viewContainerRef = viewContainerRef;
319
720
  }
320
721
  ngAfterViewInit() {
321
722
  this.initDashboard();
@@ -334,14 +735,16 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
334
735
  const rv = new RunView();
335
736
  const result = await rv.RunView({
336
737
  EntityName: 'MJ: Components',
337
- ExtraFilter: 'HasCustomProps = 0', // Only load components without custom props
738
+ ExtraFilter: 'HasRequiredCustomProps = 0', // Only load components without required custom props
338
739
  OrderBy: 'Name',
339
740
  MaxRows: 1000,
340
741
  ResultType: 'entity_object'
341
742
  });
342
743
  if (result.Success) {
343
744
  this.components = result.Results || [];
344
- this.filterComponents();
745
+ // Load favorites for all components
746
+ await this.loadFavorites();
747
+ this.combineAndFilterComponents();
345
748
  }
346
749
  else {
347
750
  console.error('Failed to load components:', result.ErrorMessage);
@@ -354,25 +757,288 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
354
757
  this.isLoading = false;
355
758
  }
356
759
  }
760
+ /**
761
+ * Load favorite status for all components
762
+ */
763
+ async loadFavorites() {
764
+ const md = new Metadata();
765
+ const currentUserId = md.CurrentUser?.ID;
766
+ if (!currentUserId)
767
+ return;
768
+ this.favoriteComponents.clear();
769
+ // Check favorite status for each component
770
+ for (const component of this.components) {
771
+ try {
772
+ const isFavorite = await this.metadata.GetRecordFavoriteStatus(currentUserId, 'MJ: Components', CompositeKey.FromID(component.ID));
773
+ if (isFavorite) {
774
+ this.favoriteComponents.add(component.ID);
775
+ }
776
+ }
777
+ catch (error) {
778
+ console.error(`Error loading favorite status for component ${component.ID}:`, error);
779
+ }
780
+ }
781
+ }
782
+ /**
783
+ * Toggle favorite status for a component
784
+ */
785
+ async toggleFavorite(component, event) {
786
+ if (event) {
787
+ event.stopPropagation(); // Prevent card expansion
788
+ }
789
+ const md = new Metadata();
790
+ const currentUserId = md.CurrentUser?.ID;
791
+ if (!currentUserId)
792
+ return;
793
+ // File-loaded components can't be favorited
794
+ if (this.isFileLoadedComponent(component)) {
795
+ return;
796
+ }
797
+ const componentId = this.getComponentId(component);
798
+ const isFavorite = this.favoriteComponents.has(componentId);
799
+ try {
800
+ await this.metadata.SetRecordFavoriteStatus(currentUserId, 'MJ: Components', CompositeKey.FromID(componentId), !isFavorite);
801
+ // Update local state
802
+ if (isFavorite) {
803
+ this.favoriteComponents.delete(componentId);
804
+ }
805
+ else {
806
+ this.favoriteComponents.add(componentId);
807
+ }
808
+ // Trigger change detection
809
+ this.cdr.detectChanges();
810
+ }
811
+ catch (error) {
812
+ console.error('Error toggling favorite status:', error);
813
+ }
814
+ }
815
+ /**
816
+ * Check if component is favorited
817
+ */
818
+ isFavorite(component) {
819
+ if (this.isFileLoadedComponent(component)) {
820
+ return false;
821
+ }
822
+ return this.favoriteComponents.has(this.getComponentId(component));
823
+ }
824
+ /**
825
+ * Toggle showing only favorites
826
+ */
827
+ toggleShowOnlyFavorites() {
828
+ this.showOnlyFavorites = !this.showOnlyFavorites;
829
+ this.combineAndFilterComponents();
830
+ }
357
831
  onSearchChange(query) {
358
832
  this.searchQuery = query;
359
- this.filterComponents();
833
+ this.combineAndFilterComponents();
360
834
  }
361
- filterComponents() {
362
- // Note: this.components already filtered to HasCustomProps = 0 in loadData
363
- if (!this.searchQuery) {
364
- this.filteredComponents = [...this.components];
835
+ combineAndFilterComponents() {
836
+ // Combine database components with file-loaded components
837
+ this.allComponents = [
838
+ ...this.fileLoadedComponents,
839
+ ...this.components
840
+ ];
841
+ // Build available categories from all components
842
+ this.buildCategories();
843
+ // Apply filters
844
+ let filtered = [...this.allComponents];
845
+ // Apply favorites filter first if enabled
846
+ if (this.showOnlyFavorites) {
847
+ filtered = filtered.filter(c => this.isFavorite(c));
365
848
  }
366
- else {
849
+ // Apply category filter
850
+ if (this.selectedCategories.size > 0) {
851
+ filtered = filtered.filter(c => {
852
+ const namespace = this.getComponentNamespace(c) || 'Uncategorized';
853
+ const category = this.extractCategoryFromNamespace(namespace);
854
+ return this.selectedCategories.has(category);
855
+ });
856
+ }
857
+ // Apply search filter
858
+ if (this.searchQuery) {
367
859
  const query = this.searchQuery.toLowerCase();
368
- this.filteredComponents = this.components.filter(c => c.Name?.toLowerCase().includes(query) ||
369
- c.Description?.toLowerCase().includes(query) ||
370
- c.Type?.toLowerCase().includes(query));
860
+ filtered = filtered.filter(c => {
861
+ const name = this.getComponentName(c)?.toLowerCase() || '';
862
+ const description = this.getComponentDescription(c)?.toLowerCase() || '';
863
+ const type = this.getComponentType(c)?.toLowerCase() || '';
864
+ const namespace = this.getComponentNamespace(c)?.toLowerCase() || '';
865
+ return name.includes(query) || description.includes(query) || type.includes(query) || namespace.includes(query);
866
+ });
867
+ }
868
+ this.filteredComponents = filtered;
869
+ }
870
+ /**
871
+ * Build categories from components
872
+ */
873
+ buildCategories() {
874
+ const categoryMap = new Map();
875
+ const allNamespaces = new Set();
876
+ // Count components per top-level category and track all namespaces
877
+ for (const component of this.allComponents) {
878
+ const namespace = this.getComponentNamespace(component) || 'Uncategorized';
879
+ const category = this.extractCategoryFromNamespace(namespace);
880
+ categoryMap.set(category, (categoryMap.get(category) || 0) + 1);
881
+ // Track full namespace paths for better display
882
+ if (namespace && namespace !== 'Uncategorized') {
883
+ allNamespaces.add(namespace);
884
+ }
885
+ }
886
+ // Convert to array and sort by count
887
+ this.availableCategories = Array.from(categoryMap.entries())
888
+ .map(([name, count]) => ({
889
+ name,
890
+ count,
891
+ color: this.getCategoryColor(name)
892
+ }))
893
+ .sort((a, b) => b.count - a.count);
894
+ }
895
+ /**
896
+ * Extract main category from namespace
897
+ */
898
+ extractCategoryFromNamespace(namespace) {
899
+ if (!namespace || namespace === 'Uncategorized')
900
+ return 'Uncategorized';
901
+ // Get the first part of the namespace path
902
+ const parts = namespace.split('/').filter(p => p.length > 0);
903
+ return parts[0] || 'Uncategorized';
904
+ }
905
+ /**
906
+ * Get color for category
907
+ */
908
+ getCategoryColor(category) {
909
+ const colors = [
910
+ '#3B82F6', // blue
911
+ '#8B5CF6', // purple
912
+ '#10B981', // green
913
+ '#F97316', // orange
914
+ '#06B6D4', // cyan
915
+ '#EC4899', // pink
916
+ '#6366F1', // indigo
917
+ '#14B8A6', // teal
918
+ '#EAB308', // yellow
919
+ '#EF4444', // red
920
+ ];
921
+ // Use hash of category name to get consistent color
922
+ let hash = 0;
923
+ for (let i = 0; i < category.length; i++) {
924
+ hash = category.charCodeAt(i) + ((hash << 5) - hash);
925
+ }
926
+ return colors[Math.abs(hash) % colors.length];
927
+ }
928
+ /**
929
+ * Get color for a full namespace path
930
+ */
931
+ getNamespaceColor(namespace) {
932
+ if (!namespace || namespace === 'Uncategorized') {
933
+ return '#6C757D'; // Gray for uncategorized
934
+ }
935
+ // Extract the main category (first part) for consistent coloring
936
+ const category = this.extractCategoryFromNamespace(namespace);
937
+ return this.getCategoryColor(category);
938
+ }
939
+ /**
940
+ * Format namespace for display (handle long paths)
941
+ */
942
+ formatNamespace(namespace) {
943
+ if (!namespace || namespace === 'Uncategorized') {
944
+ return 'Uncategorized';
945
+ }
946
+ const parts = namespace.split('/').filter(p => p.length > 0);
947
+ // If it's really long, show abbreviated version
948
+ if (parts.length > 3) {
949
+ return `${parts[0]} / ... / ${parts[parts.length - 1]}`;
371
950
  }
951
+ // Otherwise show full path with spacing
952
+ return parts.join(' / ');
953
+ }
954
+ /**
955
+ * Toggle category filter
956
+ */
957
+ toggleCategory(category) {
958
+ if (this.selectedCategories.has(category)) {
959
+ this.selectedCategories.delete(category);
960
+ }
961
+ else {
962
+ this.selectedCategories.add(category);
963
+ }
964
+ this.combineAndFilterComponents();
965
+ }
966
+ /**
967
+ * Clear all category filters
968
+ */
969
+ clearCategoryFilters() {
970
+ this.selectedCategories.clear();
971
+ this.combineAndFilterComponents();
972
+ }
973
+ /**
974
+ * Check if category is selected
975
+ */
976
+ isCategorySelected(category) {
977
+ return this.selectedCategories.has(category);
978
+ }
979
+ /**
980
+ * Get visible categories (top 5 or all)
981
+ */
982
+ getVisibleCategories() {
983
+ return this.showAllCategories ? this.availableCategories : this.availableCategories.slice(0, 5);
984
+ }
985
+ /**
986
+ * Toggle showing all categories
987
+ */
988
+ toggleShowAllCategories() {
989
+ this.showAllCategories = !this.showAllCategories;
990
+ }
991
+ /**
992
+ * Get component namespace
993
+ */
994
+ getComponentNamespace(component) {
995
+ if (component.isFileLoaded) {
996
+ // File-loaded components might not have namespace
997
+ return component.specification.namespace;
998
+ }
999
+ else {
1000
+ return component.Namespace || undefined;
1001
+ }
1002
+ }
1003
+ // Helper methods to get properties from union type
1004
+ getComponentName(component) {
1005
+ return component.isFileLoaded ? component.name : component.Name;
1006
+ }
1007
+ getComponentDescription(component) {
1008
+ return component.isFileLoaded ? component.description : (component.Description || undefined);
1009
+ }
1010
+ getComponentType(component) {
1011
+ return component.isFileLoaded ? component.type : (component.Type || undefined);
1012
+ }
1013
+ getComponentStatus(component) {
1014
+ return component.isFileLoaded ? component.status : (component.Status || undefined);
1015
+ }
1016
+ getComponentVersion(component) {
1017
+ return component.isFileLoaded ? '1.0.0' : (component.Version || '1.0.0');
1018
+ }
1019
+ getComponentSpec(component) {
1020
+ return component.isFileLoaded ? component.specification : JSON.parse(component.Specification);
1021
+ }
1022
+ getComponentId(component) {
1023
+ return component.isFileLoaded ? component.id : component.ID;
1024
+ }
1025
+ isFileLoadedComponent(component) {
1026
+ return component.isFileLoaded === true;
1027
+ }
1028
+ getComponentFilename(component) {
1029
+ return component.isFileLoaded ? component.filename : undefined;
1030
+ }
1031
+ getComponentLoadedAt(component) {
1032
+ return component.isFileLoaded ? component.loadedAt : undefined;
1033
+ }
1034
+ getComponentUpdatedAt(component) {
1035
+ return !component.isFileLoaded && component.__mj_UpdatedAt ? component.__mj_UpdatedAt : undefined;
372
1036
  }
373
1037
  toggleComponentExpansion(component) {
374
1038
  // Toggle expansion - if clicking the same component, collapse it
375
- if (this.expandedComponent?.ID === component.ID) {
1039
+ const componentId = this.getComponentId(component);
1040
+ const expandedId = this.expandedComponent ? this.getComponentId(this.expandedComponent) : null;
1041
+ if (expandedId === componentId) {
376
1042
  this.expandedComponent = null;
377
1043
  }
378
1044
  else {
@@ -382,7 +1048,9 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
382
1048
  }
383
1049
  runComponent(component) {
384
1050
  // If another component is running, stop it first then start the new one
385
- if (this.isRunning && this.selectedComponent?.ID !== component.ID) {
1051
+ const componentId = this.getComponentId(component);
1052
+ const selectedId = this.selectedComponent ? this.getComponentId(this.selectedComponent) : null;
1053
+ if (this.isRunning && selectedId !== componentId) {
386
1054
  this.stopComponent();
387
1055
  this.startComponent(component);
388
1056
  }
@@ -392,10 +1060,12 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
392
1060
  }
393
1061
  startComponent(component) {
394
1062
  this.selectedComponent = component;
395
- this.componentSpec = JSON.parse(component.Specification);
1063
+ this.componentSpec = this.getComponentSpec(component);
396
1064
  this.isRunning = true;
397
1065
  this.currentError = null; // Clear any previous errors
398
- console.log('Running component:', component.Name);
1066
+ this.isDetailsPaneCollapsed = true; // Start with details collapsed
1067
+ this.initializeEditors(); // Initialize spec and code editors
1068
+ console.log('Running component:', this.getComponentName(component));
399
1069
  try {
400
1070
  this.cdr.detectChanges();
401
1071
  }
@@ -458,7 +1128,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
458
1128
  const errorText = `
459
1129
  Component Error Report
460
1130
  ${'='.repeat(50)}
461
- Component: ${this.selectedComponent?.Name}
1131
+ Component: ${this.selectedComponent ? this.getComponentName(this.selectedComponent) : 'Unknown'}
462
1132
  Error Type: ${this.currentError.type}
463
1133
  Message: ${this.currentError.message}
464
1134
  ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify(this.currentError.technicalDetails, null, 2) : ''}
@@ -483,6 +1153,143 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
483
1153
  async refreshData() {
484
1154
  await this.loadData();
485
1155
  }
1156
+ // Import handling methods
1157
+ toggleImportDropdown() {
1158
+ this.importDropdownOpen = !this.importDropdownOpen;
1159
+ }
1160
+ closeImportDropdown() {
1161
+ this.importDropdownOpen = false;
1162
+ }
1163
+ onDocumentClick(event) {
1164
+ // Close dropdown if clicking outside
1165
+ const target = event.target;
1166
+ const dropdown = target.closest('.import-dropdown');
1167
+ if (!dropdown && this.importDropdownOpen) {
1168
+ this.importDropdownOpen = false;
1169
+ }
1170
+ }
1171
+ importFromFile() {
1172
+ this.closeImportDropdown();
1173
+ this.fileInput?.nativeElement.click();
1174
+ }
1175
+ importFromText() {
1176
+ this.closeImportDropdown();
1177
+ this.openTextImportDialog();
1178
+ }
1179
+ openTextImportDialog() {
1180
+ this.textImportDialog = this.dialogService.open({
1181
+ content: TextImportDialogComponent,
1182
+ width: 700,
1183
+ height: 600,
1184
+ minWidth: 500,
1185
+ title: '', // Title is in the component
1186
+ actions: [], // Actions are in the component
1187
+ appendTo: this.viewContainerRef
1188
+ });
1189
+ // Handle the import event from the dialog component
1190
+ const dialogComponentRef = this.textImportDialog.content.instance;
1191
+ // Subscribe to import event
1192
+ dialogComponentRef.importSpec.subscribe((spec) => {
1193
+ this.handleTextImport(spec);
1194
+ this.textImportDialog?.close();
1195
+ });
1196
+ // Subscribe to cancel event
1197
+ dialogComponentRef.cancelDialog.subscribe(() => {
1198
+ this.textImportDialog?.close();
1199
+ });
1200
+ }
1201
+ async handleTextImport(spec) {
1202
+ // Create a file-loaded component (reusing the same structure)
1203
+ const textComponent = {
1204
+ id: this.generateId(),
1205
+ name: spec.name,
1206
+ description: spec.description,
1207
+ specification: spec,
1208
+ filename: 'text-import.json',
1209
+ loadedAt: new Date(),
1210
+ isFileLoaded: true,
1211
+ type: spec.type || 'Component',
1212
+ status: 'Text'
1213
+ };
1214
+ // Add to the list and refresh
1215
+ this.fileLoadedComponents.push(textComponent);
1216
+ this.combineAndFilterComponents();
1217
+ console.log(`Loaded component "${spec.name}" from text input`);
1218
+ // Automatically select and run the newly loaded component
1219
+ this.expandedComponent = textComponent;
1220
+ this.runComponent(textComponent);
1221
+ }
1222
+ async handleFileSelect(event) {
1223
+ const input = event.target;
1224
+ const file = input.files?.[0];
1225
+ if (!file)
1226
+ return;
1227
+ // Only accept JSON files
1228
+ if (!file.name.endsWith('.json')) {
1229
+ console.error('Please select a JSON file');
1230
+ // Could add a toast notification here
1231
+ return;
1232
+ }
1233
+ try {
1234
+ const fileContent = await this.readFile(file);
1235
+ const spec = JSON.parse(fileContent);
1236
+ // Validate the spec has required fields
1237
+ if (!spec.name || !spec.code) {
1238
+ console.error('Invalid component specification: missing required fields (name, code)');
1239
+ return;
1240
+ }
1241
+ // Create a file-loaded component
1242
+ const fileComponent = {
1243
+ id: this.generateId(),
1244
+ name: spec.name,
1245
+ description: spec.description,
1246
+ specification: spec,
1247
+ filename: file.name,
1248
+ loadedAt: new Date(),
1249
+ isFileLoaded: true,
1250
+ type: spec.type || 'Component',
1251
+ status: 'File'
1252
+ };
1253
+ // Add to the list and refresh
1254
+ this.fileLoadedComponents.push(fileComponent);
1255
+ this.combineAndFilterComponents();
1256
+ console.log(`Loaded component "${spec.name}" from ${file.name}`);
1257
+ // Automatically select and run the newly loaded component
1258
+ this.expandedComponent = fileComponent;
1259
+ this.runComponent(fileComponent);
1260
+ // Clear the input for future uploads
1261
+ input.value = '';
1262
+ }
1263
+ catch (error) {
1264
+ console.error('Error loading component file:', error);
1265
+ }
1266
+ }
1267
+ readFile(file) {
1268
+ return new Promise((resolve, reject) => {
1269
+ const reader = new FileReader();
1270
+ reader.onload = (e) => resolve(e.target?.result);
1271
+ reader.onerror = reject;
1272
+ reader.readAsText(file);
1273
+ });
1274
+ }
1275
+ generateId() {
1276
+ return 'file-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
1277
+ }
1278
+ removeFileComponent(component) {
1279
+ const index = this.fileLoadedComponents.indexOf(component);
1280
+ if (index > -1) {
1281
+ this.fileLoadedComponents.splice(index, 1);
1282
+ // If this was the selected component, clear it
1283
+ if (this.selectedComponent === component) {
1284
+ this.stopComponent();
1285
+ }
1286
+ // If this was the expanded component, clear it
1287
+ if (this.expandedComponent === component) {
1288
+ this.expandedComponent = null;
1289
+ }
1290
+ this.combineAndFilterComponents();
1291
+ }
1292
+ }
486
1293
  getComponentTypeIcon(type) {
487
1294
  const icons = {
488
1295
  'Report': 'fa-file-alt',
@@ -511,47 +1318,313 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
511
1318
  };
512
1319
  return colors[type || ''] || '#9CA3AF';
513
1320
  }
514
- static ɵfac = function ComponentStudioDashboardComponent_Factory(t) { return new (t || ComponentStudioDashboardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
515
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentStudioDashboardComponent, selectors: [["mj-component-studio-dashboard"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 29, vars: 9, consts: [[1, "component-studio"], [1, "dashboard-header"], [1, "header-content"], [1, "fa-solid", "fa-puzzle-piece"], [1, "header-subtitle"], ["kendoButton", "", 3, "click", "disabled"], [1, "fa-solid", "fa-sync"], ["orientation", "horizontal", 2, "flex", "1", "height", "auto"], [3, "min", "max", "size"], [1, "components-panel"], [1, "panel-header"], [1, "search-box"], ["placeholder", "Search components...", 3, "valueChange", "value", "clearButton"], ["kendoTextBoxPrefixTemplate", ""], [1, "components-list"], [1, "loading-message"], [1, "empty-message"], [3, "min"], [1, "component-display"], [1, "empty-state"], [1, "fa-solid", "fa-search"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-info-circle"], [1, "component-card", 3, "expanded", "running"], [1, "component-card"], [1, "card-header", 3, "click"], [1, "card-icon"], [1, "fa-solid", 3, "ngClass"], [1, "card-info"], [1, "card-name"], [1, "card-meta"], [1, "card-type"], [1, "card-version"], [1, "status-badge", "published"], [1, "status-badge", "draft"], [1, "card-chevron"], [1, "fa-solid", "fa-chevron-up"], [1, "fa-solid", "fa-chevron-down"], [1, "card-details"], [1, "detail-section"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "card-actions"], ["kendoButton", "", 3, "themeColor"], ["kendoButton", "", "title", "Stop current component and run this one", 3, "themeColor"], ["kendoButton", "", 3, "click", "themeColor"], [1, "fa-solid", "fa-stop"], ["kendoButton", "", "title", "Stop current component and run this one", 3, "click", "themeColor"], [1, "fa-solid", "fa-play"], [1, "error-display"], [3, "component"], [1, "error-container"], [1, "error-header"], [1, "fa-solid", "fa-exclamation-triangle"], ["title", "Copy error details", 1, "copy-button", 3, "click"], [1, "fa-solid", "fa-copy"], [1, "error-intro"], [1, "error-details"], [1, "technical-details"], [1, "error-help"], [1, "error-actions"], ["kendoButton", "", 3, "click"], [1, "fa-solid", "fa-rotate"], [3, "componentEvent", "openEntityRecord", "component"], [1, "fa-solid", "fa-rocket", "fa-3x"]], template: function ComponentStudioDashboardComponent_Template(rf, ctx) { if (rf & 1) {
516
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div")(4, "h1");
517
- i0.ɵɵelement(5, "i", 3);
1321
+ /**
1322
+ * Initialize the spec and code editors when a component is selected
1323
+ */
1324
+ initializeEditors() {
1325
+ if (this.selectedComponent) {
1326
+ const spec = this.getComponentSpec(this.selectedComponent);
1327
+ // Deep parse the spec for better readability
1328
+ const parseOptions = {
1329
+ extractInlineJson: true,
1330
+ maxDepth: 100,
1331
+ debug: false
1332
+ };
1333
+ const parsed = ParseJSONRecursive(spec, parseOptions);
1334
+ this.editableSpec = JSON.stringify(parsed, null, 2);
1335
+ // Extract code from spec
1336
+ this.editableCode = spec.code || '// No code available';
1337
+ // Build code sections array
1338
+ this.buildCodeSections();
1339
+ // Reset editing flags
1340
+ this.isEditingSpec = false;
1341
+ this.isEditingCode = false;
1342
+ this.lastEditSource = null;
1343
+ }
1344
+ }
1345
+ /**
1346
+ * Handle spec editor changes
1347
+ */
1348
+ onSpecChange(newSpec) {
1349
+ this.editableSpec = newSpec;
1350
+ this.isEditingSpec = true;
1351
+ this.lastEditSource = 'spec';
1352
+ }
1353
+ /**
1354
+ * Handle code editor changes
1355
+ */
1356
+ onCodeChange(newCode) {
1357
+ this.editableCode = newCode;
1358
+ this.isEditingCode = true;
1359
+ this.lastEditSource = 'code';
1360
+ }
1361
+ /**
1362
+ * Apply spec changes and update the code tab
1363
+ */
1364
+ applySpecChanges() {
1365
+ try {
1366
+ const parsed = JSON.parse(this.editableSpec);
1367
+ // Update the component spec
1368
+ if (this.selectedComponent) {
1369
+ if (this.isFileLoadedComponent(this.selectedComponent)) {
1370
+ // Update file-loaded component
1371
+ this.selectedComponent.specification = parsed;
1372
+ }
1373
+ else {
1374
+ // Update database component's Specification field in memory only
1375
+ this.selectedComponent.Specification = JSON.stringify(parsed);
1376
+ }
1377
+ // Update the runtime spec
1378
+ this.componentSpec = parsed;
1379
+ // Update the code editor with new code from spec
1380
+ this.editableCode = parsed.code || '// No code available';
1381
+ // Rebuild code sections from updated spec
1382
+ this.buildCodeSections();
1383
+ // If component is running, update it without full refresh
1384
+ if (this.isRunning) {
1385
+ this.updateRunningComponent();
1386
+ }
1387
+ this.isEditingSpec = false;
1388
+ }
1389
+ }
1390
+ catch (error) {
1391
+ console.error('Invalid JSON in spec editor:', error);
1392
+ // Could show a toast notification here
1393
+ }
1394
+ }
1395
+ /**
1396
+ * Apply code changes and update the spec
1397
+ */
1398
+ applyCodeChanges() {
1399
+ if (this.selectedComponent) {
1400
+ try {
1401
+ // Parse the current spec
1402
+ const spec = JSON.parse(this.editableSpec);
1403
+ // Update main code and dependencies from code sections
1404
+ if (this.codeSections.length > 0) {
1405
+ // First section is always the main component
1406
+ spec.code = this.codeSections[0].code;
1407
+ // Update dependencies if any
1408
+ if (this.codeSections.length > 1 && spec.dependencies) {
1409
+ for (let i = 1; i < this.codeSections.length; i++) {
1410
+ const section = this.codeSections[i];
1411
+ if (section.index !== undefined && spec.dependencies[section.index]) {
1412
+ spec.dependencies[section.index].code = section.code;
1413
+ }
1414
+ }
1415
+ }
1416
+ }
1417
+ // Update the spec editor
1418
+ const parseOptions = {
1419
+ extractInlineJson: true,
1420
+ maxDepth: 100,
1421
+ debug: false
1422
+ };
1423
+ const parsed = ParseJSONRecursive(spec, parseOptions);
1424
+ this.editableSpec = JSON.stringify(parsed, null, 2);
1425
+ // Update the component entity in memory
1426
+ if (this.isFileLoadedComponent(this.selectedComponent)) {
1427
+ this.selectedComponent.specification = spec;
1428
+ }
1429
+ else {
1430
+ // Update database component's Specification field in memory only
1431
+ this.selectedComponent.Specification = JSON.stringify(spec);
1432
+ }
1433
+ // Update the runtime spec
1434
+ this.componentSpec = spec;
1435
+ // If component is running, update it without full refresh
1436
+ if (this.isRunning) {
1437
+ this.updateRunningComponent();
1438
+ }
1439
+ this.isEditingCode = false;
1440
+ }
1441
+ catch (error) {
1442
+ console.error('Error applying code changes:', error);
1443
+ }
1444
+ }
1445
+ }
1446
+ /**
1447
+ * Refresh the running component with new spec/code (in-place update)
1448
+ */
1449
+ refreshComponent() {
1450
+ if (this.selectedComponent && this.isRunning) {
1451
+ // Use the same in-place update logic as Apply Changes
1452
+ this.updateRunningComponent();
1453
+ }
1454
+ }
1455
+ /**
1456
+ * Update the running component without full refresh
1457
+ */
1458
+ updateRunningComponent() {
1459
+ if (this.selectedComponent && this.isRunning) {
1460
+ // Get the updated spec
1461
+ const spec = this.getComponentSpec(this.selectedComponent);
1462
+ // Temporarily set to null to force React to re-render
1463
+ this.componentSpec = null;
1464
+ this.cdr.detectChanges();
1465
+ // Then set the new spec
1466
+ setTimeout(() => {
1467
+ this.componentSpec = spec;
1468
+ try {
1469
+ this.cdr.detectChanges();
1470
+ }
1471
+ catch (error) {
1472
+ console.error('Error with cdr.detectChanges():', error);
1473
+ }
1474
+ }, 10);
1475
+ }
1476
+ }
1477
+ /**
1478
+ * Build code sections array from spec
1479
+ */
1480
+ buildCodeSections() {
1481
+ if (!this.selectedComponent) {
1482
+ this.codeSections = [];
1483
+ return;
1484
+ }
1485
+ const spec = this.getComponentSpec(this.selectedComponent);
1486
+ const sections = [];
1487
+ // Main component code
1488
+ sections.push({
1489
+ title: spec.name || 'Main Component',
1490
+ code: spec.code || '// No code available',
1491
+ expanded: true,
1492
+ isDependency: false
1493
+ });
1494
+ // Add dependent components if any
1495
+ if (spec.dependencies && Array.isArray(spec.dependencies)) {
1496
+ spec.dependencies.forEach((dep, index) => {
1497
+ sections.push({
1498
+ title: dep.name || `Dependency ${index + 1}`,
1499
+ code: dep.code || '// No code available',
1500
+ expanded: false,
1501
+ isDependency: true,
1502
+ index: index
1503
+ });
1504
+ });
1505
+ }
1506
+ this.codeSections = sections;
1507
+ }
1508
+ /**
1509
+ * Get component code sections for panel bar
1510
+ */
1511
+ getComponentCodeSections() {
1512
+ return this.codeSections;
1513
+ }
1514
+ /**
1515
+ * Handle code section changes
1516
+ */
1517
+ onCodeSectionChange(newCode, sectionIndex) {
1518
+ if (this.codeSections[sectionIndex]) {
1519
+ this.codeSections[sectionIndex].code = newCode;
1520
+ this.isEditingCode = true;
1521
+ this.lastEditSource = 'code';
1522
+ }
1523
+ }
1524
+ /**
1525
+ * Toggle the details pane (spec/code editors)
1526
+ */
1527
+ toggleDetailsPane() {
1528
+ this.isDetailsPaneCollapsed = !this.isDetailsPaneCollapsed;
1529
+ this.cdr.detectChanges();
1530
+ }
1531
+ /**
1532
+ * Handle tab selection
1533
+ */
1534
+ onTabSelect(event) {
1535
+ this.activeTab = event.index;
1536
+ // Initialize editors when switching to spec or code tabs
1537
+ // Both tabs now need initialization since there's no separate Run tab
1538
+ this.initializeEditors();
1539
+ }
1540
+ static ɵfac = function ComponentStudioDashboardComponent_Factory(t) { return new (t || ComponentStudioDashboardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef)); };
1541
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentStudioDashboardComponent, selectors: [["mj-component-studio-dashboard"]], viewQuery: function ComponentStudioDashboardComponent_Query(rf, ctx) { if (rf & 1) {
1542
+ i0.ɵɵviewQuery(_c0, 5);
1543
+ } if (rf & 2) {
1544
+ let _t;
1545
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fileInput = _t.first);
1546
+ } }, hostBindings: function ComponentStudioDashboardComponent_HostBindings(rf, ctx) { if (rf & 1) {
1547
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_click_HostBindingHandler($event) { return ctx.onDocumentClick($event); }, false, i0.ɵɵresolveDocument);
1548
+ } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 48, vars: 20, consts: [["fileInput", ""], [1, "component-studio"], [1, "dashboard-header"], [1, "header-content"], [1, "fa-solid", "fa-puzzle-piece"], [1, "header-subtitle"], [1, "header-buttons"], ["kendoButton", "", 3, "themeColor"], [1, "import-dropdown"], ["kendoButton", "", 3, "click", "themeColor"], [1, "fa-solid", "fa-file-import"], [1, "fa-solid", "fa-chevron-down", 2, "margin-left", "5px", "font-size", "10px"], [1, "dropdown-menu"], ["kendoButton", "", 3, "click", "disabled"], [1, "fa-solid", "fa-sync"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], ["orientation", "horizontal"], [3, "min", "max", "size"], [1, "components-panel"], [1, "panel-header"], [1, "panel-header-top"], [1, "header-actions"], ["title", "Show only favorites", 1, "favorites-toggle", 3, "click"], [1, "component-count"], [1, "category-filters"], [1, "filter-pills"], [1, "search-box"], ["placeholder", "Search components...", 3, "valueChange", "value", "clearButton"], ["kendoTextBoxPrefixTemplate", ""], [1, "components-list"], [1, "loading-message"], [1, "empty-message"], [3, "min"], [1, "component-display"], [1, "empty-state"], [1, "fa-solid", "fa-eye"], [1, "fa-solid", "fa-eye-slash"], [1, "dropdown-item", 3, "click"], [1, "fa-solid", "fa-file"], [1, "fa-solid", "fa-keyboard"], [1, "fa-solid", "fa-star"], [1, "fa-regular", "fa-star"], [1, "category-pill", 3, "active", "--pill-color"], [1, "more-button"], [1, "clear-filters-button"], [1, "category-pill", 3, "click"], [1, "pill-name"], [1, "pill-count"], [1, "more-button", 3, "click"], [1, "fa-solid", "fa-chevron-up"], [1, "fa-solid", "fa-chevron-down"], [1, "clear-filters-button", 3, "click"], [1, "fa-solid", "fa-times"], [1, "fa-solid", "fa-search"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-info-circle"], [1, "component-card", 3, "expanded", "running", "file-loaded"], [1, "component-card"], [1, "card-header", 3, "click"], [1, "card-icon"], [1, "fa-solid", 3, "ngClass"], [1, "favorite-btn", 3, "is-favorite", "title"], [1, "card-info"], [1, "card-name"], [1, "file-badge", 3, "title"], [1, "card-meta"], [1, "card-type"], [1, "card-version"], [1, "status-badge", "published"], [1, "status-badge", "draft"], [1, "card-namespace"], [1, "namespace-chip", 3, "title"], [1, "fa-solid", "fa-folder-tree"], [1, "card-chevron"], [1, "card-details"], [1, "favorite-btn", 3, "click", "title"], [1, "status-badge", "text"], [1, "status-badge", "file"], [1, "detail-section"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "card-actions"], ["kendoButton", "", "title", "Stop current component and run this one", 3, "themeColor"], [1, "fa-solid", "fa-stop"], ["kendoButton", "", "title", "Stop current component and run this one", 3, "click", "themeColor"], [1, "fa-solid", "fa-play"], [3, "size"], [1, "component-runtime"], [1, "run-empty-state"], [1, "editor-tabs", 3, "tabSelect"], [3, "title", "selected"], ["kendoTabContent", ""], [1, "error-display"], [3, "component"], [1, "error-container"], [1, "error-header"], [1, "fa-solid", "fa-exclamation-triangle"], ["title", "Copy error details", 1, "copy-button", 3, "click"], [1, "fa-solid", "fa-copy"], [1, "error-intro"], [1, "error-details"], [1, "technical-details"], [1, "error-help"], [1, "error-actions"], ["kendoButton", "", 3, "click"], [1, "fa-solid", "fa-rotate"], [3, "componentEvent", "openEntityRecord", "component"], [1, "fa-solid", "fa-play-circle", "fa-3x"], ["kendoButton", "", 3, "click", "themeColor", "size"], [1, "tab-content", "spec-tab"], [1, "editor-header"], [1, "fa-solid", "fa-code"], [1, "editor-actions"], [1, "editor-wrapper"], [2, "height", "100%", "width", "100%", 3, "ngModelChange", "ngModel", "language", "readonly"], [1, "fa-solid", "fa-check"], [1, "tab-content", "code-tab"], [1, "fa-solid", "fa-file-code"], [1, "code-sections"], [3, "title", "expanded"], ["kendoPanelBarContent", ""], [2, "height", "400px", "width", "100%", 3, "ngModelChange", "ngModel", "language", "readonly"], [1, "fa-solid", "fa-rocket", "fa-3x"]], template: function ComponentStudioDashboardComponent_Template(rf, ctx) { if (rf & 1) {
1549
+ const _r1 = i0.ɵɵgetCurrentView();
1550
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div")(4, "h1");
1551
+ i0.ɵɵelement(5, "i", 4);
518
1552
  i0.ɵɵtext(6, " Component Studio");
519
1553
  i0.ɵɵelementEnd();
520
- i0.ɵɵelementStart(7, "p", 4);
521
- i0.ɵɵtext(8, "Testing components without custom properties");
1554
+ i0.ɵɵelementStart(7, "p", 5);
1555
+ i0.ɵɵtext(8, "Testing components without required custom properties");
522
1556
  i0.ɵɵelementEnd()();
523
- i0.ɵɵelementStart(9, "button", 5);
524
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_9_listener() { return ctx.refreshData(); });
525
- i0.ɵɵelement(10, "span", 6);
526
- i0.ɵɵtext(11, " Refresh ");
1557
+ i0.ɵɵelementStart(9, "div", 6);
1558
+ i0.ɵɵtemplate(10, ComponentStudioDashboardComponent_Conditional_10_Template, 3, 2, "button", 7);
1559
+ i0.ɵɵelementStart(11, "div", 8)(12, "button", 9);
1560
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleImportDropdown()); });
1561
+ i0.ɵɵelement(13, "span", 10);
1562
+ i0.ɵɵtext(14, " Import ");
1563
+ i0.ɵɵelement(15, "span", 11);
1564
+ i0.ɵɵelementEnd();
1565
+ i0.ɵɵtemplate(16, ComponentStudioDashboardComponent_Conditional_16_Template, 7, 0, "div", 12);
1566
+ i0.ɵɵelementEnd();
1567
+ i0.ɵɵelementStart(17, "button", 13);
1568
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.refreshData()); });
1569
+ i0.ɵɵelement(18, "span", 14);
1570
+ i0.ɵɵtext(19, " Refresh ");
1571
+ i0.ɵɵelementEnd()();
1572
+ i0.ɵɵelementStart(20, "input", 15, 0);
1573
+ i0.ɵɵlistener("change", function ComponentStudioDashboardComponent_Template_input_change_20_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.handleFileSelect($event)); });
1574
+ i0.ɵɵelementEnd()()();
1575
+ i0.ɵɵelementStart(22, "kendo-splitter", 16)(23, "kendo-splitter-pane", 17)(24, "div", 18)(25, "div", 19)(26, "div", 20)(27, "h3");
1576
+ i0.ɵɵtext(28, "Components");
1577
+ i0.ɵɵelementEnd();
1578
+ i0.ɵɵelementStart(29, "div", 21)(30, "button", 22);
1579
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleShowOnlyFavorites()); });
1580
+ i0.ɵɵtemplate(31, ComponentStudioDashboardComponent_Conditional_31_Template, 2, 0)(32, ComponentStudioDashboardComponent_Conditional_32_Template, 2, 0);
1581
+ i0.ɵɵelementEnd();
1582
+ i0.ɵɵelementStart(33, "span", 23);
1583
+ i0.ɵɵtext(34);
527
1584
  i0.ɵɵelementEnd()()();
528
- i0.ɵɵelementStart(12, "kendo-splitter", 7)(13, "kendo-splitter-pane", 8)(14, "div", 9)(15, "div", 10)(16, "h3");
529
- i0.ɵɵtext(17, "Components");
1585
+ i0.ɵɵelementStart(35, "div", 24);
1586
+ i0.ɵɵtemplate(36, ComponentStudioDashboardComponent_Conditional_36_Template, 5, 2, "div", 25);
530
1587
  i0.ɵɵelementEnd();
531
- i0.ɵɵelementStart(18, "div", 11)(19, "kendo-textbox", 12);
532
- i0.ɵɵlistener("valueChange", function ComponentStudioDashboardComponent_Template_kendo_textbox_valueChange_19_listener($event) { return ctx.onSearchChange($event); });
533
- i0.ɵɵtemplate(20, ComponentStudioDashboardComponent_ng_template_20_Template, 1, 0, "ng-template", 13);
1588
+ i0.ɵɵelementStart(37, "div", 26)(38, "kendo-textbox", 27);
1589
+ i0.ɵɵlistener("valueChange", function ComponentStudioDashboardComponent_Template_kendo_textbox_valueChange_38_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearchChange($event)); });
1590
+ i0.ɵɵtemplate(39, ComponentStudioDashboardComponent_ng_template_39_Template, 1, 0, "ng-template", 28);
534
1591
  i0.ɵɵelementEnd()()();
535
- i0.ɵɵelementStart(21, "div", 14);
536
- i0.ɵɵtemplate(22, ComponentStudioDashboardComponent_Conditional_22_Template, 3, 0, "div", 15)(23, ComponentStudioDashboardComponent_Conditional_23_Template, 6, 0, "div", 16)(24, ComponentStudioDashboardComponent_Conditional_24_Template, 2, 0);
1592
+ i0.ɵɵelementStart(40, "div", 29);
1593
+ i0.ɵɵtemplate(41, ComponentStudioDashboardComponent_Conditional_41_Template, 3, 0, "div", 30)(42, ComponentStudioDashboardComponent_Conditional_42_Template, 6, 0, "div", 31)(43, ComponentStudioDashboardComponent_Conditional_43_Template, 2, 0);
537
1594
  i0.ɵɵelementEnd()()();
538
- i0.ɵɵelementStart(25, "kendo-splitter-pane", 17)(26, "div", 18);
539
- i0.ɵɵtemplate(27, ComponentStudioDashboardComponent_Conditional_27_Template, 2, 1)(28, ComponentStudioDashboardComponent_Conditional_28_Template, 6, 0, "div", 19);
1595
+ i0.ɵɵelementStart(44, "kendo-splitter-pane", 32)(45, "div", 33);
1596
+ i0.ɵɵtemplate(46, ComponentStudioDashboardComponent_Conditional_46_Template, 13, 8)(47, ComponentStudioDashboardComponent_Conditional_47_Template, 6, 0, "div", 34);
540
1597
  i0.ɵɵelementEnd()()()();
541
1598
  } if (rf & 2) {
542
- i0.ɵɵadvance(9);
543
- i0.ɵɵproperty("disabled", ctx.isLoading);
1599
+ i0.ɵɵadvance(10);
1600
+ i0.ɵɵconditional(ctx.selectedComponent && ctx.isRunning ? 10 : -1);
1601
+ i0.ɵɵadvance();
1602
+ i0.ɵɵclassProp("open", ctx.importDropdownOpen);
1603
+ i0.ɵɵadvance();
1604
+ i0.ɵɵproperty("themeColor", "info");
544
1605
  i0.ɵɵadvance(4);
545
- i0.ɵɵproperty("min", "350px")("max", "600px")("size", "400px");
1606
+ i0.ɵɵconditional(ctx.importDropdownOpen ? 16 : -1);
1607
+ i0.ɵɵadvance();
1608
+ i0.ɵɵproperty("disabled", ctx.isLoading);
546
1609
  i0.ɵɵadvance(6);
1610
+ i0.ɵɵproperty("min", "350px")("max", "650px")("size", "400px");
1611
+ i0.ɵɵadvance(7);
1612
+ i0.ɵɵclassProp("active", ctx.showOnlyFavorites);
1613
+ i0.ɵɵadvance();
1614
+ i0.ɵɵconditional(ctx.showOnlyFavorites ? 31 : 32);
1615
+ i0.ɵɵadvance(3);
1616
+ i0.ɵɵtextInterpolate2("", ctx.filteredComponents.length, " of ", ctx.allComponents.length, "");
1617
+ i0.ɵɵadvance(2);
1618
+ i0.ɵɵconditional(ctx.availableCategories.length > 0 ? 36 : -1);
1619
+ i0.ɵɵadvance(2);
547
1620
  i0.ɵɵproperty("value", ctx.searchQuery)("clearButton", true);
548
1621
  i0.ɵɵadvance(3);
549
- i0.ɵɵconditional(ctx.isLoading ? 22 : ctx.filteredComponents.length === 0 ? 23 : 24);
1622
+ i0.ɵɵconditional(ctx.isLoading ? 41 : ctx.filteredComponents.length === 0 ? 42 : 43);
550
1623
  i0.ɵɵadvance(3);
551
1624
  i0.ɵɵproperty("min", "400px");
552
1625
  i0.ɵɵadvance(2);
553
- i0.ɵɵconditional(ctx.isRunning && ctx.selectedComponent && ctx.componentSpec ? 27 : 28);
554
- } }, dependencies: [i1.NgClass, i2.TextBoxComponent, i2.TextBoxPrefixTemplateDirective, i3.SplitterComponent, i3.SplitterPaneComponent, i4.ButtonComponent, i5.MJReactComponent, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n overflow: hidden;\n\n .dashboard-header {\n background: white;\n border-bottom: 1px solid #dee2e6;\n padding: 16px 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n \n .header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n \n h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 12px;\n \n i {\n color: #6366f1;\n }\n }\n \n .header-subtitle {\n margin: 4px 0 0 0;\n font-size: 13px;\n color: #6c757d;\n font-weight: normal;\n }\n }\n }\n\n kendo-splitter {\n flex: 1;\n background: white;\n display: flex;\n height: 100%;\n min-height: 0;\n }\n\n .components-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f8f9fa;\n \n .panel-header {\n padding: 20px;\n background: white;\n border-bottom: 1px solid #dee2e6;\n \n h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #212529;\n }\n \n .search-box {\n kendo-textbox {\n width: 100%;\n }\n }\n }\n \n .components-list {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n \n .loading-message,\n .empty-message {\n padding: 48px 24px;\n text-align: center;\n color: #6c757d;\n font-size: 14px;\n \n i {\n margin-right: 8px;\n }\n }\n \n .component-card {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 8px;\n margin-bottom: 12px;\n transition: all 0.2s ease;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n &.expanded {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n border-color: #6366f1;\n }\n \n &.running {\n border-color: #10b981;\n box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);\n background: linear-gradient(to right, rgba(16, 185, 129, 0.03) 0%, white 100%);\n \n .card-header {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 4px;\n background: #10b981;\n }\n }\n }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\n position: relative;\n \n &:hover {\n background: #f8f9fa;\n }\n \n .card-icon {\n font-size: 24px;\n margin-right: 16px;\n width: 32px;\n text-align: center;\n flex-shrink: 0;\n }\n \n .card-info {\n flex: 1;\n min-width: 0;\n \n .card-name {\n font-size: 15px;\n font-weight: 600;\n color: #212529;\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n \n .card-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #6c757d;\n \n .card-type {\n font-weight: 500;\n }\n \n .card-version {\n color: #868e96;\n }\n \n .status-badge {\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n \n &.published {\n background: #d1fae5;\n color: #065f46;\n }\n \n &.draft {\n background: #fef3c7;\n color: #92400e;\n }\n }\n }\n }\n \n .card-chevron {\n color: #6c757d;\n font-size: 12px;\n margin-left: 12px;\n transition: transform 0.2s ease;\n }\n }\n \n .card-details {\n padding: 0 16px 16px 16px;\n border-top: 1px solid #e9ecef;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease;\n \n .detail-section {\n margin-top: 16px;\n \n label {\n display: block;\n font-size: 11px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n \n p {\n margin: 0;\n font-size: 13px;\n color: #495057;\n line-height: 1.5;\n }\n \n .info-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n \n .info-item {\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n \n .info-label {\n font-weight: 500;\n color: #6c757d;\n min-width: 50px;\n }\n \n .info-value {\n color: #212529;\n }\n }\n }\n }\n \n .card-actions {\n margin-top: 16px;\n display: flex;\n gap: 8px;\n \n button {\n flex: 1;\n }\n }\n }\n }\n }\n }\n\n .component-display {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n \n .empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n color: #868e96;\n padding: 48px;\n text-align: center;\n \n i {\n color: #dee2e6;\n margin-bottom: 24px;\n }\n \n h2 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 600;\n color: #495057;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n }\n }\n \n .error-display {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: #f8f9fa;\n \n .error-container {\n width: 100%;\n max-width: 600px;\n background: white;\n border: 2px solid #dc3545;\n border-radius: 8px;\n padding: 24px;\n box-shadow: 0 4px 12px rgba(220, 53, 69, 0.15);\n \n .error-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n color: #dc3545;\n position: relative;\n \n i {\n font-size: 24px;\n }\n \n h3 {\n margin: 0;\n font-size: 20px;\n flex: 1;\n }\n \n .copy-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 10px;\n cursor: pointer;\n color: #6c757d;\n transition: all 0.2s;\n \n &:hover {\n background: #e9ecef;\n color: #495057;\n }\n \n i {\n font-size: 14px;\n }\n }\n }\n \n .error-intro {\n color: #495057;\n margin-bottom: 20px;\n font-size: 14px;\n }\n \n .error-details {\n background: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 13px;\n \n .technical-details {\n margin-top: 12px;\n \n summary {\n cursor: pointer;\n color: #0066cc;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \n &:hover {\n text-decoration: underline;\n }\n }\n \n pre {\n margin-top: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 11px;\n color: #495057;\n max-height: 200px;\n overflow-y: auto;\n }\n }\n }\n \n .error-help {\n background: #e7f3ff;\n border: 1px solid #b3d9ff;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-size: 13px;\n \n strong {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n color: #0066cc;\n }\n \n ol {\n margin: 0;\n padding-left: 20px;\n \n li {\n margin-bottom: 4px;\n color: #495057;\n }\n }\n }\n \n .error-actions {\n display: flex;\n gap: 12px;\n \n button {\n min-width: 100px;\n }\n }\n }\n }\n \n mj-react-component {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}"] });
1626
+ i0.ɵɵconditional(ctx.selectedComponent ? 46 : 47);
1627
+ } }, dependencies: [i2.NgClass, i3.NgControlStatus, i3.NgModel, i4.TextBoxComponent, i4.TextBoxPrefixTemplateDirective, i5.PanelBarComponent, i5.PanelBarItemComponent, i5.PanelBarContentDirective, i5.SplitterComponent, i5.SplitterPaneComponent, i5.TabStripComponent, i5.TabStripTabComponent, i5.TabContentDirective, i6.CodeEditorComponent, i7.ButtonComponent, i8.MJReactComponent, i2.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100vh;\n background: #f8f9fa;\n overflow: hidden;\n position: relative;\n\n .dashboard-header {\n background: white;\n border-bottom: 1px solid #dee2e6;\n padding: 16px 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n \n .header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n \n .header-buttons {\n display: flex;\n gap: 8px;\n \n .import-dropdown {\n position: relative;\n \n .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n min-width: 180px;\n \n .dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n text-align: left;\n cursor: pointer;\n font-size: 14px;\n color: #212529;\n transition: background-color 0.2s;\n \n &:hover {\n background-color: #f8f9fa;\n }\n \n &:not(:last-child) {\n border-bottom: 1px solid #e9ecef;\n }\n \n i {\n width: 16px;\n text-align: center;\n color: #6366f1;\n }\n }\n }\n }\n }\n \n h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 12px;\n \n i {\n color: #6366f1;\n }\n }\n \n .header-subtitle {\n margin: 4px 0 0 0;\n font-size: 13px;\n color: #6c757d;\n font-weight: normal;\n }\n }\n }\n\n kendo-splitter {\n flex: 1;\n background: white;\n display: flex;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n \n ::ng-deep .k-pane {\n overflow: hidden;\n height: 100%;\n }\n }\n\n .components-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f8f9fa;\n \n .panel-header {\n padding: 20px;\n background: white;\n border-bottom: 1px solid #dee2e6;\n \n .panel-header-top {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n \n h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #212529;\n }\n \n .header-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n \n .favorites-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #dee2e6;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n \n &:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n }\n \n &.active {\n background: #fff3cd;\n border-color: #ffc107;\n color: #856404;\n \n i {\n color: #ffc107;\n }\n }\n \n i {\n font-size: 14px;\n }\n }\n \n .component-count {\n font-size: 13px;\n color: #6c757d;\n background: #f8f9fa;\n padding: 4px 10px;\n border-radius: 12px;\n font-weight: 500;\n }\n }\n }\n \n .category-filters {\n margin-bottom: 16px;\n \n .filter-pills {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n \n .category-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 2px solid #e9ecef;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s ease;\n position: relative;\n overflow: hidden;\n \n &:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n &.active {\n border-color: var(--pill-color);\n background: var(--pill-color);\n color: white;\n \n .pill-count {\n background: rgba(255, 255, 255, 0.3);\n color: white;\n }\n }\n \n .pill-name {\n font-weight: 500;\n }\n \n .pill-count {\n background: #f1f3f5;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n min-width: 20px;\n text-align: center;\n }\n }\n \n .more-button,\n .clear-filters-button {\n padding: 6px 12px;\n border: 1px solid #dee2e6;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n \n &:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n }\n \n i {\n font-size: 11px;\n margin-right: 4px;\n }\n }\n \n .clear-filters-button {\n background: #fee2e2;\n border-color: #fca5a5;\n color: #dc2626;\n \n &:hover {\n background: #fca5a5;\n color: white;\n }\n }\n }\n }\n \n .search-box {\n kendo-textbox {\n width: 100%;\n }\n }\n }\n \n .components-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 16px;\n \n .loading-message,\n .empty-message {\n padding: 48px 24px;\n text-align: center;\n color: #6c757d;\n font-size: 14px;\n \n i {\n margin-right: 8px;\n }\n }\n \n .component-card {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 8px;\n margin-bottom: 12px;\n transition: all 0.2s ease;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n &.expanded {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n border-color: #6366f1;\n }\n \n &.running {\n border-color: #10b981;\n box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);\n background: linear-gradient(to right, rgba(16, 185, 129, 0.03) 0%, white 100%);\n \n .card-header {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 4px;\n background: #10b981;\n }\n }\n }\n \n &.file-loaded {\n background: linear-gradient(135deg, #f0f8ff 0%, white 100%);\n border-style: dashed;\n border-color: #3b82f6;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);\n }\n \n &.expanded {\n border-style: solid;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n }\n }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\n position: relative;\n \n &:hover {\n background: #f8f9fa;\n }\n \n .card-icon {\n font-size: 24px;\n margin-right: 16px;\n width: 32px;\n text-align: center;\n flex-shrink: 0;\n }\n \n .favorite-btn {\n position: absolute;\n top: 12px;\n right: 48px; // Leave room for chevron\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 50%;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n \n &:hover {\n background: #f8f9fa;\n transform: scale(1.1);\n }\n \n &.is-favorite {\n color: #ffc107;\n border-color: #ffc107;\n background: #fff3cd;\n \n &:hover {\n background: #ffe69c;\n }\n }\n \n i {\n font-size: 14px;\n }\n }\n \n .card-info {\n flex: 1;\n min-width: 0;\n \n .card-name {\n font-size: 15px;\n font-weight: 600;\n color: #212529;\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 8px;\n \n .file-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n background: #e0f2fe;\n color: #0369a1;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n flex-shrink: 0;\n \n i {\n font-size: 10px;\n }\n }\n }\n \n .card-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #6c757d;\n \n .card-type {\n font-weight: 500;\n }\n \n .card-version {\n color: #868e96;\n }\n \n .status-badge {\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n \n &.published {\n background: #d1fae5;\n color: #065f46;\n }\n \n &.draft {\n background: #fef3c7;\n color: #92400e;\n }\n \n &.file {\n background: #e0f2fe;\n color: #0369a1;\n }\n \n &.text {\n background: #f3e8ff;\n color: #6b21a8;\n }\n }\n }\n \n .card-namespace {\n margin-top: 8px;\n \n .namespace-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n color: white;\n \n i {\n font-size: 11px;\n opacity: 0.9;\n }\n }\n }\n }\n \n .card-chevron {\n color: #6c757d;\n font-size: 12px;\n margin-left: 12px;\n transition: transform 0.2s ease;\n }\n }\n \n .card-details {\n padding: 0 16px 16px 16px;\n border-top: 1px solid #e9ecef;\n animation: slideDown 0.2s ease;\n \n .detail-section {\n margin-top: 16px;\n \n label {\n display: block;\n font-size: 11px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n \n p {\n margin: 0;\n font-size: 13px;\n color: #495057;\n line-height: 1.5;\n }\n \n .info-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n \n .info-item {\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n \n .info-label {\n font-weight: 500;\n color: #6c757d;\n min-width: 50px;\n }\n \n .info-value {\n color: #212529;\n }\n }\n }\n }\n \n .card-actions {\n margin-top: 16px;\n display: flex;\n gap: 8px;\n \n button {\n flex: 1;\n }\n }\n }\n }\n }\n }\n\n .component-display {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n overflow: hidden;\n \n .empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n color: #868e96;\n padding: 48px;\n text-align: center;\n \n i {\n color: #dee2e6;\n margin-bottom: 24px;\n }\n \n h2 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 600;\n color: #495057;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n }\n }\n \n .error-display {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: #f8f9fa;\n \n .error-container {\n width: 100%;\n max-width: 600px;\n background: white;\n border: 2px solid #dc3545;\n border-radius: 8px;\n padding: 24px;\n box-shadow: 0 4px 12px rgba(220, 53, 69, 0.15);\n \n .error-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n color: #dc3545;\n position: relative;\n \n i {\n font-size: 24px;\n }\n \n h3 {\n margin: 0;\n font-size: 20px;\n flex: 1;\n }\n \n .copy-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 10px;\n cursor: pointer;\n color: #6c757d;\n transition: all 0.2s;\n \n &:hover {\n background: #e9ecef;\n color: #495057;\n }\n \n i {\n font-size: 14px;\n }\n }\n }\n \n .error-intro {\n color: #495057;\n margin-bottom: 20px;\n font-size: 14px;\n }\n \n .error-details {\n background: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 13px;\n \n .technical-details {\n margin-top: 12px;\n \n summary {\n cursor: pointer;\n color: #0066cc;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \n &:hover {\n text-decoration: underline;\n }\n }\n \n pre {\n margin-top: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 11px;\n color: #495057;\n max-height: 200px;\n overflow-y: auto;\n }\n }\n }\n \n .error-help {\n background: #e7f3ff;\n border: 1px solid #b3d9ff;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-size: 13px;\n \n strong {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n color: #0066cc;\n }\n \n ol {\n margin: 0;\n padding-left: 20px;\n \n li {\n margin-bottom: 4px;\n color: #495057;\n }\n }\n }\n \n .error-actions {\n display: flex;\n gap: 12px;\n \n button {\n min-width: 100px;\n }\n }\n }\n }\n \n mj-react-component {\n flex: 1;\n width: 100%;\n height: 100%;\n display: block;\n overflow-y: auto;\n overflow-x: hidden;\n }\n \n // Component and editor splitter\n .component-editor-splitter {\n height: 100%;\n overflow: hidden;\n \n ::ng-deep .k-splitter-bar {\n background: #6366f1; // Same blue as Import button\n width: 6px; // Make it slightly wider for visibility\n \n &:hover {\n background: #4f52d9; // Darker blue on hover\n }\n \n .k-resize-handle {\n background-color: rgba(255, 255, 255, 0.3);\n }\n }\n \n ::ng-deep .k-pane {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n }\n \n // Component runtime area\n .component-runtime {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n overflow-y: auto;\n overflow-x: hidden;\n \n .run-empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n text-align: center;\n \n i {\n color: #10b981;\n margin-bottom: 24px;\n }\n \n h3 {\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #212529;\n }\n \n p {\n margin: 0 0 24px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n }\n }\n }\n \n // Editor tabs on the right\n .editor-tabs {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n \n ::ng-deep .k-tabstrip-items-wrapper {\n background: #f8f9fa;\n border-bottom: 2px solid #dee2e6;\n flex-shrink: 0;\n }\n \n ::ng-deep .k-tabstrip-content {\n flex: 1;\n padding: 0;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n \n ::ng-deep .k-item.k-tabstrip-item {\n font-weight: 500;\n \n &.k-active {\n background: white;\n border-bottom-color: white;\n }\n }\n }\n \n .tab-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n \n &.spec-tab, &.code-tab {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n \n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\n flex-shrink: 0;\n min-width: 0; // Fix width issue\n \n h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 1; // Allow title to shrink\n min-width: 0; // Prevent overflow\n \n i {\n color: #6366f1;\n flex-shrink: 0; // Keep icon from shrinking\n }\n }\n \n .editor-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0; // Prevent buttons from shrinking\n \n button {\n min-width: auto;\n padding: 4px 12px;\n font-size: 13px;\n white-space: nowrap; // Prevent button text wrapping\n }\n }\n }\n \n .editor-wrapper {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n }\n \n ::ng-deep .monaco-editor {\n border: 1px solid #dee2e6;\n }\n }\n \n .code-sections {\n height: 100%;\n \n ::ng-deep .k-panelbar-item-header {\n background: #f8f9fa;\n font-weight: 500;\n font-size: 14px;\n }\n \n ::ng-deep .k-panelbar-content {\n padding: 0;\n }\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Removed[_ngcontent-%COMP%] tree[_ngcontent-%COMP%] view[_ngcontent-%COMP%] styles[_ngcontent-%COMP%] -[_ngcontent-%COMP%] using[_ngcontent-%COMP%] modern[_ngcontent-%COMP%] category[_ngcontent-%COMP%] filters[_ngcontent-%COMP%] instead\n\n@keyframes[_ngcontent-%COMP%] slideDown[_ngcontent-%COMP%] {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}"] });
555
1628
  };
556
1629
  ComponentStudioDashboardComponent = __decorate([
557
1630
  RegisterClass(BaseDashboard, 'ComponentStudioDashboard')
@@ -559,9 +1632,15 @@ ComponentStudioDashboardComponent = __decorate([
559
1632
  export { ComponentStudioDashboardComponent };
560
1633
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentStudioDashboardComponent, [{
561
1634
  type: Component,
562
- args: [{ selector: 'mj-component-studio-dashboard', template: "<div class=\"component-studio\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-content\">\n <div>\n <h1><i class=\"fa-solid fa-puzzle-piece\"></i> Component Studio</h1>\n <p class=\"header-subtitle\">Testing components without custom properties</p>\n </div>\n <button kendoButton (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <span class=\"fa-solid fa-sync\"></span> Refresh\n </button>\n </div>\n </div>\n\n <!-- Main Content with Splitter -->\n <kendo-splitter orientation=\"horizontal\" style=\"flex: 1; height: auto;\">\n <!-- Left Panel - Component List -->\n <kendo-splitter-pane [min]=\"'350px'\" [max]=\"'600px'\" [size]=\"'400px'\">\n <div class=\"components-panel\">\n <div class=\"panel-header\">\n <h3>Components</h3>\n <div class=\"search-box\">\n <kendo-textbox \n [value]=\"searchQuery\"\n (valueChange)=\"onSearchChange($event)\"\n placeholder=\"Search components...\"\n [clearButton]=\"true\">\n <ng-template kendoTextBoxPrefixTemplate>\n <i class=\"fa-solid fa-search\"></i>\n </ng-template>\n </kendo-textbox>\n </div>\n </div>\n \n <div class=\"components-list\">\n @if (isLoading) {\n <div class=\"loading-message\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading components...\n </div>\n } @else if (filteredComponents.length === 0) {\n <div class=\"empty-message\">\n <i class=\"fa-solid fa-info-circle\"></i> No components found without custom properties.\n <br>\n <small>Only components that don't require custom props can be tested here.</small>\n </div>\n } @else {\n @for (component of filteredComponents; track component.ID) {\n <div class=\"component-card\" \n [class.expanded]=\"expandedComponent?.ID === component.ID\"\n [class.running]=\"selectedComponent?.ID === component.ID && isRunning\">\n \n <!-- Card Header - Always visible -->\n <div class=\"card-header\" (click)=\"toggleComponentExpansion(component)\">\n <div class=\"card-icon\" [style.color]=\"getComponentTypeColor(component.Type)\">\n <i class=\"fa-solid\" [ngClass]=\"getComponentTypeIcon(component.Type)\"></i>\n </div>\n <div class=\"card-info\">\n <div class=\"card-name\">{{ component.Name }}</div>\n <div class=\"card-meta\">\n <span class=\"card-type\">{{ component.Type || 'Component' }}</span>\n <span class=\"card-version\">v{{ component.Version || '1.0.0' }}</span>\n @if (component.Status === 'Published') {\n <span class=\"status-badge published\">Published</span>\n } @else {\n <span class=\"status-badge draft\">Draft</span>\n }\n </div>\n </div>\n <div class=\"card-chevron\">\n @if (expandedComponent?.ID === component.ID) {\n <i class=\"fa-solid fa-chevron-up\"></i>\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i>\n }\n </div>\n </div>\n \n <!-- Card Details - Only visible when expanded -->\n @if (expandedComponent?.ID === component.ID) {\n <div class=\"card-details\">\n @if (component.Description) {\n <div class=\"detail-section\">\n <label>Description</label>\n <p>{{ component.Description }}</p>\n </div>\n }\n \n <div class=\"detail-section\">\n <label>Component Info</label>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <span class=\"info-label\">Type:</span>\n <span class=\"info-value\">{{ component.Type || 'Unknown' }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Version:</span>\n <span class=\"info-value\">{{ component.Version || '1.0.0' }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Status:</span>\n <span class=\"info-value\">{{ component.Status || 'Draft' }}</span>\n </div>\n @if (component.__mj_UpdatedAt) {\n <div class=\"info-item\">\n <span class=\"info-label\">Updated:</span>\n <span class=\"info-value\">{{ component.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n \n <div class=\"card-actions\">\n @if (selectedComponent?.ID === component.ID && isRunning) {\n <button kendoButton \n [themeColor]=\"'error'\"\n (click)=\"stopComponent(); $event.stopPropagation()\">\n <span class=\"fa-solid fa-stop\"></span> Stop Component\n </button>\n } @else if (isRunning && selectedComponent?.ID !== component.ID) {\n <button kendoButton \n [themeColor]=\"'base'\"\n title=\"Stop current component and run this one\"\n (click)=\"runComponent(component); $event.stopPropagation()\">\n <span class=\"fa-solid fa-play\"></span> Switch to This Component\n </button>\n } @else {\n <button kendoButton \n [themeColor]=\"'primary'\"\n (click)=\"runComponent(component); $event.stopPropagation()\">\n <span class=\"fa-solid fa-play\"></span> Run Component\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n </kendo-splitter-pane>\n\n <!-- Right Panel - Component Display -->\n <kendo-splitter-pane [min]=\"'400px'\">\n <div class=\"component-display\">\n @if (isRunning && selectedComponent && componentSpec) {\n @if (currentError) {\n <!-- Error Display -->\n <div class=\"error-display\">\n <div class=\"error-container\">\n <div class=\"error-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>Component Error</h3>\n <button class=\"copy-button\" (click)=\"copyErrorToClipboard()\" title=\"Copy error details\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </div>\n \n <p class=\"error-intro\">\n The component could not be rendered due to the following error:\n </p>\n \n <div class=\"error-details\">\n <strong>Error Type:</strong> {{ currentError.type }}<br>\n <strong>Message:</strong> {{ currentError.message }}\n @if (currentError.technicalDetails) {\n <details class=\"technical-details\">\n <summary>Technical Details (click to expand)</summary>\n <pre>{{ formatTechnicalDetails(currentError.technicalDetails) }}</pre>\n </details>\n }\n </div>\n \n <div class=\"error-help\">\n <strong>What to do:</strong>\n <ol>\n <li>Check that the component code is valid JavaScript/React</li>\n <li>Ensure all required dependencies are available</li>\n <li>Review the technical details for specific error information</li>\n <li>Contact your system administrator if the issue persists</li>\n </ol>\n </div>\n \n <div class=\"error-actions\">\n <button kendoButton (click)=\"retryComponent()\">\n <span class=\"fa-solid fa-rotate\"></span> Retry\n </button>\n <button kendoButton (click)=\"stopComponent()\" [themeColor]=\"'error'\">\n <span class=\"fa-solid fa-stop\"></span> Stop\n </button>\n </div>\n </div>\n </div>\n } @else {\n <!-- React Component -->\n <mj-react-component \n [component]=\"componentSpec\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-react-component>\n }\n } @else {\n <!-- Empty State -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-rocket fa-3x\"></i>\n <h2>Ready to Test Components</h2>\n <p>Select a component from the list and click \"Run Component\" to see it in action</p>\n </div>\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n</div>", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n overflow: hidden;\n\n .dashboard-header {\n background: white;\n border-bottom: 1px solid #dee2e6;\n padding: 16px 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n \n .header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n \n h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 12px;\n \n i {\n color: #6366f1;\n }\n }\n \n .header-subtitle {\n margin: 4px 0 0 0;\n font-size: 13px;\n color: #6c757d;\n font-weight: normal;\n }\n }\n }\n\n kendo-splitter {\n flex: 1;\n background: white;\n display: flex;\n height: 100%;\n min-height: 0;\n }\n\n .components-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f8f9fa;\n \n .panel-header {\n padding: 20px;\n background: white;\n border-bottom: 1px solid #dee2e6;\n \n h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #212529;\n }\n \n .search-box {\n kendo-textbox {\n width: 100%;\n }\n }\n }\n \n .components-list {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n \n .loading-message,\n .empty-message {\n padding: 48px 24px;\n text-align: center;\n color: #6c757d;\n font-size: 14px;\n \n i {\n margin-right: 8px;\n }\n }\n \n .component-card {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 8px;\n margin-bottom: 12px;\n transition: all 0.2s ease;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n &.expanded {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n border-color: #6366f1;\n }\n \n &.running {\n border-color: #10b981;\n box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);\n background: linear-gradient(to right, rgba(16, 185, 129, 0.03) 0%, white 100%);\n \n .card-header {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 4px;\n background: #10b981;\n }\n }\n }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\n position: relative;\n \n &:hover {\n background: #f8f9fa;\n }\n \n .card-icon {\n font-size: 24px;\n margin-right: 16px;\n width: 32px;\n text-align: center;\n flex-shrink: 0;\n }\n \n .card-info {\n flex: 1;\n min-width: 0;\n \n .card-name {\n font-size: 15px;\n font-weight: 600;\n color: #212529;\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n \n .card-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #6c757d;\n \n .card-type {\n font-weight: 500;\n }\n \n .card-version {\n color: #868e96;\n }\n \n .status-badge {\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n \n &.published {\n background: #d1fae5;\n color: #065f46;\n }\n \n &.draft {\n background: #fef3c7;\n color: #92400e;\n }\n }\n }\n }\n \n .card-chevron {\n color: #6c757d;\n font-size: 12px;\n margin-left: 12px;\n transition: transform 0.2s ease;\n }\n }\n \n .card-details {\n padding: 0 16px 16px 16px;\n border-top: 1px solid #e9ecef;\n animation: slideDown 0.2s ease;\n \n .detail-section {\n margin-top: 16px;\n \n label {\n display: block;\n font-size: 11px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n \n p {\n margin: 0;\n font-size: 13px;\n color: #495057;\n line-height: 1.5;\n }\n \n .info-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n \n .info-item {\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n \n .info-label {\n font-weight: 500;\n color: #6c757d;\n min-width: 50px;\n }\n \n .info-value {\n color: #212529;\n }\n }\n }\n }\n \n .card-actions {\n margin-top: 16px;\n display: flex;\n gap: 8px;\n \n button {\n flex: 1;\n }\n }\n }\n }\n }\n }\n\n .component-display {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n \n .empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n color: #868e96;\n padding: 48px;\n text-align: center;\n \n i {\n color: #dee2e6;\n margin-bottom: 24px;\n }\n \n h2 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 600;\n color: #495057;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n }\n }\n \n .error-display {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: #f8f9fa;\n \n .error-container {\n width: 100%;\n max-width: 600px;\n background: white;\n border: 2px solid #dc3545;\n border-radius: 8px;\n padding: 24px;\n box-shadow: 0 4px 12px rgba(220, 53, 69, 0.15);\n \n .error-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n color: #dc3545;\n position: relative;\n \n i {\n font-size: 24px;\n }\n \n h3 {\n margin: 0;\n font-size: 20px;\n flex: 1;\n }\n \n .copy-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 10px;\n cursor: pointer;\n color: #6c757d;\n transition: all 0.2s;\n \n &:hover {\n background: #e9ecef;\n color: #495057;\n }\n \n i {\n font-size: 14px;\n }\n }\n }\n \n .error-intro {\n color: #495057;\n margin-bottom: 20px;\n font-size: 14px;\n }\n \n .error-details {\n background: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 13px;\n \n .technical-details {\n margin-top: 12px;\n \n summary {\n cursor: pointer;\n color: #0066cc;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \n &:hover {\n text-decoration: underline;\n }\n }\n \n pre {\n margin-top: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 11px;\n color: #495057;\n max-height: 200px;\n overflow-y: auto;\n }\n }\n }\n \n .error-help {\n background: #e7f3ff;\n border: 1px solid #b3d9ff;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-size: 13px;\n \n strong {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n color: #0066cc;\n }\n \n ol {\n margin: 0;\n padding-left: 20px;\n \n li {\n margin-bottom: 4px;\n color: #495057;\n }\n }\n }\n \n .error-actions {\n display: flex;\n gap: 12px;\n \n button {\n min-width: 100px;\n }\n }\n }\n }\n \n mj-react-component {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n }\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}"] }]
563
- }], () => [{ type: i0.ChangeDetectorRef }], null); })();
564
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentStudioDashboardComponent, { className: "ComponentStudioDashboardComponent", filePath: "src/ComponentStudio/component-studio-dashboard.component.ts", lineNumber: 18 }); })();
1635
+ args: [{ selector: 'mj-component-studio-dashboard', template: "<div class=\"component-studio\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-content\">\n <div>\n <h1><i class=\"fa-solid fa-puzzle-piece\"></i> Component Studio</h1>\n <p class=\"header-subtitle\">Testing components without required custom properties</p>\n </div>\n <div class=\"header-buttons\">\n @if (selectedComponent && isRunning) {\n <button kendoButton (click)=\"toggleDetailsPane()\" [themeColor]=\"'base'\">\n @if (isDetailsPaneCollapsed) {\n <span class=\"fa-solid fa-eye\"></span> Show Details\n } @else {\n <span class=\"fa-solid fa-eye-slash\"></span> Hide Details\n }\n </button>\n }\n <div class=\"import-dropdown\" [class.open]=\"importDropdownOpen\">\n <button kendoButton (click)=\"toggleImportDropdown()\" [themeColor]=\"'info'\">\n <span class=\"fa-solid fa-file-import\"></span> Import\n <span class=\"fa-solid fa-chevron-down\" style=\"margin-left: 5px; font-size: 10px;\"></span>\n </button>\n @if (importDropdownOpen) {\n <div class=\"dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"importFromFile()\">\n <i class=\"fa-solid fa-file\"></i> Import from File\n </button>\n <button class=\"dropdown-item\" (click)=\"importFromText()\">\n <i class=\"fa-solid fa-keyboard\"></i> Import from Text\n </button>\n </div>\n }\n </div>\n <button kendoButton (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <span class=\"fa-solid fa-sync\"></span> Refresh\n </button>\n </div>\n <!-- Hidden file input -->\n <input #fileInput type=\"file\" accept=\".json\" (change)=\"handleFileSelect($event)\" style=\"display: none;\" />\n </div>\n </div>\n\n <!-- Main Content with Splitter -->\n <kendo-splitter orientation=\"horizontal\">\n <!-- Left Panel - Component List -->\n <kendo-splitter-pane [min]=\"'350px'\" [max]=\"'650px'\" [size]=\"'400px'\">\n <div class=\"components-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header-top\">\n <h3>Components</h3>\n <div class=\"header-actions\">\n <button \n class=\"favorites-toggle\"\n [class.active]=\"showOnlyFavorites\"\n (click)=\"toggleShowOnlyFavorites()\"\n title=\"Show only favorites\">\n @if (showOnlyFavorites) {\n <i class=\"fa-solid fa-star\"></i> Favorites\n } @else {\n <i class=\"fa-regular fa-star\"></i> All\n }\n </button>\n <span class=\"component-count\">{{ filteredComponents.length }} of {{ allComponents.length }}</span>\n </div>\n </div>\n \n <!-- Modern Category Filter Pills -->\n <div class=\"category-filters\">\n @if (availableCategories.length > 0) {\n <div class=\"filter-pills\">\n @for (category of getVisibleCategories(); track category.name) {\n <button \n class=\"category-pill\"\n [class.active]=\"isCategorySelected(category.name)\"\n [style.--pill-color]=\"category.color\"\n (click)=\"toggleCategory(category.name)\">\n <span class=\"pill-name\">{{ category.name }}</span>\n <span class=\"pill-count\">{{ category.count }}</span>\n </button>\n }\n @if (availableCategories.length > 5) {\n <button \n class=\"more-button\"\n (click)=\"toggleShowAllCategories()\">\n @if (showAllCategories) {\n <i class=\"fa-solid fa-chevron-up\"></i> Less\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i> +{{ availableCategories.length - 5 }} more\n }\n </button>\n }\n @if (selectedCategories.size > 0) {\n <button \n class=\"clear-filters-button\"\n (click)=\"clearCategoryFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n </div>\n \n <div class=\"search-box\">\n <kendo-textbox \n [value]=\"searchQuery\"\n (valueChange)=\"onSearchChange($event)\"\n placeholder=\"Search components...\"\n [clearButton]=\"true\">\n <ng-template kendoTextBoxPrefixTemplate>\n <i class=\"fa-solid fa-search\"></i>\n </ng-template>\n </kendo-textbox>\n </div>\n </div>\n \n <div class=\"components-list\">\n @if (isLoading) {\n <div class=\"loading-message\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading components...\n </div>\n } @else if (filteredComponents.length === 0) {\n <div class=\"empty-message\">\n <i class=\"fa-solid fa-info-circle\"></i> No components found without required custom properties.\n <br>\n <small>Components with optional custom props can be tested, but not those with required props.</small>\n </div>\n } @else {\n <!-- Component Cards -->\n @for (component of filteredComponents; track getComponentId(component)) {\n <div class=\"component-card\" \n [class.expanded]=\"expandedComponent && getComponentId(expandedComponent) === getComponentId(component)\"\n [class.running]=\"selectedComponent && getComponentId(selectedComponent) === getComponentId(component) && isRunning\"\n [class.file-loaded]=\"isFileLoadedComponent(component)\">\n \n <!-- Card Header - Always visible -->\n <div class=\"card-header\" (click)=\"toggleComponentExpansion(component)\">\n <div class=\"card-icon\" [style.color]=\"getComponentTypeColor(getComponentType(component))\">\n <i class=\"fa-solid\" [ngClass]=\"getComponentTypeIcon(getComponentType(component))\"></i>\n </div>\n @if (!isFileLoadedComponent(component)) {\n <button \n class=\"favorite-btn\"\n [class.is-favorite]=\"isFavorite(component)\"\n (click)=\"toggleFavorite(component, $event)\"\n [title]=\"isFavorite(component) ? 'Remove from favorites' : 'Add to favorites'\">\n @if (isFavorite(component)) {\n <i class=\"fa-solid fa-star\"></i>\n } @else {\n <i class=\"fa-regular fa-star\"></i>\n }\n </button>\n }\n <div class=\"card-info\">\n <div class=\"card-name\">\n {{ getComponentName(component) }}\n @if (isFileLoadedComponent(component)) {\n <span class=\"file-badge\" [title]=\"getComponentStatus(component) === 'Text' ? 'Imported from text input' : 'Loaded from ' + getComponentFilename(component)\">\n @if (getComponentStatus(component) === 'Text') {\n <i class=\"fa-solid fa-keyboard\"></i> Text Import\n } @else {\n <i class=\"fa-solid fa-file\"></i> {{ getComponentFilename(component) }}\n }\n </span>\n }\n </div>\n <div class=\"card-meta\">\n <span class=\"card-type\">{{ getComponentType(component) || 'Component' }}</span>\n <span class=\"card-version\">v{{ getComponentVersion(component) }}</span>\n @if (isFileLoadedComponent(component)) {\n @if (getComponentStatus(component) === 'Text') {\n <span class=\"status-badge text\">Text</span>\n } @else {\n <span class=\"status-badge file\">File</span>\n }\n } @else if (getComponentStatus(component) === 'Published') {\n <span class=\"status-badge published\">Published</span>\n } @else {\n <span class=\"status-badge draft\">Draft</span>\n }\n </div>\n <!-- Namespace chip with color coding -->\n <div class=\"card-namespace\">\n <span class=\"namespace-chip\" \n [style.background-color]=\"getNamespaceColor(getComponentNamespace(component))\"\n [title]=\"getComponentNamespace(component) || 'Uncategorized'\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n {{ formatNamespace(getComponentNamespace(component)) }}\n </span>\n </div>\n </div>\n <div class=\"card-chevron\">\n @if (expandedComponent && getComponentId(expandedComponent) === getComponentId(component)) {\n <i class=\"fa-solid fa-chevron-up\"></i>\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i>\n }\n </div>\n </div>\n \n <!-- Card Details - Only visible when expanded -->\n @if (expandedComponent && getComponentId(expandedComponent) === getComponentId(component)) {\n <div class=\"card-details\">\n @if (getComponentDescription(component)) {\n <div class=\"detail-section\">\n <label>Description</label>\n <p>{{ getComponentDescription(component) }}</p>\n </div>\n }\n \n <div class=\"detail-section\">\n <label>Component Info</label>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <span class=\"info-label\">Type:</span>\n <span class=\"info-value\">{{ getComponentType(component) || 'Unknown' }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Version:</span>\n <span class=\"info-value\">{{ getComponentVersion(component) }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"info-label\">Status:</span>\n <span class=\"info-value\">{{ getComponentStatus(component) || 'Draft' }}</span>\n </div>\n @if (isFileLoadedComponent(component)) {\n <div class=\"info-item\">\n <span class=\"info-label\">Loaded:</span>\n <span class=\"info-value\">{{ getComponentLoadedAt(component) | date:'short' }}</span>\n </div>\n } @else if (!isFileLoadedComponent(component) && getComponentUpdatedAt(component)) {\n <div class=\"info-item\">\n <span class=\"info-label\">Updated:</span>\n <span class=\"info-value\">{{ getComponentUpdatedAt(component) | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n \n <div class=\"card-actions\">\n @if (selectedComponent && getComponentId(selectedComponent) === getComponentId(component) && isRunning) {\n <button kendoButton \n [themeColor]=\"'error'\"\n (click)=\"stopComponent(); $event.stopPropagation()\">\n <span class=\"fa-solid fa-stop\"></span> Stop Component\n </button>\n } @else if (isRunning && selectedComponent && getComponentId(selectedComponent) !== getComponentId(component)) {\n <button kendoButton \n [themeColor]=\"'base'\"\n title=\"Stop current component and run this one\"\n (click)=\"runComponent(component); $event.stopPropagation()\">\n <span class=\"fa-solid fa-play\"></span> Switch to This Component\n </button>\n } @else {\n <button kendoButton \n [themeColor]=\"'primary'\"\n (click)=\"runComponent(component); $event.stopPropagation()\">\n <span class=\"fa-solid fa-play\"></span> Run Component\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n </kendo-splitter-pane>\n\n <!-- Right Panel - Component Display with Editor Splitter -->\n <kendo-splitter-pane [min]=\"'400px'\">\n <div class=\"component-display\">\n @if (selectedComponent) {\n <kendo-splitter orientation=\"horizontal\">\n <kendo-splitter-pane [size]=\"isDetailsPaneCollapsed ? '100%' : '50%'\">\n <div class=\"component-runtime\">\n @if (isRunning && componentSpec) {\n @if (currentError) {\n <!-- Error Display -->\n <div class=\"error-display\">\n <div class=\"error-container\">\n <div class=\"error-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>Component Error</h3>\n <button class=\"copy-button\" (click)=\"copyErrorToClipboard()\" title=\"Copy error details\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n </div>\n \n <p class=\"error-intro\">\n The component could not be rendered due to the following error:\n </p>\n \n <div class=\"error-details\">\n <strong>Error Type:</strong> {{ currentError.type }}<br>\n <strong>Message:</strong> {{ currentError.message }}\n @if (currentError.technicalDetails) {\n <details class=\"technical-details\">\n <summary>Technical Details (click to expand)</summary>\n <pre>{{ formatTechnicalDetails(currentError.technicalDetails) }}</pre>\n </details>\n }\n </div>\n \n <div class=\"error-help\">\n <strong>What to do:</strong>\n <ol>\n <li>Check that the component code is valid JavaScript/React</li>\n <li>Ensure all required dependencies are available</li>\n <li>Review the technical details for specific error information</li>\n <li>Contact your system administrator if the issue persists</li>\n </ol>\n </div>\n \n <div class=\"error-actions\">\n <button kendoButton (click)=\"retryComponent()\">\n <span class=\"fa-solid fa-rotate\"></span> Retry\n </button>\n <button kendoButton (click)=\"stopComponent()\" [themeColor]=\"'error'\">\n <span class=\"fa-solid fa-stop\"></span> Stop\n </button>\n </div>\n </div>\n </div>\n } @else {\n <!-- React Component -->\n <mj-react-component \n [component]=\"componentSpec\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-react-component>\n }\n } @else {\n <!-- Component Not Running State -->\n <div class=\"run-empty-state\">\n <i class=\"fa-solid fa-play-circle fa-3x\"></i>\n <h3>Component: {{ getComponentName(selectedComponent) }}</h3>\n <p>{{ getComponentDescription(selectedComponent) || 'No description available' }}</p>\n <button kendoButton [themeColor]=\"'primary'\" [size]=\"'large'\" (click)=\"runComponent(selectedComponent)\">\n <span class=\"fa-solid fa-play\"></span> Run Component\n </button>\n </div>\n }\n </div>\n\n </kendo-splitter-pane>\n <kendo-splitter-pane [size]=\"isDetailsPaneCollapsed ? '0px' : '50%'\">\n <div>\n <kendo-tabstrip (tabSelect)=\"onTabSelect($event)\" class=\"editor-tabs\">\n <!-- Spec Tab -->\n <kendo-tabstrip-tab [title]=\"'Spec'\" [selected]=\"activeTab === 0\">\n <ng-template kendoTabContent>\n <div class=\"tab-content spec-tab\">\n <div class=\"editor-header\">\n <h4><i class=\"fa-solid fa-code\"></i> Component Specification (JSON)</h4>\n <div class=\"editor-actions\">\n @if (isEditingSpec) {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"applySpecChanges()\">\n <span class=\"fa-solid fa-check\"></span> Apply Changes\n </button>\n <button kendoButton (click)=\"initializeEditors()\">\n <span class=\"fa-solid fa-times\"></span> Cancel\n </button>\n }\n @if (isRunning) {\n <button kendoButton (click)=\"refreshComponent()\" [themeColor]=\"'info'\">\n <span class=\"fa-solid fa-sync\"></span> Refresh Component\n </button>\n }\n </div>\n </div>\n <div class=\"editor-wrapper\">\n <mj-code-editor\n [(ngModel)]=\"editableSpec\"\n (ngModelChange)=\"onSpecChange($event)\"\n [language]=\"'json'\"\n [readonly]=\"false\"\n style=\"height: 100%; width: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n \n <!-- Code Tab -->\n <kendo-tabstrip-tab [title]=\"'Code'\" [selected]=\"activeTab === 1\">\n <ng-template kendoTabContent>\n <div class=\"tab-content code-tab\">\n <div class=\"editor-header\">\n <h4><i class=\"fa-solid fa-file-code\"></i> Component Code (JavaScript/React)</h4>\n <div class=\"editor-actions\">\n @if (isEditingCode) {\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"applyCodeChanges()\">\n <span class=\"fa-solid fa-check\"></span> Apply Changes\n </button>\n <button kendoButton (click)=\"initializeEditors()\">\n <span class=\"fa-solid fa-times\"></span> Cancel\n </button>\n }\n @if (isRunning) {\n <button kendoButton (click)=\"refreshComponent()\" [themeColor]=\"'info'\">\n <span class=\"fa-solid fa-sync\"></span> Refresh Component\n </button>\n }\n </div>\n </div>\n \n <!-- Always use panel bar for consistency and to show all components -->\n <div class=\"editor-wrapper\">\n <kendo-panelbar class=\"code-sections\">\n @for (section of getComponentCodeSections(); track section.title; let i = $index) {\n <kendo-panelbar-item [title]=\"section.title\" [expanded]=\"section.expanded\">\n <ng-template kendoPanelBarContent>\n <mj-code-editor\n [ngModel]=\"section.code\"\n (ngModelChange)=\"onCodeSectionChange($event, i)\"\n [language]=\"'javascript'\"\n [readonly]=\"false\"\n style=\"height: 400px; width: 100%;\">\n </mj-code-editor>\n </ng-template>\n </kendo-panelbar-item>\n }\n </kendo-panelbar>\n </div>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n\n @if (!isDetailsPaneCollapsed) {\n \n }\n } @else {\n <!-- Empty State when no component selected -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-rocket fa-3x\"></i>\n <h2>Ready to Test Components</h2>\n <p>Select a component from the list to view its details and run it</p>\n </div>\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n</div>", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio {\n display: flex;\n flex-direction: column;\n height: 100vh;\n background: #f8f9fa;\n overflow: hidden;\n position: relative;\n\n .dashboard-header {\n background: white;\n border-bottom: 1px solid #dee2e6;\n padding: 16px 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n \n .header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n \n .header-buttons {\n display: flex;\n gap: 8px;\n \n .import-dropdown {\n position: relative;\n \n .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n min-width: 180px;\n \n .dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n text-align: left;\n cursor: pointer;\n font-size: 14px;\n color: #212529;\n transition: background-color 0.2s;\n \n &:hover {\n background-color: #f8f9fa;\n }\n \n &:not(:last-child) {\n border-bottom: 1px solid #e9ecef;\n }\n \n i {\n width: 16px;\n text-align: center;\n color: #6366f1;\n }\n }\n }\n }\n }\n \n h1 {\n margin: 0;\n font-size: 24px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 12px;\n \n i {\n color: #6366f1;\n }\n }\n \n .header-subtitle {\n margin: 4px 0 0 0;\n font-size: 13px;\n color: #6c757d;\n font-weight: normal;\n }\n }\n }\n\n kendo-splitter {\n flex: 1;\n background: white;\n display: flex;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n \n ::ng-deep .k-pane {\n overflow: hidden;\n height: 100%;\n }\n }\n\n .components-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f8f9fa;\n \n .panel-header {\n padding: 20px;\n background: white;\n border-bottom: 1px solid #dee2e6;\n \n .panel-header-top {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n \n h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #212529;\n }\n \n .header-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n \n .favorites-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #dee2e6;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 500;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n \n &:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n }\n \n &.active {\n background: #fff3cd;\n border-color: #ffc107;\n color: #856404;\n \n i {\n color: #ffc107;\n }\n }\n \n i {\n font-size: 14px;\n }\n }\n \n .component-count {\n font-size: 13px;\n color: #6c757d;\n background: #f8f9fa;\n padding: 4px 10px;\n border-radius: 12px;\n font-weight: 500;\n }\n }\n }\n \n .category-filters {\n margin-bottom: 16px;\n \n .filter-pills {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n \n .category-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 2px solid #e9ecef;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s ease;\n position: relative;\n overflow: hidden;\n \n &:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n &.active {\n border-color: var(--pill-color);\n background: var(--pill-color);\n color: white;\n \n .pill-count {\n background: rgba(255, 255, 255, 0.3);\n color: white;\n }\n }\n \n .pill-name {\n font-weight: 500;\n }\n \n .pill-count {\n background: #f1f3f5;\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n min-width: 20px;\n text-align: center;\n }\n }\n \n .more-button,\n .clear-filters-button {\n padding: 6px 12px;\n border: 1px solid #dee2e6;\n background: white;\n border-radius: 20px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n \n &:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n }\n \n i {\n font-size: 11px;\n margin-right: 4px;\n }\n }\n \n .clear-filters-button {\n background: #fee2e2;\n border-color: #fca5a5;\n color: #dc2626;\n \n &:hover {\n background: #fca5a5;\n color: white;\n }\n }\n }\n }\n \n .search-box {\n kendo-textbox {\n width: 100%;\n }\n }\n }\n \n .components-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 16px;\n \n .loading-message,\n .empty-message {\n padding: 48px 24px;\n text-align: center;\n color: #6c757d;\n font-size: 14px;\n \n i {\n margin-right: 8px;\n }\n }\n \n .component-card {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 8px;\n margin-bottom: 12px;\n transition: all 0.2s ease;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n &.expanded {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n border-color: #6366f1;\n }\n \n &.running {\n border-color: #10b981;\n box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);\n background: linear-gradient(to right, rgba(16, 185, 129, 0.03) 0%, white 100%);\n \n .card-header {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 4px;\n background: #10b981;\n }\n }\n }\n \n &.file-loaded {\n background: linear-gradient(135deg, #f0f8ff 0%, white 100%);\n border-style: dashed;\n border-color: #3b82f6;\n \n &:hover {\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);\n }\n \n &.expanded {\n border-style: solid;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n }\n }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\n position: relative;\n \n &:hover {\n background: #f8f9fa;\n }\n \n .card-icon {\n font-size: 24px;\n margin-right: 16px;\n width: 32px;\n text-align: center;\n flex-shrink: 0;\n }\n \n .favorite-btn {\n position: absolute;\n top: 12px;\n right: 48px; // Leave room for chevron\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 50%;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n \n &:hover {\n background: #f8f9fa;\n transform: scale(1.1);\n }\n \n &.is-favorite {\n color: #ffc107;\n border-color: #ffc107;\n background: #fff3cd;\n \n &:hover {\n background: #ffe69c;\n }\n }\n \n i {\n font-size: 14px;\n }\n }\n \n .card-info {\n flex: 1;\n min-width: 0;\n \n .card-name {\n font-size: 15px;\n font-weight: 600;\n color: #212529;\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n align-items: center;\n gap: 8px;\n \n .file-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n background: #e0f2fe;\n color: #0369a1;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n flex-shrink: 0;\n \n i {\n font-size: 10px;\n }\n }\n }\n \n .card-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #6c757d;\n \n .card-type {\n font-weight: 500;\n }\n \n .card-version {\n color: #868e96;\n }\n \n .status-badge {\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n \n &.published {\n background: #d1fae5;\n color: #065f46;\n }\n \n &.draft {\n background: #fef3c7;\n color: #92400e;\n }\n \n &.file {\n background: #e0f2fe;\n color: #0369a1;\n }\n \n &.text {\n background: #f3e8ff;\n color: #6b21a8;\n }\n }\n }\n \n .card-namespace {\n margin-top: 8px;\n \n .namespace-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n color: white;\n \n i {\n font-size: 11px;\n opacity: 0.9;\n }\n }\n }\n }\n \n .card-chevron {\n color: #6c757d;\n font-size: 12px;\n margin-left: 12px;\n transition: transform 0.2s ease;\n }\n }\n \n .card-details {\n padding: 0 16px 16px 16px;\n border-top: 1px solid #e9ecef;\n animation: slideDown 0.2s ease;\n \n .detail-section {\n margin-top: 16px;\n \n label {\n display: block;\n font-size: 11px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n \n p {\n margin: 0;\n font-size: 13px;\n color: #495057;\n line-height: 1.5;\n }\n \n .info-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n \n .info-item {\n display: flex;\n align-items: baseline;\n gap: 6px;\n font-size: 13px;\n \n .info-label {\n font-weight: 500;\n color: #6c757d;\n min-width: 50px;\n }\n \n .info-value {\n color: #212529;\n }\n }\n }\n }\n \n .card-actions {\n margin-top: 16px;\n display: flex;\n gap: 8px;\n \n button {\n flex: 1;\n }\n }\n }\n }\n }\n }\n\n .component-display {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n overflow: hidden;\n \n .empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n color: #868e96;\n padding: 48px;\n text-align: center;\n \n i {\n color: #dee2e6;\n margin-bottom: 24px;\n }\n \n h2 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 600;\n color: #495057;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n }\n }\n \n .error-display {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: #f8f9fa;\n \n .error-container {\n width: 100%;\n max-width: 600px;\n background: white;\n border: 2px solid #dc3545;\n border-radius: 8px;\n padding: 24px;\n box-shadow: 0 4px 12px rgba(220, 53, 69, 0.15);\n \n .error-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n color: #dc3545;\n position: relative;\n \n i {\n font-size: 24px;\n }\n \n h3 {\n margin: 0;\n font-size: 20px;\n flex: 1;\n }\n \n .copy-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 10px;\n cursor: pointer;\n color: #6c757d;\n transition: all 0.2s;\n \n &:hover {\n background: #e9ecef;\n color: #495057;\n }\n \n i {\n font-size: 14px;\n }\n }\n }\n \n .error-intro {\n color: #495057;\n margin-bottom: 20px;\n font-size: 14px;\n }\n \n .error-details {\n background: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 13px;\n \n .technical-details {\n margin-top: 12px;\n \n summary {\n cursor: pointer;\n color: #0066cc;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \n &:hover {\n text-decoration: underline;\n }\n }\n \n pre {\n margin-top: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 11px;\n color: #495057;\n max-height: 200px;\n overflow-y: auto;\n }\n }\n }\n \n .error-help {\n background: #e7f3ff;\n border: 1px solid #b3d9ff;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 20px;\n font-size: 13px;\n \n strong {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n color: #0066cc;\n }\n \n ol {\n margin: 0;\n padding-left: 20px;\n \n li {\n margin-bottom: 4px;\n color: #495057;\n }\n }\n }\n \n .error-actions {\n display: flex;\n gap: 12px;\n \n button {\n min-width: 100px;\n }\n }\n }\n }\n \n mj-react-component {\n flex: 1;\n width: 100%;\n height: 100%;\n display: block;\n overflow-y: auto;\n overflow-x: hidden;\n }\n \n // Component and editor splitter\n .component-editor-splitter {\n height: 100%;\n overflow: hidden;\n \n ::ng-deep .k-splitter-bar {\n background: #6366f1; // Same blue as Import button\n width: 6px; // Make it slightly wider for visibility\n \n &:hover {\n background: #4f52d9; // Darker blue on hover\n }\n \n .k-resize-handle {\n background-color: rgba(255, 255, 255, 0.3);\n }\n }\n \n ::ng-deep .k-pane {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n }\n \n // Component runtime area\n .component-runtime {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: white;\n position: relative;\n overflow-y: auto;\n overflow-x: hidden;\n \n .run-empty-state {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n text-align: center;\n \n i {\n color: #10b981;\n margin-bottom: 24px;\n }\n \n h3 {\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #212529;\n }\n \n p {\n margin: 0 0 24px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n }\n }\n }\n \n // Editor tabs on the right\n .editor-tabs {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n \n ::ng-deep .k-tabstrip-items-wrapper {\n background: #f8f9fa;\n border-bottom: 2px solid #dee2e6;\n flex-shrink: 0;\n }\n \n ::ng-deep .k-tabstrip-content {\n flex: 1;\n padding: 0;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n \n ::ng-deep .k-item.k-tabstrip-item {\n font-weight: 500;\n \n &.k-active {\n background: white;\n border-bottom-color: white;\n }\n }\n }\n \n .tab-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n \n &.spec-tab, &.code-tab {\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n \n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\n flex-shrink: 0;\n min-width: 0; // Fix width issue\n \n h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 1; // Allow title to shrink\n min-width: 0; // Prevent overflow\n \n i {\n color: #6366f1;\n flex-shrink: 0; // Keep icon from shrinking\n }\n }\n \n .editor-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0; // Prevent buttons from shrinking\n \n button {\n min-width: auto;\n padding: 4px 12px;\n font-size: 13px;\n white-space: nowrap; // Prevent button text wrapping\n }\n }\n }\n \n .editor-wrapper {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n }\n \n ::ng-deep .monaco-editor {\n border: 1px solid #dee2e6;\n }\n }\n \n .code-sections {\n height: 100%;\n \n ::ng-deep .k-panelbar-item-header {\n background: #f8f9fa;\n font-weight: 500;\n font-size: 14px;\n }\n \n ::ng-deep .k-panelbar-content {\n padding: 0;\n }\n }\n }\n }\n}\n\n// Removed tree view styles - using modern category filters instead\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}"] }]
1636
+ }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.DialogService }, { type: i0.ViewContainerRef }], { fileInput: [{
1637
+ type: ViewChild,
1638
+ args: ['fileInput', { static: false }]
1639
+ }], onDocumentClick: [{
1640
+ type: HostListener,
1641
+ args: ['document:click', ['$event']]
1642
+ }] }); })();
1643
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentStudioDashboardComponent, { className: "ComponentStudioDashboardComponent", filePath: "src/ComponentStudio/component-studio-dashboard.component.ts", lineNumber: 45 }); })();
565
1644
  /**
566
1645
  * Function to prevent tree shaking of the ComponentStudioDashboardComponent.
567
1646
  */