@memberjunction/ng-dashboards 2.88.0 → 2.89.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +105 -9
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +768 -167
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +10 -4
- package/dist/module.js.map +1 -1
- package/package.json +10 -10
|
@@ -4,230 +4,291 @@ 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 } from '@angular/core';
|
|
8
8
|
import { BaseDashboard } from '../generic/base-dashboard';
|
|
9
9
|
import { RegisterClass } from '@memberjunction/global';
|
|
10
10
|
import { RunView } from '@memberjunction/core';
|
|
11
11
|
import { Subject } from 'rxjs';
|
|
12
12
|
import { SharedService } from '@memberjunction/ng-shared';
|
|
13
|
+
import { ParseJSONRecursive } from '@memberjunction/global';
|
|
13
14
|
import * as i0 from "@angular/core";
|
|
14
15
|
import * as i1 from "@angular/common";
|
|
15
|
-
import * as i2 from "@
|
|
16
|
-
import * as i3 from "@progress/kendo-angular-
|
|
17
|
-
import * as i4 from "@progress/kendo-angular-
|
|
18
|
-
import * as i5 from "@memberjunction/ng-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
i0.ɵɵelement(
|
|
16
|
+
import * as i2 from "@angular/forms";
|
|
17
|
+
import * as i3 from "@progress/kendo-angular-inputs";
|
|
18
|
+
import * as i4 from "@progress/kendo-angular-layout";
|
|
19
|
+
import * as i5 from "@memberjunction/ng-code-editor";
|
|
20
|
+
import * as i6 from "@progress/kendo-angular-buttons";
|
|
21
|
+
import * as i7 from "@memberjunction/ng-react";
|
|
22
|
+
const _c0 = ["fileInput"];
|
|
23
|
+
function _forTrack0($index, $item) { return this.getComponentId($item); }
|
|
24
|
+
const _forTrack1 = ($index, $item) => $item.title;
|
|
25
|
+
function ComponentStudioDashboardComponent_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
26
|
+
i0.ɵɵelement(0, "span", 27);
|
|
27
|
+
i0.ɵɵtext(1, " Show Details ");
|
|
28
|
+
} }
|
|
29
|
+
function ComponentStudioDashboardComponent_Conditional_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
30
|
+
i0.ɵɵelement(0, "span", 28);
|
|
31
|
+
i0.ɵɵtext(1, " Hide Details ");
|
|
32
|
+
} }
|
|
33
|
+
function ComponentStudioDashboardComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
34
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
35
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
36
|
+
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()); });
|
|
37
|
+
i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_10_Conditional_1_Template, 2, 0)(2, ComponentStudioDashboardComponent_Conditional_10_Conditional_2_Template, 2, 0);
|
|
38
|
+
i0.ɵɵelementEnd();
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
41
|
+
i0.ɵɵproperty("themeColor", "base");
|
|
42
|
+
i0.ɵɵadvance();
|
|
43
|
+
i0.ɵɵconditional(ctx_r2.isDetailsPaneCollapsed ? 1 : 2);
|
|
44
|
+
} }
|
|
45
|
+
function ComponentStudioDashboardComponent_ng_template_27_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
i0.ɵɵelement(0, "i", 29);
|
|
47
|
+
} }
|
|
48
|
+
function ComponentStudioDashboardComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
49
|
+
i0.ɵɵelementStart(0, "div", 21);
|
|
50
|
+
i0.ɵɵelement(1, "i", 30);
|
|
26
51
|
i0.ɵɵtext(2, " Loading components... ");
|
|
27
52
|
i0.ɵɵelementEnd();
|
|
28
53
|
} }
|
|
29
|
-
function
|
|
30
|
-
i0.ɵɵelementStart(0, "div",
|
|
31
|
-
i0.ɵɵelement(1, "i",
|
|
54
|
+
function ComponentStudioDashboardComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
55
|
+
i0.ɵɵelementStart(0, "div", 22);
|
|
56
|
+
i0.ɵɵelement(1, "i", 31);
|
|
32
57
|
i0.ɵɵtext(2, " No components found without custom properties. ");
|
|
33
58
|
i0.ɵɵelement(3, "br");
|
|
34
59
|
i0.ɵɵelementStart(4, "small");
|
|
35
60
|
i0.ɵɵtext(5, "Only components that don't require custom props can be tested here.");
|
|
36
61
|
i0.ɵɵelementEnd()();
|
|
37
62
|
} }
|
|
38
|
-
function
|
|
39
|
-
i0.ɵɵelementStart(0, "span",
|
|
63
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
+
i0.ɵɵelementStart(0, "span", 39);
|
|
65
|
+
i0.ɵɵelement(1, "i", 50);
|
|
66
|
+
i0.ɵɵtext(2);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
} if (rf & 2) {
|
|
69
|
+
const component_r5 = i0.ɵɵnextContext().$implicit;
|
|
70
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
71
|
+
i0.ɵɵpropertyInterpolate1("title", "Loaded from ", ctx_r2.getComponentFilename(component_r5), "");
|
|
72
|
+
i0.ɵɵadvance(2);
|
|
73
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.getComponentFilename(component_r5), " ");
|
|
74
|
+
} }
|
|
75
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
76
|
+
i0.ɵɵelementStart(0, "span", 43);
|
|
77
|
+
i0.ɵɵtext(1, "File");
|
|
78
|
+
i0.ɵɵelementEnd();
|
|
79
|
+
} }
|
|
80
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
81
|
+
i0.ɵɵelementStart(0, "span", 44);
|
|
40
82
|
i0.ɵɵtext(1, "Published");
|
|
41
83
|
i0.ɵɵelementEnd();
|
|
42
84
|
} }
|
|
43
|
-
function
|
|
44
|
-
i0.ɵɵelementStart(0, "span",
|
|
85
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
86
|
+
i0.ɵɵelementStart(0, "span", 45);
|
|
45
87
|
i0.ɵɵtext(1, "Draft");
|
|
46
88
|
i0.ɵɵelementEnd();
|
|
47
89
|
} }
|
|
48
|
-
function
|
|
49
|
-
i0.ɵɵelement(0, "i",
|
|
90
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
91
|
+
i0.ɵɵelement(0, "i", 47);
|
|
50
92
|
} }
|
|
51
|
-
function
|
|
52
|
-
i0.ɵɵelement(0, "i",
|
|
93
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
+
i0.ɵɵelement(0, "i", 48);
|
|
53
95
|
} }
|
|
54
|
-
function
|
|
55
|
-
i0.ɵɵelementStart(0, "div",
|
|
96
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
i0.ɵɵelementStart(0, "div", 51)(1, "label");
|
|
56
98
|
i0.ɵɵtext(2, "Description");
|
|
57
99
|
i0.ɵɵelementEnd();
|
|
58
100
|
i0.ɵɵelementStart(3, "p");
|
|
59
101
|
i0.ɵɵtext(4);
|
|
60
102
|
i0.ɵɵelementEnd()();
|
|
61
103
|
} if (rf & 2) {
|
|
62
|
-
const
|
|
104
|
+
const component_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
105
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
106
|
+
i0.ɵɵadvance(4);
|
|
107
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(component_r5));
|
|
108
|
+
} }
|
|
109
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
110
|
+
i0.ɵɵelementStart(0, "div", 53)(1, "span", 54);
|
|
111
|
+
i0.ɵɵtext(2, "Loaded:");
|
|
112
|
+
i0.ɵɵelementEnd();
|
|
113
|
+
i0.ɵɵelementStart(3, "span", 55);
|
|
114
|
+
i0.ɵɵtext(4);
|
|
115
|
+
i0.ɵɵpipe(5, "date");
|
|
116
|
+
i0.ɵɵelementEnd()();
|
|
117
|
+
} if (rf & 2) {
|
|
118
|
+
const component_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
119
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
63
120
|
i0.ɵɵadvance(4);
|
|
64
|
-
i0.ɵɵtextInterpolate(
|
|
121
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentLoadedAt(component_r5), "short"));
|
|
65
122
|
} }
|
|
66
|
-
function
|
|
67
|
-
i0.ɵɵelementStart(0, "div",
|
|
123
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
124
|
+
i0.ɵɵelementStart(0, "div", 53)(1, "span", 54);
|
|
68
125
|
i0.ɵɵtext(2, "Updated:");
|
|
69
126
|
i0.ɵɵelementEnd();
|
|
70
|
-
i0.ɵɵelementStart(3, "span",
|
|
127
|
+
i0.ɵɵelementStart(3, "span", 55);
|
|
71
128
|
i0.ɵɵtext(4);
|
|
72
129
|
i0.ɵɵpipe(5, "date");
|
|
73
130
|
i0.ɵɵelementEnd()();
|
|
74
131
|
} if (rf & 2) {
|
|
75
|
-
const
|
|
132
|
+
const component_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
133
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
76
134
|
i0.ɵɵadvance(4);
|
|
77
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1,
|
|
135
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentUpdatedAt(component_r5), "short"));
|
|
78
136
|
} }
|
|
79
|
-
function
|
|
80
|
-
const
|
|
81
|
-
i0.ɵɵelementStart(0, "button",
|
|
82
|
-
i0.ɵɵlistener("click", function
|
|
83
|
-
i0.ɵɵelement(1, "span",
|
|
137
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
139
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
140
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_24_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.stopComponent(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
141
|
+
i0.ɵɵelement(1, "span", 58);
|
|
84
142
|
i0.ɵɵtext(2, " Stop Component ");
|
|
85
143
|
i0.ɵɵelementEnd();
|
|
86
144
|
} if (rf & 2) {
|
|
87
145
|
i0.ɵɵproperty("themeColor", "error");
|
|
88
146
|
} }
|
|
89
|
-
function
|
|
90
|
-
const
|
|
91
|
-
i0.ɵɵelementStart(0, "button",
|
|
92
|
-
i0.ɵɵlistener("click", function
|
|
93
|
-
i0.ɵɵelement(1, "span",
|
|
147
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
148
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
149
|
+
i0.ɵɵelementStart(0, "button", 59);
|
|
150
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_25_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r7); const component_r5 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r5); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
151
|
+
i0.ɵɵelement(1, "span", 60);
|
|
94
152
|
i0.ɵɵtext(2, " Switch to This Component ");
|
|
95
153
|
i0.ɵɵelementEnd();
|
|
96
154
|
} if (rf & 2) {
|
|
97
155
|
i0.ɵɵproperty("themeColor", "base");
|
|
98
156
|
} }
|
|
99
|
-
function
|
|
100
|
-
const
|
|
101
|
-
i0.ɵɵelementStart(0, "button",
|
|
102
|
-
i0.ɵɵlistener("click", function
|
|
103
|
-
i0.ɵɵelement(1, "span",
|
|
157
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
158
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
159
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
160
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_26_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r8); const component_r5 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.runComponent(component_r5); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
161
|
+
i0.ɵɵelement(1, "span", 60);
|
|
104
162
|
i0.ɵɵtext(2, " Run Component ");
|
|
105
163
|
i0.ɵɵelementEnd();
|
|
106
164
|
} if (rf & 2) {
|
|
107
165
|
i0.ɵɵproperty("themeColor", "primary");
|
|
108
166
|
} }
|
|
109
|
-
function
|
|
110
|
-
i0.ɵɵelementStart(0, "div",
|
|
111
|
-
i0.ɵɵtemplate(1,
|
|
112
|
-
i0.ɵɵelementStart(2, "div",
|
|
167
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
168
|
+
i0.ɵɵelementStart(0, "div", 49);
|
|
169
|
+
i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_1_Template, 5, 1, "div", 51);
|
|
170
|
+
i0.ɵɵelementStart(2, "div", 51)(3, "label");
|
|
113
171
|
i0.ɵɵtext(4, "Component Info");
|
|
114
172
|
i0.ɵɵelementEnd();
|
|
115
|
-
i0.ɵɵelementStart(5, "div",
|
|
173
|
+
i0.ɵɵelementStart(5, "div", 52)(6, "div", 53)(7, "span", 54);
|
|
116
174
|
i0.ɵɵtext(8, "Type:");
|
|
117
175
|
i0.ɵɵelementEnd();
|
|
118
|
-
i0.ɵɵelementStart(9, "span",
|
|
176
|
+
i0.ɵɵelementStart(9, "span", 55);
|
|
119
177
|
i0.ɵɵtext(10);
|
|
120
178
|
i0.ɵɵelementEnd()();
|
|
121
|
-
i0.ɵɵelementStart(11, "div",
|
|
179
|
+
i0.ɵɵelementStart(11, "div", 53)(12, "span", 54);
|
|
122
180
|
i0.ɵɵtext(13, "Version:");
|
|
123
181
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵelementStart(14, "span",
|
|
182
|
+
i0.ɵɵelementStart(14, "span", 55);
|
|
125
183
|
i0.ɵɵtext(15);
|
|
126
184
|
i0.ɵɵelementEnd()();
|
|
127
|
-
i0.ɵɵelementStart(16, "div",
|
|
185
|
+
i0.ɵɵelementStart(16, "div", 53)(17, "span", 54);
|
|
128
186
|
i0.ɵɵtext(18, "Status:");
|
|
129
187
|
i0.ɵɵelementEnd();
|
|
130
|
-
i0.ɵɵelementStart(19, "span",
|
|
188
|
+
i0.ɵɵelementStart(19, "span", 55);
|
|
131
189
|
i0.ɵɵtext(20);
|
|
132
190
|
i0.ɵɵelementEnd()();
|
|
133
|
-
i0.ɵɵtemplate(21,
|
|
191
|
+
i0.ɵɵtemplate(21, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_21_Template, 6, 4, "div", 53)(22, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_22_Template, 6, 4, "div", 53);
|
|
134
192
|
i0.ɵɵelementEnd()();
|
|
135
|
-
i0.ɵɵelementStart(
|
|
136
|
-
i0.ɵɵtemplate(
|
|
193
|
+
i0.ɵɵelementStart(23, "div", 56);
|
|
194
|
+
i0.ɵɵtemplate(24, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_24_Template, 3, 1, "button", 7)(25, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_25_Template, 3, 1, "button", 57)(26, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Conditional_26_Template, 3, 1, "button", 7);
|
|
137
195
|
i0.ɵɵelementEnd()();
|
|
138
196
|
} if (rf & 2) {
|
|
139
|
-
const
|
|
197
|
+
const component_r5 = i0.ɵɵnextContext().$implicit;
|
|
140
198
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
141
199
|
i0.ɵɵadvance();
|
|
142
|
-
i0.ɵɵconditional(
|
|
200
|
+
i0.ɵɵconditional(ctx_r2.getComponentDescription(component_r5) ? 1 : -1);
|
|
143
201
|
i0.ɵɵadvance(9);
|
|
144
|
-
i0.ɵɵtextInterpolate(
|
|
202
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r5) || "Unknown");
|
|
145
203
|
i0.ɵɵadvance(5);
|
|
146
|
-
i0.ɵɵtextInterpolate(
|
|
204
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentVersion(component_r5));
|
|
147
205
|
i0.ɵɵadvance(5);
|
|
148
|
-
i0.ɵɵtextInterpolate(
|
|
206
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentStatus(component_r5) || "Draft");
|
|
149
207
|
i0.ɵɵadvance();
|
|
150
|
-
i0.ɵɵconditional(
|
|
151
|
-
i0.ɵɵadvance(
|
|
152
|
-
i0.ɵɵconditional(
|
|
208
|
+
i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r5) ? 21 : !ctx_r2.isFileLoadedComponent(component_r5) && ctx_r2.getComponentUpdatedAt(component_r5) ? 22 : -1);
|
|
209
|
+
i0.ɵɵadvance(3);
|
|
210
|
+
i0.ɵɵconditional(ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) === ctx_r2.getComponentId(component_r5) && ctx_r2.isRunning ? 24 : ctx_r2.isRunning && ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) !== ctx_r2.getComponentId(component_r5) ? 25 : 26);
|
|
153
211
|
} }
|
|
154
|
-
function
|
|
155
|
-
const
|
|
156
|
-
i0.ɵɵelementStart(0, "div",
|
|
157
|
-
i0.ɵɵlistener("click", function
|
|
158
|
-
i0.ɵɵelementStart(2, "div",
|
|
159
|
-
i0.ɵɵelement(3, "i",
|
|
212
|
+
function ComponentStudioDashboardComponent_Conditional_31_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
213
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
214
|
+
i0.ɵɵelementStart(0, "div", 33)(1, "div", 34);
|
|
215
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_31_For_1_Template_div_click_1_listener() { const component_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleComponentExpansion(component_r5)); });
|
|
216
|
+
i0.ɵɵelementStart(2, "div", 35);
|
|
217
|
+
i0.ɵɵelement(3, "i", 36);
|
|
160
218
|
i0.ɵɵelementEnd();
|
|
161
|
-
i0.ɵɵelementStart(4, "div",
|
|
219
|
+
i0.ɵɵelementStart(4, "div", 37)(5, "div", 38);
|
|
162
220
|
i0.ɵɵtext(6);
|
|
221
|
+
i0.ɵɵtemplate(7, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_7_Template, 3, 3, "span", 39);
|
|
163
222
|
i0.ɵɵelementEnd();
|
|
164
|
-
i0.ɵɵelementStart(
|
|
165
|
-
i0.ɵɵtext(
|
|
223
|
+
i0.ɵɵelementStart(8, "div", 40)(9, "span", 41);
|
|
224
|
+
i0.ɵɵtext(10);
|
|
166
225
|
i0.ɵɵelementEnd();
|
|
167
|
-
i0.ɵɵelementStart(
|
|
168
|
-
i0.ɵɵtext(
|
|
226
|
+
i0.ɵɵelementStart(11, "span", 42);
|
|
227
|
+
i0.ɵɵtext(12);
|
|
169
228
|
i0.ɵɵelementEnd();
|
|
170
|
-
i0.ɵɵtemplate(
|
|
229
|
+
i0.ɵɵtemplate(13, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_13_Template, 2, 0, "span", 43)(14, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_14_Template, 2, 0, "span", 44)(15, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_15_Template, 2, 0, "span", 45);
|
|
171
230
|
i0.ɵɵelementEnd()();
|
|
172
|
-
i0.ɵɵelementStart(
|
|
173
|
-
i0.ɵɵtemplate(
|
|
231
|
+
i0.ɵɵelementStart(16, "div", 46);
|
|
232
|
+
i0.ɵɵtemplate(17, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_17_Template, 1, 0, "i", 47)(18, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_18_Template, 1, 0, "i", 48);
|
|
174
233
|
i0.ɵɵelementEnd()();
|
|
175
|
-
i0.ɵɵtemplate(
|
|
234
|
+
i0.ɵɵtemplate(19, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Template, 27, 6, "div", 49);
|
|
176
235
|
i0.ɵɵelementEnd();
|
|
177
236
|
} if (rf & 2) {
|
|
178
|
-
const
|
|
237
|
+
const component_r5 = ctx.$implicit;
|
|
179
238
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
180
|
-
i0.ɵɵclassProp("expanded",
|
|
239
|
+
i0.ɵɵclassProp("expanded", ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r5))("running", ctx_r2.selectedComponent && ctx_r2.getComponentId(ctx_r2.selectedComponent) === ctx_r2.getComponentId(component_r5) && ctx_r2.isRunning)("file-loaded", ctx_r2.isFileLoadedComponent(component_r5));
|
|
181
240
|
i0.ɵɵadvance(2);
|
|
182
|
-
i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(
|
|
241
|
+
i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(ctx_r2.getComponentType(component_r5)));
|
|
183
242
|
i0.ɵɵadvance();
|
|
184
|
-
i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(
|
|
243
|
+
i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(ctx_r2.getComponentType(component_r5)));
|
|
185
244
|
i0.ɵɵadvance(3);
|
|
186
|
-
i0.ɵɵ
|
|
245
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.getComponentName(component_r5), " ");
|
|
246
|
+
i0.ɵɵadvance();
|
|
247
|
+
i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r5) ? 7 : -1);
|
|
187
248
|
i0.ɵɵadvance(3);
|
|
188
|
-
i0.ɵɵtextInterpolate(
|
|
249
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r5) || "Component");
|
|
189
250
|
i0.ɵɵadvance(2);
|
|
190
|
-
i0.ɵɵtextInterpolate1("v",
|
|
251
|
+
i0.ɵɵtextInterpolate1("v", ctx_r2.getComponentVersion(component_r5), "");
|
|
191
252
|
i0.ɵɵadvance();
|
|
192
|
-
i0.ɵɵconditional(
|
|
193
|
-
i0.ɵɵadvance(
|
|
194
|
-
i0.ɵɵconditional(
|
|
253
|
+
i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r5) ? 13 : ctx_r2.getComponentStatus(component_r5) === "Published" ? 14 : 15);
|
|
254
|
+
i0.ɵɵadvance(4);
|
|
255
|
+
i0.ɵɵconditional(ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r5) ? 17 : 18);
|
|
195
256
|
i0.ɵɵadvance(2);
|
|
196
|
-
i0.ɵɵconditional(
|
|
257
|
+
i0.ɵɵconditional(ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r5) ? 19 : -1);
|
|
197
258
|
} }
|
|
198
|
-
function
|
|
199
|
-
i0.ɵɵrepeaterCreate(0,
|
|
259
|
+
function ComponentStudioDashboardComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
260
|
+
i0.ɵɵrepeaterCreate(0, ComponentStudioDashboardComponent_Conditional_31_For_1_Template, 20, 16, "div", 32, _forTrack0, true);
|
|
200
261
|
} if (rf & 2) {
|
|
201
262
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
202
263
|
i0.ɵɵrepeater(ctx_r2.filteredComponents);
|
|
203
264
|
} }
|
|
204
|
-
function
|
|
205
|
-
i0.ɵɵelementStart(0, "details",
|
|
265
|
+
function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
266
|
+
i0.ɵɵelementStart(0, "details", 77)(1, "summary");
|
|
206
267
|
i0.ɵɵtext(2, "Technical Details (click to expand)");
|
|
207
268
|
i0.ɵɵelementEnd();
|
|
208
269
|
i0.ɵɵelementStart(3, "pre");
|
|
209
270
|
i0.ɵɵtext(4);
|
|
210
271
|
i0.ɵɵelementEnd()();
|
|
211
272
|
} if (rf & 2) {
|
|
212
|
-
const ctx_r2 = i0.ɵɵnextContext(
|
|
273
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
213
274
|
i0.ɵɵadvance(4);
|
|
214
275
|
i0.ɵɵtextInterpolate(ctx_r2.formatTechnicalDetails(ctx_r2.currentError.technicalDetails));
|
|
215
276
|
} }
|
|
216
|
-
function
|
|
217
|
-
const
|
|
218
|
-
i0.ɵɵelementStart(0, "div",
|
|
219
|
-
i0.ɵɵelement(3, "i",
|
|
277
|
+
function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
278
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
279
|
+
i0.ɵɵelementStart(0, "div", 68)(1, "div", 70)(2, "div", 71);
|
|
280
|
+
i0.ɵɵelement(3, "i", 72);
|
|
220
281
|
i0.ɵɵelementStart(4, "h3");
|
|
221
282
|
i0.ɵɵtext(5, "Component Error");
|
|
222
283
|
i0.ɵɵelementEnd();
|
|
223
|
-
i0.ɵɵelementStart(6, "button",
|
|
224
|
-
i0.ɵɵlistener("click", function
|
|
225
|
-
i0.ɵɵelement(7, "i",
|
|
284
|
+
i0.ɵɵelementStart(6, "button", 73);
|
|
285
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.copyErrorToClipboard()); });
|
|
286
|
+
i0.ɵɵelement(7, "i", 74);
|
|
226
287
|
i0.ɵɵelementEnd()();
|
|
227
|
-
i0.ɵɵelementStart(8, "p",
|
|
288
|
+
i0.ɵɵelementStart(8, "p", 75);
|
|
228
289
|
i0.ɵɵtext(9, " The component could not be rendered due to the following error: ");
|
|
229
290
|
i0.ɵɵelementEnd();
|
|
230
|
-
i0.ɵɵelementStart(10, "div",
|
|
291
|
+
i0.ɵɵelementStart(10, "div", 76)(11, "strong");
|
|
231
292
|
i0.ɵɵtext(12, "Error Type:");
|
|
232
293
|
i0.ɵɵelementEnd();
|
|
233
294
|
i0.ɵɵtext(13);
|
|
@@ -236,9 +297,9 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
|
|
|
236
297
|
i0.ɵɵtext(16, "Message:");
|
|
237
298
|
i0.ɵɵelementEnd();
|
|
238
299
|
i0.ɵɵtext(17);
|
|
239
|
-
i0.ɵɵtemplate(18,
|
|
300
|
+
i0.ɵɵtemplate(18, ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Conditional_18_Template, 5, 1, "details", 77);
|
|
240
301
|
i0.ɵɵelementEnd();
|
|
241
|
-
i0.ɵɵelementStart(19, "div",
|
|
302
|
+
i0.ɵɵelementStart(19, "div", 78)(20, "strong");
|
|
242
303
|
i0.ɵɵtext(21, "What to do:");
|
|
243
304
|
i0.ɵɵelementEnd();
|
|
244
305
|
i0.ɵɵelementStart(22, "ol")(23, "li");
|
|
@@ -253,18 +314,18 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
|
|
|
253
314
|
i0.ɵɵelementStart(29, "li");
|
|
254
315
|
i0.ɵɵtext(30, "Contact your system administrator if the issue persists");
|
|
255
316
|
i0.ɵɵelementEnd()()();
|
|
256
|
-
i0.ɵɵelementStart(31, "div",
|
|
257
|
-
i0.ɵɵlistener("click", function
|
|
258
|
-
i0.ɵɵelement(33, "span",
|
|
317
|
+
i0.ɵɵelementStart(31, "div", 79)(32, "button", 80);
|
|
318
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.retryComponent()); });
|
|
319
|
+
i0.ɵɵelement(33, "span", 81);
|
|
259
320
|
i0.ɵɵtext(34, " Retry ");
|
|
260
321
|
i0.ɵɵelementEnd();
|
|
261
|
-
i0.ɵɵelementStart(35, "button",
|
|
262
|
-
i0.ɵɵlistener("click", function
|
|
263
|
-
i0.ɵɵelement(36, "span",
|
|
322
|
+
i0.ɵɵelementStart(35, "button", 8);
|
|
323
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.stopComponent()); });
|
|
324
|
+
i0.ɵɵelement(36, "span", 58);
|
|
264
325
|
i0.ɵɵtext(37, " Stop ");
|
|
265
326
|
i0.ɵɵelementEnd()()()();
|
|
266
327
|
} if (rf & 2) {
|
|
267
|
-
const ctx_r2 = i0.ɵɵnextContext(
|
|
328
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
268
329
|
i0.ɵɵadvance(13);
|
|
269
330
|
i0.ɵɵtextInterpolate1(" ", ctx_r2.currentError.type, "");
|
|
270
331
|
i0.ɵɵadvance(4);
|
|
@@ -274,35 +335,197 @@ function ComponentStudioDashboardComponent_Conditional_27_Conditional_0_Template
|
|
|
274
335
|
i0.ɵɵadvance(17);
|
|
275
336
|
i0.ɵɵproperty("themeColor", "error");
|
|
276
337
|
} }
|
|
277
|
-
function
|
|
278
|
-
const
|
|
279
|
-
i0.ɵɵelementStart(0, "mj-react-component",
|
|
280
|
-
i0.ɵɵlistener("componentEvent", function
|
|
338
|
+
function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
339
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
340
|
+
i0.ɵɵelementStart(0, "mj-react-component", 82);
|
|
341
|
+
i0.ɵɵlistener("componentEvent", function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_1_Template_mj_react_component_componentEvent_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onComponentEvent($event)); })("openEntityRecord", function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_1_Template_mj_react_component_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
|
|
281
342
|
i0.ɵɵelementEnd();
|
|
282
343
|
} if (rf & 2) {
|
|
283
|
-
const ctx_r2 = i0.ɵɵnextContext(
|
|
344
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
284
345
|
i0.ɵɵproperty("component", ctx_r2.componentSpec);
|
|
285
346
|
} }
|
|
286
|
-
function
|
|
287
|
-
i0.ɵɵtemplate(0,
|
|
347
|
+
function ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
+
i0.ɵɵtemplate(0, ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Template, 38, 4, "div", 68)(1, ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_1_Template, 1, 1, "mj-react-component", 69);
|
|
288
349
|
} if (rf & 2) {
|
|
289
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
350
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
290
351
|
i0.ɵɵconditional(ctx_r2.currentError ? 0 : 1);
|
|
291
352
|
} }
|
|
292
|
-
function
|
|
293
|
-
i0.ɵɵ
|
|
294
|
-
i0.ɵɵ
|
|
353
|
+
function ComponentStudioDashboardComponent_Conditional_34_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
354
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
355
|
+
i0.ɵɵelementStart(0, "div", 63);
|
|
356
|
+
i0.ɵɵelement(1, "i", 83);
|
|
357
|
+
i0.ɵɵelementStart(2, "h3");
|
|
358
|
+
i0.ɵɵtext(3);
|
|
359
|
+
i0.ɵɵelementEnd();
|
|
360
|
+
i0.ɵɵelementStart(4, "p");
|
|
361
|
+
i0.ɵɵtext(5);
|
|
362
|
+
i0.ɵɵelementEnd();
|
|
363
|
+
i0.ɵɵelementStart(6, "button", 84);
|
|
364
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_Conditional_4_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.runComponent(ctx_r2.selectedComponent)); });
|
|
365
|
+
i0.ɵɵelement(7, "span", 60);
|
|
366
|
+
i0.ɵɵtext(8, " Run Component ");
|
|
367
|
+
i0.ɵɵelementEnd()();
|
|
368
|
+
} if (rf & 2) {
|
|
369
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
370
|
+
i0.ɵɵadvance(3);
|
|
371
|
+
i0.ɵɵtextInterpolate1("Component: ", ctx_r2.getComponentName(ctx_r2.selectedComponent), "");
|
|
372
|
+
i0.ɵɵadvance(2);
|
|
373
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(ctx_r2.selectedComponent) || "No description available");
|
|
374
|
+
i0.ɵɵadvance();
|
|
375
|
+
i0.ɵɵproperty("themeColor", "primary")("size", "large");
|
|
376
|
+
} }
|
|
377
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
378
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
379
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
380
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.applySpecChanges()); });
|
|
381
|
+
i0.ɵɵelement(1, "span", 91);
|
|
382
|
+
i0.ɵɵtext(2, " Apply Changes ");
|
|
383
|
+
i0.ɵɵelementEnd();
|
|
384
|
+
i0.ɵɵelementStart(3, "button", 80);
|
|
385
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.initializeEditors()); });
|
|
386
|
+
i0.ɵɵelement(4, "span", 92);
|
|
387
|
+
i0.ɵɵtext(5, " Cancel ");
|
|
388
|
+
i0.ɵɵelementEnd();
|
|
389
|
+
} if (rf & 2) {
|
|
390
|
+
i0.ɵɵproperty("themeColor", "primary");
|
|
391
|
+
} }
|
|
392
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
393
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
394
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
395
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.refreshComponent()); });
|
|
396
|
+
i0.ɵɵelement(1, "span", 11);
|
|
397
|
+
i0.ɵɵtext(2, " Refresh Component ");
|
|
398
|
+
i0.ɵɵelementEnd();
|
|
399
|
+
} if (rf & 2) {
|
|
400
|
+
i0.ɵɵproperty("themeColor", "info");
|
|
401
|
+
} }
|
|
402
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Template(rf, ctx) { if (rf & 1) {
|
|
403
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
404
|
+
i0.ɵɵelementStart(0, "div", 85)(1, "div", 86)(2, "h4");
|
|
405
|
+
i0.ɵɵelement(3, "i", 87);
|
|
406
|
+
i0.ɵɵtext(4, " Component Specification (JSON)");
|
|
407
|
+
i0.ɵɵelementEnd();
|
|
408
|
+
i0.ɵɵelementStart(5, "div", 88);
|
|
409
|
+
i0.ɵɵtemplate(6, ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_6_Template, 6, 1)(7, ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Conditional_7_Template, 3, 1, "button", 7);
|
|
410
|
+
i0.ɵɵelementEnd()();
|
|
411
|
+
i0.ɵɵelementStart(8, "div", 89)(9, "mj-code-editor", 90);
|
|
412
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Template_mj_code_editor_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.editableSpec, $event) || (ctx_r2.editableSpec = $event); return i0.ɵɵresetView($event); });
|
|
413
|
+
i0.ɵɵlistener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Template_mj_code_editor_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onSpecChange($event)); });
|
|
414
|
+
i0.ɵɵelementEnd()()();
|
|
415
|
+
} if (rf & 2) {
|
|
416
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
417
|
+
i0.ɵɵadvance(6);
|
|
418
|
+
i0.ɵɵconditional(ctx_r2.isEditingSpec ? 6 : -1);
|
|
419
|
+
i0.ɵɵadvance();
|
|
420
|
+
i0.ɵɵconditional(ctx_r2.isRunning ? 7 : -1);
|
|
421
|
+
i0.ɵɵadvance(2);
|
|
422
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.editableSpec);
|
|
423
|
+
i0.ɵɵproperty("language", "json")("readonly", false);
|
|
424
|
+
} }
|
|
425
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
426
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
427
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
428
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.applyCodeChanges()); });
|
|
429
|
+
i0.ɵɵelement(1, "span", 91);
|
|
430
|
+
i0.ɵɵtext(2, " Apply Changes ");
|
|
431
|
+
i0.ɵɵelementEnd();
|
|
432
|
+
i0.ɵɵelementStart(3, "button", 80);
|
|
433
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.initializeEditors()); });
|
|
434
|
+
i0.ɵɵelement(4, "span", 92);
|
|
435
|
+
i0.ɵɵtext(5, " Cancel ");
|
|
436
|
+
i0.ɵɵelementEnd();
|
|
437
|
+
} if (rf & 2) {
|
|
438
|
+
i0.ɵɵproperty("themeColor", "primary");
|
|
439
|
+
} }
|
|
440
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
441
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
442
|
+
i0.ɵɵelementStart(0, "button", 8);
|
|
443
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.refreshComponent()); });
|
|
444
|
+
i0.ɵɵelement(1, "span", 11);
|
|
445
|
+
i0.ɵɵtext(2, " Refresh Component ");
|
|
446
|
+
i0.ɵɵelementEnd();
|
|
447
|
+
} if (rf & 2) {
|
|
448
|
+
i0.ɵɵproperty("themeColor", "info");
|
|
449
|
+
} }
|
|
450
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_For_11_ng_template_1_Template(rf, ctx) { if (rf & 1) {
|
|
451
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
452
|
+
i0.ɵɵelementStart(0, "mj-code-editor", 98);
|
|
453
|
+
i0.ɵɵlistener("ngModelChange", function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_For_11_ng_template_1_Template_mj_code_editor_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r18); const ɵ$index_390_r19 = i0.ɵɵnextContext().$index; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onCodeSectionChange($event, ɵ$index_390_r19)); });
|
|
454
|
+
i0.ɵɵelementEnd();
|
|
455
|
+
} if (rf & 2) {
|
|
456
|
+
const section_r20 = i0.ɵɵnextContext().$implicit;
|
|
457
|
+
i0.ɵɵproperty("ngModel", section_r20.code)("language", "javascript")("readonly", false);
|
|
458
|
+
} }
|
|
459
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
460
|
+
i0.ɵɵelementStart(0, "kendo-panelbar-item", 96);
|
|
461
|
+
i0.ɵɵtemplate(1, ComponentStudioDashboardComponent_Conditional_34_ng_template_10_For_11_ng_template_1_Template, 1, 3, "ng-template", 97);
|
|
462
|
+
i0.ɵɵelementEnd();
|
|
463
|
+
} if (rf & 2) {
|
|
464
|
+
const section_r20 = ctx.$implicit;
|
|
465
|
+
i0.ɵɵproperty("title", section_r20.title)("expanded", section_r20.expanded);
|
|
466
|
+
} }
|
|
467
|
+
function ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Template(rf, ctx) { if (rf & 1) {
|
|
468
|
+
i0.ɵɵelementStart(0, "div", 93)(1, "div", 86)(2, "h4");
|
|
469
|
+
i0.ɵɵelement(3, "i", 94);
|
|
470
|
+
i0.ɵɵtext(4, " Component Code (JavaScript/React)");
|
|
471
|
+
i0.ɵɵelementEnd();
|
|
472
|
+
i0.ɵɵelementStart(5, "div", 88);
|
|
473
|
+
i0.ɵɵtemplate(6, ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_6_Template, 6, 1)(7, ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Conditional_7_Template, 3, 1, "button", 7);
|
|
474
|
+
i0.ɵɵelementEnd()();
|
|
475
|
+
i0.ɵɵelementStart(8, "div", 89)(9, "kendo-panelbar", 95);
|
|
476
|
+
i0.ɵɵrepeaterCreate(10, ComponentStudioDashboardComponent_Conditional_34_ng_template_10_For_11_Template, 2, 2, "kendo-panelbar-item", 96, _forTrack1);
|
|
477
|
+
i0.ɵɵelementEnd()()();
|
|
478
|
+
} if (rf & 2) {
|
|
479
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
480
|
+
i0.ɵɵadvance(6);
|
|
481
|
+
i0.ɵɵconditional(ctx_r2.isEditingCode ? 6 : -1);
|
|
482
|
+
i0.ɵɵadvance();
|
|
483
|
+
i0.ɵɵconditional(ctx_r2.isRunning ? 7 : -1);
|
|
484
|
+
i0.ɵɵadvance(3);
|
|
485
|
+
i0.ɵɵrepeater(ctx_r2.getComponentCodeSections());
|
|
486
|
+
} }
|
|
487
|
+
function ComponentStudioDashboardComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
488
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
489
|
+
i0.ɵɵelementStart(0, "kendo-splitter", 25)(1, "kendo-splitter-pane", 61)(2, "div", 62);
|
|
490
|
+
i0.ɵɵtemplate(3, ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Template, 2, 1)(4, ComponentStudioDashboardComponent_Conditional_34_Conditional_4_Template, 9, 4, "div", 63);
|
|
491
|
+
i0.ɵɵelementEnd()();
|
|
492
|
+
i0.ɵɵelementStart(5, "kendo-splitter-pane", 64)(6, "kendo-tabstrip", 65);
|
|
493
|
+
i0.ɵɵlistener("tabSelect", function ComponentStudioDashboardComponent_Conditional_34_Template_kendo_tabstrip_tabSelect_6_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTabSelect($event)); });
|
|
494
|
+
i0.ɵɵelementStart(7, "kendo-tabstrip-tab", 66);
|
|
495
|
+
i0.ɵɵtemplate(8, ComponentStudioDashboardComponent_Conditional_34_ng_template_8_Template, 10, 5, "ng-template", 67);
|
|
496
|
+
i0.ɵɵelementEnd();
|
|
497
|
+
i0.ɵɵelementStart(9, "kendo-tabstrip-tab", 66);
|
|
498
|
+
i0.ɵɵtemplate(10, ComponentStudioDashboardComponent_Conditional_34_ng_template_10_Template, 12, 2, "ng-template", 67);
|
|
499
|
+
i0.ɵɵelementEnd()()()();
|
|
500
|
+
} if (rf & 2) {
|
|
501
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
502
|
+
i0.ɵɵadvance();
|
|
503
|
+
i0.ɵɵproperty("min", "300px")("collapsible", false)("size", ctx_r2.isDetailsPaneCollapsed ? "100%" : "50%");
|
|
504
|
+
i0.ɵɵadvance(2);
|
|
505
|
+
i0.ɵɵconditional(ctx_r2.isRunning && ctx_r2.componentSpec ? 3 : 4);
|
|
506
|
+
i0.ɵɵadvance(2);
|
|
507
|
+
i0.ɵɵproperty("min", "400px")("collapsible", true)("collapsed", ctx_r2.isDetailsPaneCollapsed);
|
|
508
|
+
i0.ɵɵadvance(2);
|
|
509
|
+
i0.ɵɵproperty("title", "Spec")("selected", ctx_r2.activeTab === 0);
|
|
510
|
+
i0.ɵɵadvance(2);
|
|
511
|
+
i0.ɵɵproperty("title", "Code")("selected", ctx_r2.activeTab === 1);
|
|
512
|
+
} }
|
|
513
|
+
function ComponentStudioDashboardComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
514
|
+
i0.ɵɵelementStart(0, "div", 26);
|
|
515
|
+
i0.ɵɵelement(1, "i", 99);
|
|
295
516
|
i0.ɵɵelementStart(2, "h2");
|
|
296
517
|
i0.ɵɵtext(3, "Ready to Test Components");
|
|
297
518
|
i0.ɵɵelementEnd();
|
|
298
519
|
i0.ɵɵelementStart(4, "p");
|
|
299
|
-
i0.ɵɵtext(5, "Select a component from the list
|
|
520
|
+
i0.ɵɵtext(5, "Select a component from the list to view its details and run it");
|
|
300
521
|
i0.ɵɵelementEnd()();
|
|
301
522
|
} }
|
|
302
523
|
let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent extends BaseDashboard {
|
|
303
524
|
cdr;
|
|
304
525
|
// Component data
|
|
305
526
|
components = [];
|
|
527
|
+
fileLoadedComponents = []; // Components loaded from files
|
|
528
|
+
allComponents = []; // Combined list
|
|
306
529
|
filteredComponents = [];
|
|
307
530
|
selectedComponent = null;
|
|
308
531
|
expandedComponent = null; // Track which card is expanded
|
|
@@ -312,6 +535,19 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
312
535
|
isRunning = false; // Track if component is currently running
|
|
313
536
|
// Error handling
|
|
314
537
|
currentError = null;
|
|
538
|
+
// Tab management
|
|
539
|
+
activeTab = 0; // 0 = Spec, 1 = Code
|
|
540
|
+
// Splitter state
|
|
541
|
+
isDetailsPaneCollapsed = true; // Start with details collapsed
|
|
542
|
+
// Editor content
|
|
543
|
+
editableSpec = ''; // JSON string for spec editor
|
|
544
|
+
editableCode = ''; // JavaScript code for code editor
|
|
545
|
+
codeSections = [];
|
|
546
|
+
isEditingSpec = false;
|
|
547
|
+
isEditingCode = false;
|
|
548
|
+
lastEditSource = null;
|
|
549
|
+
// File input element reference
|
|
550
|
+
fileInput;
|
|
315
551
|
destroy$ = new Subject();
|
|
316
552
|
constructor(cdr) {
|
|
317
553
|
super();
|
|
@@ -341,7 +577,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
341
577
|
});
|
|
342
578
|
if (result.Success) {
|
|
343
579
|
this.components = result.Results || [];
|
|
344
|
-
this.
|
|
580
|
+
this.combineAndFilterComponents();
|
|
345
581
|
}
|
|
346
582
|
else {
|
|
347
583
|
console.error('Failed to load components:', result.ErrorMessage);
|
|
@@ -356,23 +592,67 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
356
592
|
}
|
|
357
593
|
onSearchChange(query) {
|
|
358
594
|
this.searchQuery = query;
|
|
359
|
-
this.
|
|
595
|
+
this.combineAndFilterComponents();
|
|
360
596
|
}
|
|
361
|
-
|
|
362
|
-
//
|
|
597
|
+
combineAndFilterComponents() {
|
|
598
|
+
// Combine database components with file-loaded components
|
|
599
|
+
this.allComponents = [
|
|
600
|
+
...this.fileLoadedComponents,
|
|
601
|
+
...this.components
|
|
602
|
+
];
|
|
603
|
+
// Apply search filter
|
|
363
604
|
if (!this.searchQuery) {
|
|
364
|
-
this.filteredComponents = [...this.
|
|
605
|
+
this.filteredComponents = [...this.allComponents];
|
|
365
606
|
}
|
|
366
607
|
else {
|
|
367
608
|
const query = this.searchQuery.toLowerCase();
|
|
368
|
-
this.filteredComponents = this.
|
|
369
|
-
c
|
|
370
|
-
c
|
|
609
|
+
this.filteredComponents = this.allComponents.filter(c => {
|
|
610
|
+
const name = this.getComponentName(c)?.toLowerCase() || '';
|
|
611
|
+
const description = this.getComponentDescription(c)?.toLowerCase() || '';
|
|
612
|
+
const type = this.getComponentType(c)?.toLowerCase() || '';
|
|
613
|
+
return name.includes(query) || description.includes(query) || type.includes(query);
|
|
614
|
+
});
|
|
371
615
|
}
|
|
372
616
|
}
|
|
617
|
+
// Helper methods to get properties from union type
|
|
618
|
+
getComponentName(component) {
|
|
619
|
+
return component.isFileLoaded ? component.name : component.Name;
|
|
620
|
+
}
|
|
621
|
+
getComponentDescription(component) {
|
|
622
|
+
return component.isFileLoaded ? component.description : (component.Description || undefined);
|
|
623
|
+
}
|
|
624
|
+
getComponentType(component) {
|
|
625
|
+
return component.isFileLoaded ? component.type : (component.Type || undefined);
|
|
626
|
+
}
|
|
627
|
+
getComponentStatus(component) {
|
|
628
|
+
return component.isFileLoaded ? component.status : (component.Status || undefined);
|
|
629
|
+
}
|
|
630
|
+
getComponentVersion(component) {
|
|
631
|
+
return component.isFileLoaded ? '1.0.0' : (component.Version || '1.0.0');
|
|
632
|
+
}
|
|
633
|
+
getComponentSpec(component) {
|
|
634
|
+
return component.isFileLoaded ? component.specification : JSON.parse(component.Specification);
|
|
635
|
+
}
|
|
636
|
+
getComponentId(component) {
|
|
637
|
+
return component.isFileLoaded ? component.id : component.ID;
|
|
638
|
+
}
|
|
639
|
+
isFileLoadedComponent(component) {
|
|
640
|
+
return component.isFileLoaded === true;
|
|
641
|
+
}
|
|
642
|
+
getComponentFilename(component) {
|
|
643
|
+
return component.isFileLoaded ? component.filename : undefined;
|
|
644
|
+
}
|
|
645
|
+
getComponentLoadedAt(component) {
|
|
646
|
+
return component.isFileLoaded ? component.loadedAt : undefined;
|
|
647
|
+
}
|
|
648
|
+
getComponentUpdatedAt(component) {
|
|
649
|
+
return !component.isFileLoaded && component.__mj_UpdatedAt ? component.__mj_UpdatedAt : undefined;
|
|
650
|
+
}
|
|
373
651
|
toggleComponentExpansion(component) {
|
|
374
652
|
// Toggle expansion - if clicking the same component, collapse it
|
|
375
|
-
|
|
653
|
+
const componentId = this.getComponentId(component);
|
|
654
|
+
const expandedId = this.expandedComponent ? this.getComponentId(this.expandedComponent) : null;
|
|
655
|
+
if (expandedId === componentId) {
|
|
376
656
|
this.expandedComponent = null;
|
|
377
657
|
}
|
|
378
658
|
else {
|
|
@@ -382,7 +662,9 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
382
662
|
}
|
|
383
663
|
runComponent(component) {
|
|
384
664
|
// If another component is running, stop it first then start the new one
|
|
385
|
-
|
|
665
|
+
const componentId = this.getComponentId(component);
|
|
666
|
+
const selectedId = this.selectedComponent ? this.getComponentId(this.selectedComponent) : null;
|
|
667
|
+
if (this.isRunning && selectedId !== componentId) {
|
|
386
668
|
this.stopComponent();
|
|
387
669
|
this.startComponent(component);
|
|
388
670
|
}
|
|
@@ -392,10 +674,12 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
392
674
|
}
|
|
393
675
|
startComponent(component) {
|
|
394
676
|
this.selectedComponent = component;
|
|
395
|
-
this.componentSpec =
|
|
677
|
+
this.componentSpec = this.getComponentSpec(component);
|
|
396
678
|
this.isRunning = true;
|
|
397
679
|
this.currentError = null; // Clear any previous errors
|
|
398
|
-
|
|
680
|
+
this.isDetailsPaneCollapsed = true; // Start with details collapsed
|
|
681
|
+
this.initializeEditors(); // Initialize spec and code editors
|
|
682
|
+
console.log('Running component:', this.getComponentName(component));
|
|
399
683
|
try {
|
|
400
684
|
this.cdr.detectChanges();
|
|
401
685
|
}
|
|
@@ -458,7 +742,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
458
742
|
const errorText = `
|
|
459
743
|
Component Error Report
|
|
460
744
|
${'='.repeat(50)}
|
|
461
|
-
Component: ${this.selectedComponent
|
|
745
|
+
Component: ${this.selectedComponent ? this.getComponentName(this.selectedComponent) : 'Unknown'}
|
|
462
746
|
Error Type: ${this.currentError.type}
|
|
463
747
|
Message: ${this.currentError.message}
|
|
464
748
|
${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify(this.currentError.technicalDetails, null, 2) : ''}
|
|
@@ -483,6 +767,81 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
|
|
|
483
767
|
async refreshData() {
|
|
484
768
|
await this.loadData();
|
|
485
769
|
}
|
|
770
|
+
// File upload handling methods
|
|
771
|
+
triggerFileInput() {
|
|
772
|
+
this.fileInput?.nativeElement.click();
|
|
773
|
+
}
|
|
774
|
+
async handleFileSelect(event) {
|
|
775
|
+
const input = event.target;
|
|
776
|
+
const file = input.files?.[0];
|
|
777
|
+
if (!file)
|
|
778
|
+
return;
|
|
779
|
+
// Only accept JSON files
|
|
780
|
+
if (!file.name.endsWith('.json')) {
|
|
781
|
+
console.error('Please select a JSON file');
|
|
782
|
+
// Could add a toast notification here
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
try {
|
|
786
|
+
const fileContent = await this.readFile(file);
|
|
787
|
+
const spec = JSON.parse(fileContent);
|
|
788
|
+
// Validate the spec has required fields
|
|
789
|
+
if (!spec.name || !spec.code) {
|
|
790
|
+
console.error('Invalid component specification: missing required fields (name, code)');
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
// Create a file-loaded component
|
|
794
|
+
const fileComponent = {
|
|
795
|
+
id: this.generateId(),
|
|
796
|
+
name: spec.name,
|
|
797
|
+
description: spec.description,
|
|
798
|
+
specification: spec,
|
|
799
|
+
filename: file.name,
|
|
800
|
+
loadedAt: new Date(),
|
|
801
|
+
isFileLoaded: true,
|
|
802
|
+
type: spec.type || 'Component',
|
|
803
|
+
status: 'File'
|
|
804
|
+
};
|
|
805
|
+
// Add to the list and refresh
|
|
806
|
+
this.fileLoadedComponents.push(fileComponent);
|
|
807
|
+
this.combineAndFilterComponents();
|
|
808
|
+
console.log(`Loaded component "${spec.name}" from ${file.name}`);
|
|
809
|
+
// Automatically select and run the newly loaded component
|
|
810
|
+
this.expandedComponent = fileComponent;
|
|
811
|
+
this.runComponent(fileComponent);
|
|
812
|
+
// Clear the input for future uploads
|
|
813
|
+
input.value = '';
|
|
814
|
+
}
|
|
815
|
+
catch (error) {
|
|
816
|
+
console.error('Error loading component file:', error);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
readFile(file) {
|
|
820
|
+
return new Promise((resolve, reject) => {
|
|
821
|
+
const reader = new FileReader();
|
|
822
|
+
reader.onload = (e) => resolve(e.target?.result);
|
|
823
|
+
reader.onerror = reject;
|
|
824
|
+
reader.readAsText(file);
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
generateId() {
|
|
828
|
+
return 'file-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
|
|
829
|
+
}
|
|
830
|
+
removeFileComponent(component) {
|
|
831
|
+
const index = this.fileLoadedComponents.indexOf(component);
|
|
832
|
+
if (index > -1) {
|
|
833
|
+
this.fileLoadedComponents.splice(index, 1);
|
|
834
|
+
// If this was the selected component, clear it
|
|
835
|
+
if (this.selectedComponent === component) {
|
|
836
|
+
this.stopComponent();
|
|
837
|
+
}
|
|
838
|
+
// If this was the expanded component, clear it
|
|
839
|
+
if (this.expandedComponent === component) {
|
|
840
|
+
this.expandedComponent = null;
|
|
841
|
+
}
|
|
842
|
+
this.combineAndFilterComponents();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
486
845
|
getComponentTypeIcon(type) {
|
|
487
846
|
const icons = {
|
|
488
847
|
'Report': 'fa-file-alt',
|
|
@@ -511,47 +870,286 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
|
|
|
511
870
|
};
|
|
512
871
|
return colors[type || ''] || '#9CA3AF';
|
|
513
872
|
}
|
|
873
|
+
/**
|
|
874
|
+
* Initialize the spec and code editors when a component is selected
|
|
875
|
+
*/
|
|
876
|
+
initializeEditors() {
|
|
877
|
+
if (this.selectedComponent) {
|
|
878
|
+
const spec = this.getComponentSpec(this.selectedComponent);
|
|
879
|
+
// Deep parse the spec for better readability
|
|
880
|
+
const parseOptions = {
|
|
881
|
+
extractInlineJson: true,
|
|
882
|
+
maxDepth: 100,
|
|
883
|
+
debug: false
|
|
884
|
+
};
|
|
885
|
+
const parsed = ParseJSONRecursive(spec, parseOptions);
|
|
886
|
+
this.editableSpec = JSON.stringify(parsed, null, 2);
|
|
887
|
+
// Extract code from spec
|
|
888
|
+
this.editableCode = spec.code || '// No code available';
|
|
889
|
+
// Build code sections array
|
|
890
|
+
this.buildCodeSections();
|
|
891
|
+
// Reset editing flags
|
|
892
|
+
this.isEditingSpec = false;
|
|
893
|
+
this.isEditingCode = false;
|
|
894
|
+
this.lastEditSource = null;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Handle spec editor changes
|
|
899
|
+
*/
|
|
900
|
+
onSpecChange(newSpec) {
|
|
901
|
+
this.editableSpec = newSpec;
|
|
902
|
+
this.isEditingSpec = true;
|
|
903
|
+
this.lastEditSource = 'spec';
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Handle code editor changes
|
|
907
|
+
*/
|
|
908
|
+
onCodeChange(newCode) {
|
|
909
|
+
this.editableCode = newCode;
|
|
910
|
+
this.isEditingCode = true;
|
|
911
|
+
this.lastEditSource = 'code';
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Apply spec changes and update the code tab
|
|
915
|
+
*/
|
|
916
|
+
applySpecChanges() {
|
|
917
|
+
try {
|
|
918
|
+
const parsed = JSON.parse(this.editableSpec);
|
|
919
|
+
// Update the component spec
|
|
920
|
+
if (this.selectedComponent) {
|
|
921
|
+
if (this.isFileLoadedComponent(this.selectedComponent)) {
|
|
922
|
+
// Update file-loaded component
|
|
923
|
+
this.selectedComponent.specification = parsed;
|
|
924
|
+
}
|
|
925
|
+
else {
|
|
926
|
+
// Update database component's Specification field in memory only
|
|
927
|
+
this.selectedComponent.Specification = JSON.stringify(parsed);
|
|
928
|
+
}
|
|
929
|
+
// Update the runtime spec
|
|
930
|
+
this.componentSpec = parsed;
|
|
931
|
+
// Update the code editor with new code from spec
|
|
932
|
+
this.editableCode = parsed.code || '// No code available';
|
|
933
|
+
// Rebuild code sections from updated spec
|
|
934
|
+
this.buildCodeSections();
|
|
935
|
+
// If component is running, update it without full refresh
|
|
936
|
+
if (this.isRunning) {
|
|
937
|
+
this.updateRunningComponent();
|
|
938
|
+
}
|
|
939
|
+
this.isEditingSpec = false;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
catch (error) {
|
|
943
|
+
console.error('Invalid JSON in spec editor:', error);
|
|
944
|
+
// Could show a toast notification here
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Apply code changes and update the spec
|
|
949
|
+
*/
|
|
950
|
+
applyCodeChanges() {
|
|
951
|
+
if (this.selectedComponent) {
|
|
952
|
+
try {
|
|
953
|
+
// Parse the current spec
|
|
954
|
+
const spec = JSON.parse(this.editableSpec);
|
|
955
|
+
// Update main code and dependencies from code sections
|
|
956
|
+
if (this.codeSections.length > 0) {
|
|
957
|
+
// First section is always the main component
|
|
958
|
+
spec.code = this.codeSections[0].code;
|
|
959
|
+
// Update dependencies if any
|
|
960
|
+
if (this.codeSections.length > 1 && spec.dependencies) {
|
|
961
|
+
for (let i = 1; i < this.codeSections.length; i++) {
|
|
962
|
+
const section = this.codeSections[i];
|
|
963
|
+
if (section.index !== undefined && spec.dependencies[section.index]) {
|
|
964
|
+
spec.dependencies[section.index].code = section.code;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
// Update the spec editor
|
|
970
|
+
const parseOptions = {
|
|
971
|
+
extractInlineJson: true,
|
|
972
|
+
maxDepth: 100,
|
|
973
|
+
debug: false
|
|
974
|
+
};
|
|
975
|
+
const parsed = ParseJSONRecursive(spec, parseOptions);
|
|
976
|
+
this.editableSpec = JSON.stringify(parsed, null, 2);
|
|
977
|
+
// Update the component entity in memory
|
|
978
|
+
if (this.isFileLoadedComponent(this.selectedComponent)) {
|
|
979
|
+
this.selectedComponent.specification = spec;
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
// Update database component's Specification field in memory only
|
|
983
|
+
this.selectedComponent.Specification = JSON.stringify(spec);
|
|
984
|
+
}
|
|
985
|
+
// Update the runtime spec
|
|
986
|
+
this.componentSpec = spec;
|
|
987
|
+
// If component is running, update it without full refresh
|
|
988
|
+
if (this.isRunning) {
|
|
989
|
+
this.updateRunningComponent();
|
|
990
|
+
}
|
|
991
|
+
this.isEditingCode = false;
|
|
992
|
+
}
|
|
993
|
+
catch (error) {
|
|
994
|
+
console.error('Error applying code changes:', error);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Refresh the running component with new spec/code (in-place update)
|
|
1000
|
+
*/
|
|
1001
|
+
refreshComponent() {
|
|
1002
|
+
if (this.selectedComponent && this.isRunning) {
|
|
1003
|
+
// Use the same in-place update logic as Apply Changes
|
|
1004
|
+
this.updateRunningComponent();
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Update the running component without full refresh
|
|
1009
|
+
*/
|
|
1010
|
+
updateRunningComponent() {
|
|
1011
|
+
if (this.selectedComponent && this.isRunning) {
|
|
1012
|
+
// Get the updated spec
|
|
1013
|
+
const spec = this.getComponentSpec(this.selectedComponent);
|
|
1014
|
+
// Temporarily set to null to force React to re-render
|
|
1015
|
+
this.componentSpec = null;
|
|
1016
|
+
this.cdr.detectChanges();
|
|
1017
|
+
// Then set the new spec
|
|
1018
|
+
setTimeout(() => {
|
|
1019
|
+
this.componentSpec = spec;
|
|
1020
|
+
try {
|
|
1021
|
+
this.cdr.detectChanges();
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
console.error('Error with cdr.detectChanges():', error);
|
|
1025
|
+
}
|
|
1026
|
+
}, 10);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Build code sections array from spec
|
|
1031
|
+
*/
|
|
1032
|
+
buildCodeSections() {
|
|
1033
|
+
if (!this.selectedComponent) {
|
|
1034
|
+
this.codeSections = [];
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const spec = this.getComponentSpec(this.selectedComponent);
|
|
1038
|
+
const sections = [];
|
|
1039
|
+
// Main component code
|
|
1040
|
+
sections.push({
|
|
1041
|
+
title: spec.name || 'Main Component',
|
|
1042
|
+
code: spec.code || '// No code available',
|
|
1043
|
+
expanded: true,
|
|
1044
|
+
isDependency: false
|
|
1045
|
+
});
|
|
1046
|
+
// Add dependent components if any
|
|
1047
|
+
if (spec.dependencies && Array.isArray(spec.dependencies)) {
|
|
1048
|
+
spec.dependencies.forEach((dep, index) => {
|
|
1049
|
+
sections.push({
|
|
1050
|
+
title: dep.name || `Dependency ${index + 1}`,
|
|
1051
|
+
code: dep.code || '// No code available',
|
|
1052
|
+
expanded: false,
|
|
1053
|
+
isDependency: true,
|
|
1054
|
+
index: index
|
|
1055
|
+
});
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
this.codeSections = sections;
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Get component code sections for panel bar
|
|
1062
|
+
*/
|
|
1063
|
+
getComponentCodeSections() {
|
|
1064
|
+
return this.codeSections;
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Handle code section changes
|
|
1068
|
+
*/
|
|
1069
|
+
onCodeSectionChange(newCode, sectionIndex) {
|
|
1070
|
+
if (this.codeSections[sectionIndex]) {
|
|
1071
|
+
this.codeSections[sectionIndex].code = newCode;
|
|
1072
|
+
this.isEditingCode = true;
|
|
1073
|
+
this.lastEditSource = 'code';
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Toggle the details pane (spec/code editors)
|
|
1078
|
+
*/
|
|
1079
|
+
toggleDetailsPane() {
|
|
1080
|
+
this.isDetailsPaneCollapsed = !this.isDetailsPaneCollapsed;
|
|
1081
|
+
this.cdr.detectChanges();
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Handle tab selection
|
|
1085
|
+
*/
|
|
1086
|
+
onTabSelect(event) {
|
|
1087
|
+
this.activeTab = event.index;
|
|
1088
|
+
// Initialize editors when switching to spec or code tabs
|
|
1089
|
+
// Both tabs now need initialization since there's no separate Run tab
|
|
1090
|
+
this.initializeEditors();
|
|
1091
|
+
}
|
|
514
1092
|
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"]],
|
|
516
|
-
i0.ɵɵ
|
|
517
|
-
|
|
1093
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentStudioDashboardComponent, selectors: [["mj-component-studio-dashboard"]], viewQuery: function ComponentStudioDashboardComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1094
|
+
i0.ɵɵviewQuery(_c0, 5);
|
|
1095
|
+
} if (rf & 2) {
|
|
1096
|
+
let _t;
|
|
1097
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fileInput = _t.first);
|
|
1098
|
+
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 36, vars: 11, 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"], ["kendoButton", "", 3, "click", "themeColor"], [1, "fa-solid", "fa-file-import"], ["kendoButton", "", 3, "click", "disabled"], [1, "fa-solid", "fa-sync"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], ["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"], ["orientation", "horizontal", 1, "component-editor-splitter"], [1, "empty-state"], [1, "fa-solid", "fa-eye"], [1, "fa-solid", "fa-eye-slash"], [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, "card-info"], [1, "card-name"], [1, "file-badge", 3, "title"], [1, "card-meta"], [1, "card-type"], [1, "card-version"], [1, "status-badge", "file"], [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, "fa-solid", "fa-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, "min", "collapsible", "size"], [1, "component-runtime"], [1, "run-empty-state"], [3, "min", "collapsible", "collapsed"], [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, "fa-solid", "fa-times"], [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) {
|
|
1099
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
1100
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div")(4, "h1");
|
|
1101
|
+
i0.ɵɵelement(5, "i", 4);
|
|
518
1102
|
i0.ɵɵtext(6, " Component Studio");
|
|
519
1103
|
i0.ɵɵelementEnd();
|
|
520
|
-
i0.ɵɵelementStart(7, "p",
|
|
1104
|
+
i0.ɵɵelementStart(7, "p", 5);
|
|
521
1105
|
i0.ɵɵtext(8, "Testing components without custom properties");
|
|
522
1106
|
i0.ɵɵelementEnd()();
|
|
523
|
-
i0.ɵɵelementStart(9, "
|
|
524
|
-
i0.ɵɵ
|
|
525
|
-
i0.ɵɵ
|
|
526
|
-
i0.ɵɵ
|
|
1107
|
+
i0.ɵɵelementStart(9, "div", 6);
|
|
1108
|
+
i0.ɵɵtemplate(10, ComponentStudioDashboardComponent_Conditional_10_Template, 3, 2, "button", 7);
|
|
1109
|
+
i0.ɵɵelementStart(11, "button", 8);
|
|
1110
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.triggerFileInput()); });
|
|
1111
|
+
i0.ɵɵelement(12, "span", 9);
|
|
1112
|
+
i0.ɵɵtext(13, " Import from File ");
|
|
1113
|
+
i0.ɵɵelementEnd();
|
|
1114
|
+
i0.ɵɵelementStart(14, "button", 10);
|
|
1115
|
+
i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.refreshData()); });
|
|
1116
|
+
i0.ɵɵelement(15, "span", 11);
|
|
1117
|
+
i0.ɵɵtext(16, " Refresh ");
|
|
1118
|
+
i0.ɵɵelementEnd()();
|
|
1119
|
+
i0.ɵɵelementStart(17, "input", 12, 0);
|
|
1120
|
+
i0.ɵɵlistener("change", function ComponentStudioDashboardComponent_Template_input_change_17_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.handleFileSelect($event)); });
|
|
527
1121
|
i0.ɵɵelementEnd()()();
|
|
528
|
-
i0.ɵɵelementStart(
|
|
529
|
-
i0.ɵɵtext(
|
|
1122
|
+
i0.ɵɵelementStart(19, "kendo-splitter", 13)(20, "kendo-splitter-pane", 14)(21, "div", 15)(22, "div", 16)(23, "h3");
|
|
1123
|
+
i0.ɵɵtext(24, "Components");
|
|
530
1124
|
i0.ɵɵelementEnd();
|
|
531
|
-
i0.ɵɵelementStart(
|
|
532
|
-
i0.ɵɵlistener("valueChange", function
|
|
533
|
-
i0.ɵɵtemplate(
|
|
1125
|
+
i0.ɵɵelementStart(25, "div", 17)(26, "kendo-textbox", 18);
|
|
1126
|
+
i0.ɵɵlistener("valueChange", function ComponentStudioDashboardComponent_Template_kendo_textbox_valueChange_26_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearchChange($event)); });
|
|
1127
|
+
i0.ɵɵtemplate(27, ComponentStudioDashboardComponent_ng_template_27_Template, 1, 0, "ng-template", 19);
|
|
534
1128
|
i0.ɵɵelementEnd()()();
|
|
535
|
-
i0.ɵɵelementStart(
|
|
536
|
-
i0.ɵɵtemplate(
|
|
1129
|
+
i0.ɵɵelementStart(28, "div", 20);
|
|
1130
|
+
i0.ɵɵtemplate(29, ComponentStudioDashboardComponent_Conditional_29_Template, 3, 0, "div", 21)(30, ComponentStudioDashboardComponent_Conditional_30_Template, 6, 0, "div", 22)(31, ComponentStudioDashboardComponent_Conditional_31_Template, 2, 0);
|
|
537
1131
|
i0.ɵɵelementEnd()()();
|
|
538
|
-
i0.ɵɵelementStart(
|
|
539
|
-
i0.ɵɵtemplate(
|
|
1132
|
+
i0.ɵɵelementStart(32, "kendo-splitter-pane", 23)(33, "div", 24);
|
|
1133
|
+
i0.ɵɵtemplate(34, ComponentStudioDashboardComponent_Conditional_34_Template, 11, 11, "kendo-splitter", 25)(35, ComponentStudioDashboardComponent_Conditional_35_Template, 6, 0, "div", 26);
|
|
540
1134
|
i0.ɵɵelementEnd()()()();
|
|
541
1135
|
} if (rf & 2) {
|
|
542
|
-
i0.ɵɵadvance(
|
|
1136
|
+
i0.ɵɵadvance(10);
|
|
1137
|
+
i0.ɵɵconditional(ctx.selectedComponent && ctx.isRunning ? 10 : -1);
|
|
1138
|
+
i0.ɵɵadvance();
|
|
1139
|
+
i0.ɵɵproperty("themeColor", "info");
|
|
1140
|
+
i0.ɵɵadvance(3);
|
|
543
1141
|
i0.ɵɵproperty("disabled", ctx.isLoading);
|
|
544
|
-
i0.ɵɵadvance(
|
|
1142
|
+
i0.ɵɵadvance(6);
|
|
545
1143
|
i0.ɵɵproperty("min", "350px")("max", "600px")("size", "400px");
|
|
546
1144
|
i0.ɵɵadvance(6);
|
|
547
1145
|
i0.ɵɵproperty("value", ctx.searchQuery)("clearButton", true);
|
|
548
1146
|
i0.ɵɵadvance(3);
|
|
549
|
-
i0.ɵɵconditional(ctx.isLoading ?
|
|
1147
|
+
i0.ɵɵconditional(ctx.isLoading ? 29 : ctx.filteredComponents.length === 0 ? 30 : 31);
|
|
550
1148
|
i0.ɵɵadvance(3);
|
|
551
1149
|
i0.ɵɵproperty("min", "400px");
|
|
552
1150
|
i0.ɵɵadvance(2);
|
|
553
|
-
i0.ɵɵconditional(ctx.
|
|
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}"] });
|
|
1151
|
+
i0.ɵɵconditional(ctx.selectedComponent ? 34 : 35);
|
|
1152
|
+
} }, dependencies: [i1.NgClass, i2.NgControlStatus, i2.NgModel, i3.TextBoxComponent, i3.TextBoxPrefixTemplateDirective, i4.PanelBarComponent, i4.PanelBarItemComponent, i4.PanelBarContentDirective, i4.SplitterComponent, i4.SplitterPaneComponent, i4.TabStripComponent, i4.TabStripTabComponent, i4.TabContentDirective, i5.CodeEditorComponent, i6.ButtonComponent, i7.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: 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 \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 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 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 .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 }\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 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@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}"] });
|
|
555
1153
|
};
|
|
556
1154
|
ComponentStudioDashboardComponent = __decorate([
|
|
557
1155
|
RegisterClass(BaseDashboard, 'ComponentStudioDashboard')
|
|
@@ -559,9 +1157,12 @@ ComponentStudioDashboardComponent = __decorate([
|
|
|
559
1157
|
export { ComponentStudioDashboardComponent };
|
|
560
1158
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentStudioDashboardComponent, [{
|
|
561
1159
|
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 }],
|
|
564
|
-
|
|
1160
|
+
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 <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 <button kendoButton (click)=\"triggerFileInput()\" [themeColor]=\"'info'\">\n <span class=\"fa-solid fa-file-import\"></span> Import from File\n </button>\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\" 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 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 <div class=\"card-info\">\n <div class=\"card-name\">\n {{ getComponentName(component) }}\n @if (isFileLoadedComponent(component)) {\n <span class=\"file-badge\" title=\"Loaded from {{ getComponentFilename(component) }}\">\n <i class=\"fa-solid fa-file\"></i> {{ getComponentFilename(component) }}\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 <span class=\"status-badge file\">File</span>\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 </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 <!-- Splitter for component and editors -->\n <kendo-splitter orientation=\"horizontal\" class=\"component-editor-splitter\">\n <!-- Left side - Running Component -->\n <kendo-splitter-pane [min]=\"'300px'\" [collapsible]=\"false\" [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 </kendo-splitter-pane>\n \n <!-- Right side - Spec and Code Editors -->\n <kendo-splitter-pane [min]=\"'400px'\" [collapsible]=\"true\" [collapsed]=\"isDetailsPaneCollapsed\">\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 </kendo-splitter-pane>\n </kendo-splitter>\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 \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 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 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 .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 }\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@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}"] }]
|
|
1161
|
+
}], () => [{ type: i0.ChangeDetectorRef }], { fileInput: [{
|
|
1162
|
+
type: ViewChild,
|
|
1163
|
+
args: ['fileInput', { static: false }]
|
|
1164
|
+
}] }); })();
|
|
1165
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentStudioDashboardComponent, { className: "ComponentStudioDashboardComponent", filePath: "src/ComponentStudio/component-studio-dashboard.component.ts", lineNumber: 35 }); })();
|
|
565
1166
|
/**
|
|
566
1167
|
* Function to prevent tree shaking of the ComponentStudioDashboardComponent.
|
|
567
1168
|
*/
|