@memberjunction/ng-dashboards 2.87.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 +106 -9
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +809 -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,214 +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.ɵɵ
|
|
54
|
+
function ComponentStudioDashboardComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
55
|
+
i0.ɵɵelementStart(0, "div", 22);
|
|
56
|
+
i0.ɵɵelement(1, "i", 31);
|
|
57
|
+
i0.ɵɵtext(2, " No components found without custom properties. ");
|
|
58
|
+
i0.ɵɵelement(3, "br");
|
|
59
|
+
i0.ɵɵelementStart(4, "small");
|
|
60
|
+
i0.ɵɵtext(5, "Only components that don't require custom props can be tested here.");
|
|
61
|
+
i0.ɵɵelementEnd()();
|
|
62
|
+
} }
|
|
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);
|
|
32
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), " ");
|
|
33
74
|
} }
|
|
34
|
-
function
|
|
35
|
-
i0.ɵɵelementStart(0, "span",
|
|
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);
|
|
36
82
|
i0.ɵɵtext(1, "Published");
|
|
37
83
|
i0.ɵɵelementEnd();
|
|
38
84
|
} }
|
|
39
|
-
function
|
|
40
|
-
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);
|
|
41
87
|
i0.ɵɵtext(1, "Draft");
|
|
42
88
|
i0.ɵɵelementEnd();
|
|
43
89
|
} }
|
|
44
|
-
function
|
|
45
|
-
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);
|
|
46
92
|
} }
|
|
47
|
-
function
|
|
48
|
-
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);
|
|
49
95
|
} }
|
|
50
|
-
function
|
|
51
|
-
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");
|
|
52
98
|
i0.ɵɵtext(2, "Description");
|
|
53
99
|
i0.ɵɵelementEnd();
|
|
54
100
|
i0.ɵɵelementStart(3, "p");
|
|
55
101
|
i0.ɵɵtext(4);
|
|
56
102
|
i0.ɵɵelementEnd()();
|
|
57
103
|
} if (rf & 2) {
|
|
58
|
-
const
|
|
104
|
+
const component_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
105
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
59
106
|
i0.ɵɵadvance(4);
|
|
60
|
-
i0.ɵɵtextInterpolate(
|
|
107
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(component_r5));
|
|
61
108
|
} }
|
|
62
|
-
function
|
|
63
|
-
i0.ɵɵelementStart(0, "div",
|
|
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);
|
|
120
|
+
i0.ɵɵadvance(4);
|
|
121
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentLoadedAt(component_r5), "short"));
|
|
122
|
+
} }
|
|
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);
|
|
64
125
|
i0.ɵɵtext(2, "Updated:");
|
|
65
126
|
i0.ɵɵelementEnd();
|
|
66
|
-
i0.ɵɵelementStart(3, "span",
|
|
127
|
+
i0.ɵɵelementStart(3, "span", 55);
|
|
67
128
|
i0.ɵɵtext(4);
|
|
68
129
|
i0.ɵɵpipe(5, "date");
|
|
69
130
|
i0.ɵɵelementEnd()();
|
|
70
131
|
} if (rf & 2) {
|
|
71
|
-
const
|
|
132
|
+
const component_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
133
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
72
134
|
i0.ɵɵadvance(4);
|
|
73
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1,
|
|
135
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 1, ctx_r2.getComponentUpdatedAt(component_r5), "short"));
|
|
74
136
|
} }
|
|
75
|
-
function
|
|
76
|
-
const
|
|
77
|
-
i0.ɵɵelementStart(0, "button",
|
|
78
|
-
i0.ɵɵlistener("click", function
|
|
79
|
-
i0.ɵɵ
|
|
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);
|
|
142
|
+
i0.ɵɵtext(2, " Stop Component ");
|
|
80
143
|
i0.ɵɵelementEnd();
|
|
81
144
|
} if (rf & 2) {
|
|
82
|
-
i0.ɵɵproperty("
|
|
145
|
+
i0.ɵɵproperty("themeColor", "error");
|
|
83
146
|
} }
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
i0.ɵɵelementStart(0, "button",
|
|
87
|
-
i0.ɵɵlistener("click", function
|
|
88
|
-
i0.ɵɵ
|
|
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);
|
|
152
|
+
i0.ɵɵtext(2, " Switch to This Component ");
|
|
153
|
+
i0.ɵɵelementEnd();
|
|
154
|
+
} if (rf & 2) {
|
|
155
|
+
i0.ɵɵproperty("themeColor", "base");
|
|
156
|
+
} }
|
|
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);
|
|
162
|
+
i0.ɵɵtext(2, " Run Component ");
|
|
89
163
|
i0.ɵɵelementEnd();
|
|
90
164
|
} if (rf & 2) {
|
|
91
|
-
i0.ɵɵproperty("
|
|
165
|
+
i0.ɵɵproperty("themeColor", "primary");
|
|
92
166
|
} }
|
|
93
|
-
function
|
|
94
|
-
i0.ɵɵelementStart(0, "div",
|
|
95
|
-
i0.ɵɵtemplate(1,
|
|
96
|
-
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");
|
|
97
171
|
i0.ɵɵtext(4, "Component Info");
|
|
98
172
|
i0.ɵɵelementEnd();
|
|
99
|
-
i0.ɵɵelementStart(5, "div",
|
|
173
|
+
i0.ɵɵelementStart(5, "div", 52)(6, "div", 53)(7, "span", 54);
|
|
100
174
|
i0.ɵɵtext(8, "Type:");
|
|
101
175
|
i0.ɵɵelementEnd();
|
|
102
|
-
i0.ɵɵelementStart(9, "span",
|
|
176
|
+
i0.ɵɵelementStart(9, "span", 55);
|
|
103
177
|
i0.ɵɵtext(10);
|
|
104
178
|
i0.ɵɵelementEnd()();
|
|
105
|
-
i0.ɵɵelementStart(11, "div",
|
|
179
|
+
i0.ɵɵelementStart(11, "div", 53)(12, "span", 54);
|
|
106
180
|
i0.ɵɵtext(13, "Version:");
|
|
107
181
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵelementStart(14, "span",
|
|
182
|
+
i0.ɵɵelementStart(14, "span", 55);
|
|
109
183
|
i0.ɵɵtext(15);
|
|
110
184
|
i0.ɵɵelementEnd()();
|
|
111
|
-
i0.ɵɵelementStart(16, "div",
|
|
185
|
+
i0.ɵɵelementStart(16, "div", 53)(17, "span", 54);
|
|
112
186
|
i0.ɵɵtext(18, "Status:");
|
|
113
187
|
i0.ɵɵelementEnd();
|
|
114
|
-
i0.ɵɵelementStart(19, "span",
|
|
188
|
+
i0.ɵɵelementStart(19, "span", 55);
|
|
115
189
|
i0.ɵɵtext(20);
|
|
116
190
|
i0.ɵɵelementEnd()();
|
|
117
|
-
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);
|
|
118
192
|
i0.ɵɵelementEnd()();
|
|
119
|
-
i0.ɵɵelementStart(
|
|
120
|
-
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);
|
|
121
195
|
i0.ɵɵelementEnd()();
|
|
122
196
|
} if (rf & 2) {
|
|
123
|
-
const
|
|
197
|
+
const component_r5 = i0.ɵɵnextContext().$implicit;
|
|
124
198
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
125
199
|
i0.ɵɵadvance();
|
|
126
|
-
i0.ɵɵconditional(
|
|
200
|
+
i0.ɵɵconditional(ctx_r2.getComponentDescription(component_r5) ? 1 : -1);
|
|
127
201
|
i0.ɵɵadvance(9);
|
|
128
|
-
i0.ɵɵtextInterpolate(
|
|
202
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r5) || "Unknown");
|
|
129
203
|
i0.ɵɵadvance(5);
|
|
130
|
-
i0.ɵɵtextInterpolate(
|
|
204
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentVersion(component_r5));
|
|
131
205
|
i0.ɵɵadvance(5);
|
|
132
|
-
i0.ɵɵtextInterpolate(
|
|
206
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentStatus(component_r5) || "Draft");
|
|
133
207
|
i0.ɵɵadvance();
|
|
134
|
-
i0.ɵɵconditional(
|
|
135
|
-
i0.ɵɵadvance(
|
|
136
|
-
i0.ɵɵconditional((ctx_r2.selectedComponent
|
|
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);
|
|
137
211
|
} }
|
|
138
|
-
function
|
|
139
|
-
const
|
|
140
|
-
i0.ɵɵelementStart(0, "div",
|
|
141
|
-
i0.ɵɵlistener("click", function
|
|
142
|
-
i0.ɵɵelementStart(2, "div",
|
|
143
|
-
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);
|
|
144
218
|
i0.ɵɵelementEnd();
|
|
145
|
-
i0.ɵɵelementStart(4, "div",
|
|
219
|
+
i0.ɵɵelementStart(4, "div", 37)(5, "div", 38);
|
|
146
220
|
i0.ɵɵtext(6);
|
|
221
|
+
i0.ɵɵtemplate(7, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_7_Template, 3, 3, "span", 39);
|
|
147
222
|
i0.ɵɵelementEnd();
|
|
148
|
-
i0.ɵɵelementStart(
|
|
149
|
-
i0.ɵɵtext(
|
|
223
|
+
i0.ɵɵelementStart(8, "div", 40)(9, "span", 41);
|
|
224
|
+
i0.ɵɵtext(10);
|
|
150
225
|
i0.ɵɵelementEnd();
|
|
151
|
-
i0.ɵɵelementStart(
|
|
152
|
-
i0.ɵɵtext(
|
|
226
|
+
i0.ɵɵelementStart(11, "span", 42);
|
|
227
|
+
i0.ɵɵtext(12);
|
|
153
228
|
i0.ɵɵelementEnd();
|
|
154
|
-
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);
|
|
155
230
|
i0.ɵɵelementEnd()();
|
|
156
|
-
i0.ɵɵelementStart(
|
|
157
|
-
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);
|
|
158
233
|
i0.ɵɵelementEnd()();
|
|
159
|
-
i0.ɵɵtemplate(
|
|
234
|
+
i0.ɵɵtemplate(19, ComponentStudioDashboardComponent_Conditional_31_For_1_Conditional_19_Template, 27, 6, "div", 49);
|
|
160
235
|
i0.ɵɵelementEnd();
|
|
161
236
|
} if (rf & 2) {
|
|
162
|
-
const
|
|
237
|
+
const component_r5 = ctx.$implicit;
|
|
163
238
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
164
|
-
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));
|
|
165
240
|
i0.ɵɵadvance(2);
|
|
166
|
-
i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(
|
|
241
|
+
i0.ɵɵstyleProp("color", ctx_r2.getComponentTypeColor(ctx_r2.getComponentType(component_r5)));
|
|
167
242
|
i0.ɵɵadvance();
|
|
168
|
-
i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(
|
|
243
|
+
i0.ɵɵproperty("ngClass", ctx_r2.getComponentTypeIcon(ctx_r2.getComponentType(component_r5)));
|
|
169
244
|
i0.ɵɵadvance(3);
|
|
170
|
-
i0.ɵɵ
|
|
245
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.getComponentName(component_r5), " ");
|
|
246
|
+
i0.ɵɵadvance();
|
|
247
|
+
i0.ɵɵconditional(ctx_r2.isFileLoadedComponent(component_r5) ? 7 : -1);
|
|
171
248
|
i0.ɵɵadvance(3);
|
|
172
|
-
i0.ɵɵtextInterpolate(
|
|
249
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentType(component_r5) || "Component");
|
|
173
250
|
i0.ɵɵadvance(2);
|
|
174
|
-
i0.ɵɵtextInterpolate1("v",
|
|
251
|
+
i0.ɵɵtextInterpolate1("v", ctx_r2.getComponentVersion(component_r5), "");
|
|
175
252
|
i0.ɵɵadvance();
|
|
176
|
-
i0.ɵɵconditional(
|
|
177
|
-
i0.ɵɵadvance(
|
|
178
|
-
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);
|
|
179
256
|
i0.ɵɵadvance(2);
|
|
180
|
-
i0.ɵɵconditional(
|
|
257
|
+
i0.ɵɵconditional(ctx_r2.expandedComponent && ctx_r2.getComponentId(ctx_r2.expandedComponent) === ctx_r2.getComponentId(component_r5) ? 19 : -1);
|
|
181
258
|
} }
|
|
182
|
-
function
|
|
183
|
-
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);
|
|
184
261
|
} if (rf & 2) {
|
|
185
262
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
186
263
|
i0.ɵɵrepeater(ctx_r2.filteredComponents);
|
|
187
264
|
} }
|
|
188
|
-
function
|
|
189
|
-
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");
|
|
190
267
|
i0.ɵɵtext(2, "Technical Details (click to expand)");
|
|
191
268
|
i0.ɵɵelementEnd();
|
|
192
269
|
i0.ɵɵelementStart(3, "pre");
|
|
193
270
|
i0.ɵɵtext(4);
|
|
194
271
|
i0.ɵɵelementEnd()();
|
|
195
272
|
} if (rf & 2) {
|
|
196
|
-
const ctx_r2 = i0.ɵɵnextContext(
|
|
273
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
197
274
|
i0.ɵɵadvance(4);
|
|
198
275
|
i0.ɵɵtextInterpolate(ctx_r2.formatTechnicalDetails(ctx_r2.currentError.technicalDetails));
|
|
199
276
|
} }
|
|
200
|
-
function
|
|
201
|
-
const
|
|
202
|
-
i0.ɵɵelementStart(0, "div",
|
|
203
|
-
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);
|
|
204
281
|
i0.ɵɵelementStart(4, "h3");
|
|
205
282
|
i0.ɵɵtext(5, "Component Error");
|
|
206
283
|
i0.ɵɵelementEnd();
|
|
207
|
-
i0.ɵɵelementStart(6, "button",
|
|
208
|
-
i0.ɵɵlistener("click", function
|
|
209
|
-
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);
|
|
210
287
|
i0.ɵɵelementEnd()();
|
|
211
|
-
i0.ɵɵelementStart(8, "p",
|
|
288
|
+
i0.ɵɵelementStart(8, "p", 75);
|
|
212
289
|
i0.ɵɵtext(9, " The component could not be rendered due to the following error: ");
|
|
213
290
|
i0.ɵɵelementEnd();
|
|
214
|
-
i0.ɵɵelementStart(10, "div",
|
|
291
|
+
i0.ɵɵelementStart(10, "div", 76)(11, "strong");
|
|
215
292
|
i0.ɵɵtext(12, "Error Type:");
|
|
216
293
|
i0.ɵɵelementEnd();
|
|
217
294
|
i0.ɵɵtext(13);
|
|
@@ -220,9 +297,9 @@ function ComponentStudioDashboardComponent_Conditional_23_Conditional_0_Template
|
|
|
220
297
|
i0.ɵɵtext(16, "Message:");
|
|
221
298
|
i0.ɵɵelementEnd();
|
|
222
299
|
i0.ɵɵtext(17);
|
|
223
|
-
i0.ɵɵtemplate(18,
|
|
300
|
+
i0.ɵɵtemplate(18, ComponentStudioDashboardComponent_Conditional_34_Conditional_3_Conditional_0_Conditional_18_Template, 5, 1, "details", 77);
|
|
224
301
|
i0.ɵɵelementEnd();
|
|
225
|
-
i0.ɵɵelementStart(19, "div",
|
|
302
|
+
i0.ɵɵelementStart(19, "div", 78)(20, "strong");
|
|
226
303
|
i0.ɵɵtext(21, "What to do:");
|
|
227
304
|
i0.ɵɵelementEnd();
|
|
228
305
|
i0.ɵɵelementStart(22, "ol")(23, "li");
|
|
@@ -237,56 +314,218 @@ function ComponentStudioDashboardComponent_Conditional_23_Conditional_0_Template
|
|
|
237
314
|
i0.ɵɵelementStart(29, "li");
|
|
238
315
|
i0.ɵɵtext(30, "Contact your system administrator if the issue persists");
|
|
239
316
|
i0.ɵɵelementEnd()()();
|
|
240
|
-
i0.ɵɵelementStart(31, "div",
|
|
241
|
-
i0.ɵɵlistener("click", function
|
|
242
|
-
i0.ɵɵ
|
|
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);
|
|
320
|
+
i0.ɵɵtext(34, " Retry ");
|
|
243
321
|
i0.ɵɵelementEnd();
|
|
244
|
-
i0.ɵɵelementStart(
|
|
245
|
-
i0.ɵɵlistener("click", function
|
|
246
|
-
i0.ɵɵ
|
|
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);
|
|
325
|
+
i0.ɵɵtext(37, " Stop ");
|
|
247
326
|
i0.ɵɵelementEnd()()()();
|
|
248
327
|
} if (rf & 2) {
|
|
249
|
-
const ctx_r2 = i0.ɵɵnextContext(
|
|
328
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
250
329
|
i0.ɵɵadvance(13);
|
|
251
330
|
i0.ɵɵtextInterpolate1(" ", ctx_r2.currentError.type, "");
|
|
252
331
|
i0.ɵɵadvance(4);
|
|
253
332
|
i0.ɵɵtextInterpolate1(" ", ctx_r2.currentError.message, " ");
|
|
254
333
|
i0.ɵɵadvance();
|
|
255
334
|
i0.ɵɵconditional(ctx_r2.currentError.technicalDetails ? 18 : -1);
|
|
256
|
-
i0.ɵɵadvance(
|
|
257
|
-
i0.ɵɵproperty("
|
|
335
|
+
i0.ɵɵadvance(17);
|
|
336
|
+
i0.ɵɵproperty("themeColor", "error");
|
|
337
|
+
} }
|
|
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)); });
|
|
342
|
+
i0.ɵɵelementEnd();
|
|
343
|
+
} if (rf & 2) {
|
|
344
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
345
|
+
i0.ɵɵproperty("component", ctx_r2.componentSpec);
|
|
346
|
+
} }
|
|
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);
|
|
349
|
+
} if (rf & 2) {
|
|
350
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
351
|
+
i0.ɵɵconditional(ctx_r2.currentError ? 0 : 1);
|
|
352
|
+
} }
|
|
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), "");
|
|
258
372
|
i0.ɵɵadvance(2);
|
|
259
|
-
i0.ɵɵ
|
|
373
|
+
i0.ɵɵtextInterpolate(ctx_r2.getComponentDescription(ctx_r2.selectedComponent) || "No description available");
|
|
374
|
+
i0.ɵɵadvance();
|
|
375
|
+
i0.ɵɵproperty("themeColor", "primary")("size", "large");
|
|
260
376
|
} }
|
|
261
|
-
function
|
|
262
|
-
const
|
|
263
|
-
i0.ɵɵelementStart(0, "
|
|
264
|
-
i0.ɵɵlistener("
|
|
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)");
|
|
265
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()()();
|
|
266
415
|
} if (rf & 2) {
|
|
267
416
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
268
|
-
i0.ɵɵ
|
|
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());
|
|
269
486
|
} }
|
|
270
|
-
function
|
|
271
|
-
|
|
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()()()();
|
|
272
500
|
} if (rf & 2) {
|
|
273
501
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
274
|
-
i0.ɵɵ
|
|
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);
|
|
275
512
|
} }
|
|
276
|
-
function
|
|
277
|
-
i0.ɵɵelementStart(0, "div",
|
|
278
|
-
i0.ɵɵelement(1, "i",
|
|
513
|
+
function ComponentStudioDashboardComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
514
|
+
i0.ɵɵelementStart(0, "div", 26);
|
|
515
|
+
i0.ɵɵelement(1, "i", 99);
|
|
279
516
|
i0.ɵɵelementStart(2, "h2");
|
|
280
517
|
i0.ɵɵtext(3, "Ready to Test Components");
|
|
281
518
|
i0.ɵɵelementEnd();
|
|
282
519
|
i0.ɵɵelementStart(4, "p");
|
|
283
|
-
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");
|
|
284
521
|
i0.ɵɵelementEnd()();
|
|
285
522
|
} }
|
|
286
523
|
let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent extends BaseDashboard {
|
|
287
524
|
cdr;
|
|
288
525
|
// Component data
|
|
289
526
|
components = [];
|
|
527
|
+
fileLoadedComponents = []; // Components loaded from files
|
|
528
|
+
allComponents = []; // Combined list
|
|
290
529
|
filteredComponents = [];
|
|
291
530
|
selectedComponent = null;
|
|
292
531
|
expandedComponent = null; // Track which card is expanded
|
|
@@ -296,6 +535,19 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
296
535
|
isRunning = false; // Track if component is currently running
|
|
297
536
|
// Error handling
|
|
298
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;
|
|
299
551
|
destroy$ = new Subject();
|
|
300
552
|
constructor(cdr) {
|
|
301
553
|
super();
|
|
@@ -318,14 +570,14 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
318
570
|
const rv = new RunView();
|
|
319
571
|
const result = await rv.RunView({
|
|
320
572
|
EntityName: 'MJ: Components',
|
|
321
|
-
ExtraFilter: '',
|
|
573
|
+
ExtraFilter: 'HasCustomProps = 0', // Only load components without custom props
|
|
322
574
|
OrderBy: 'Name',
|
|
323
575
|
MaxRows: 1000,
|
|
324
576
|
ResultType: 'entity_object'
|
|
325
577
|
});
|
|
326
578
|
if (result.Success) {
|
|
327
579
|
this.components = result.Results || [];
|
|
328
|
-
this.
|
|
580
|
+
this.combineAndFilterComponents();
|
|
329
581
|
}
|
|
330
582
|
else {
|
|
331
583
|
console.error('Failed to load components:', result.ErrorMessage);
|
|
@@ -340,22 +592,67 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
340
592
|
}
|
|
341
593
|
onSearchChange(query) {
|
|
342
594
|
this.searchQuery = query;
|
|
343
|
-
this.
|
|
595
|
+
this.combineAndFilterComponents();
|
|
344
596
|
}
|
|
345
|
-
|
|
597
|
+
combineAndFilterComponents() {
|
|
598
|
+
// Combine database components with file-loaded components
|
|
599
|
+
this.allComponents = [
|
|
600
|
+
...this.fileLoadedComponents,
|
|
601
|
+
...this.components
|
|
602
|
+
];
|
|
603
|
+
// Apply search filter
|
|
346
604
|
if (!this.searchQuery) {
|
|
347
|
-
this.filteredComponents = [...this.
|
|
605
|
+
this.filteredComponents = [...this.allComponents];
|
|
348
606
|
}
|
|
349
607
|
else {
|
|
350
608
|
const query = this.searchQuery.toLowerCase();
|
|
351
|
-
this.filteredComponents = this.
|
|
352
|
-
c
|
|
353
|
-
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
|
+
});
|
|
354
615
|
}
|
|
355
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
|
+
}
|
|
356
651
|
toggleComponentExpansion(component) {
|
|
357
652
|
// Toggle expansion - if clicking the same component, collapse it
|
|
358
|
-
|
|
653
|
+
const componentId = this.getComponentId(component);
|
|
654
|
+
const expandedId = this.expandedComponent ? this.getComponentId(this.expandedComponent) : null;
|
|
655
|
+
if (expandedId === componentId) {
|
|
359
656
|
this.expandedComponent = null;
|
|
360
657
|
}
|
|
361
658
|
else {
|
|
@@ -364,19 +661,43 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
364
661
|
this.cdr.detectChanges();
|
|
365
662
|
}
|
|
366
663
|
runComponent(component) {
|
|
664
|
+
// If another component is running, stop it first then start the new one
|
|
665
|
+
const componentId = this.getComponentId(component);
|
|
666
|
+
const selectedId = this.selectedComponent ? this.getComponentId(this.selectedComponent) : null;
|
|
667
|
+
if (this.isRunning && selectedId !== componentId) {
|
|
668
|
+
this.stopComponent();
|
|
669
|
+
this.startComponent(component);
|
|
670
|
+
}
|
|
671
|
+
else {
|
|
672
|
+
this.startComponent(component);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
startComponent(component) {
|
|
367
676
|
this.selectedComponent = component;
|
|
368
|
-
this.componentSpec =
|
|
677
|
+
this.componentSpec = this.getComponentSpec(component);
|
|
369
678
|
this.isRunning = true;
|
|
370
679
|
this.currentError = null; // Clear any previous errors
|
|
371
|
-
|
|
372
|
-
this.
|
|
680
|
+
this.isDetailsPaneCollapsed = true; // Start with details collapsed
|
|
681
|
+
this.initializeEditors(); // Initialize spec and code editors
|
|
682
|
+
console.log('Running component:', this.getComponentName(component));
|
|
683
|
+
try {
|
|
684
|
+
this.cdr.detectChanges();
|
|
685
|
+
}
|
|
686
|
+
catch (error) {
|
|
687
|
+
console.error('Error with cdr.detectChanges():', error);
|
|
688
|
+
}
|
|
373
689
|
}
|
|
374
690
|
stopComponent() {
|
|
375
691
|
this.isRunning = false;
|
|
376
692
|
this.selectedComponent = null;
|
|
377
693
|
this.componentSpec = null;
|
|
378
694
|
this.currentError = null;
|
|
379
|
-
|
|
695
|
+
try {
|
|
696
|
+
this.cdr.detectChanges();
|
|
697
|
+
}
|
|
698
|
+
catch (error) {
|
|
699
|
+
console.error('Error with cdr.detectChanges():', error);
|
|
700
|
+
}
|
|
380
701
|
}
|
|
381
702
|
/**
|
|
382
703
|
* Handle component events from React components
|
|
@@ -421,7 +742,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
|
|
|
421
742
|
const errorText = `
|
|
422
743
|
Component Error Report
|
|
423
744
|
${'='.repeat(50)}
|
|
424
|
-
Component: ${this.selectedComponent
|
|
745
|
+
Component: ${this.selectedComponent ? this.getComponentName(this.selectedComponent) : 'Unknown'}
|
|
425
746
|
Error Type: ${this.currentError.type}
|
|
426
747
|
Message: ${this.currentError.message}
|
|
427
748
|
${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify(this.currentError.technicalDetails, null, 2) : ''}
|
|
@@ -446,6 +767,81 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
|
|
|
446
767
|
async refreshData() {
|
|
447
768
|
await this.loadData();
|
|
448
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
|
+
}
|
|
449
845
|
getComponentTypeIcon(type) {
|
|
450
846
|
const icons = {
|
|
451
847
|
'Report': 'fa-file-alt',
|
|
@@ -474,43 +870,286 @@ ${this.currentError.technicalDetails ? '\nTechnical Details:\n' + JSON.stringify
|
|
|
474
870
|
};
|
|
475
871
|
return colors[type || ''] || '#9CA3AF';
|
|
476
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
|
+
}
|
|
477
1092
|
static ɵfac = function ComponentStudioDashboardComponent_Factory(t) { return new (t || ComponentStudioDashboardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
478
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentStudioDashboardComponent, selectors: [["mj-component-studio-dashboard"]],
|
|
479
|
-
i0.ɵɵ
|
|
480
|
-
|
|
481
|
-
|
|
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);
|
|
1102
|
+
i0.ɵɵtext(6, " Component Studio");
|
|
482
1103
|
i0.ɵɵelementEnd();
|
|
483
|
-
i0.ɵɵelementStart(
|
|
484
|
-
i0.ɵɵ
|
|
485
|
-
i0.ɵɵ
|
|
1104
|
+
i0.ɵɵelementStart(7, "p", 5);
|
|
1105
|
+
i0.ɵɵtext(8, "Testing components without custom properties");
|
|
1106
|
+
i0.ɵɵelementEnd()();
|
|
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)); });
|
|
486
1121
|
i0.ɵɵelementEnd()()();
|
|
487
|
-
i0.ɵɵelementStart(
|
|
488
|
-
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");
|
|
489
1124
|
i0.ɵɵelementEnd();
|
|
490
|
-
i0.ɵɵelementStart(
|
|
491
|
-
i0.ɵɵlistener("valueChange", function
|
|
492
|
-
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);
|
|
493
1128
|
i0.ɵɵelementEnd()()();
|
|
494
|
-
i0.ɵɵelementStart(
|
|
495
|
-
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);
|
|
496
1131
|
i0.ɵɵelementEnd()()();
|
|
497
|
-
i0.ɵɵelementStart(
|
|
498
|
-
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);
|
|
499
1134
|
i0.ɵɵelementEnd()()()();
|
|
500
1135
|
} if (rf & 2) {
|
|
501
|
-
i0.ɵɵadvance(
|
|
502
|
-
i0.ɵɵ
|
|
1136
|
+
i0.ɵɵadvance(10);
|
|
1137
|
+
i0.ɵɵconditional(ctx.selectedComponent && ctx.isRunning ? 10 : -1);
|
|
1138
|
+
i0.ɵɵadvance();
|
|
1139
|
+
i0.ɵɵproperty("themeColor", "info");
|
|
503
1140
|
i0.ɵɵadvance(3);
|
|
1141
|
+
i0.ɵɵproperty("disabled", ctx.isLoading);
|
|
1142
|
+
i0.ɵɵadvance(6);
|
|
504
1143
|
i0.ɵɵproperty("min", "350px")("max", "600px")("size", "400px");
|
|
505
1144
|
i0.ɵɵadvance(6);
|
|
506
1145
|
i0.ɵɵproperty("value", ctx.searchQuery)("clearButton", true);
|
|
507
1146
|
i0.ɵɵadvance(3);
|
|
508
|
-
i0.ɵɵconditional(ctx.isLoading ?
|
|
1147
|
+
i0.ɵɵconditional(ctx.isLoading ? 29 : ctx.filteredComponents.length === 0 ? 30 : 31);
|
|
509
1148
|
i0.ɵɵadvance(3);
|
|
510
1149
|
i0.ɵɵproperty("min", "400px");
|
|
511
1150
|
i0.ɵɵadvance(2);
|
|
512
|
-
i0.ɵɵconditional(ctx.
|
|
513
|
-
} }, 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 }\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 }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\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}"] });
|
|
514
1153
|
};
|
|
515
1154
|
ComponentStudioDashboardComponent = __decorate([
|
|
516
1155
|
RegisterClass(BaseDashboard, 'ComponentStudioDashboard')
|
|
@@ -518,9 +1157,12 @@ ComponentStudioDashboardComponent = __decorate([
|
|
|
518
1157
|
export { ComponentStudioDashboardComponent };
|
|
519
1158
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentStudioDashboardComponent, [{
|
|
520
1159
|
type: Component,
|
|
521
|
-
args: [{ selector: 'mj-component-studio-dashboard', template: "<div class=\"component-studio\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-content\">\n <h1><i class=\"fa-solid fa-puzzle-piece\"></i> Component Studio</h1>\n <button kendoButton [icon]=\"'fa-solid fa-sync'\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n 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 No components found\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 [icon]=\"'fa-solid fa-stop'\" \n [themeColor]=\"'error'\"\n (click)=\"stopComponent(); $event.stopPropagation()\">\n Stop Component\n </button>\n } @else {\n <button kendoButton \n [icon]=\"'fa-solid fa-play'\" \n [themeColor]=\"'primary'\"\n (click)=\"runComponent(component); $event.stopPropagation()\">\n 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()\" [icon]=\"'fa-solid fa-rotate'\">\n Retry\n </button>\n <button kendoButton (click)=\"stopComponent()\" [icon]=\"'fa-solid fa-stop'\" [themeColor]=\"'error'\">\n 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 }\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 }\n \n .card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n cursor: pointer;\n user-select: none;\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}"] }]
|
|
522
|
-
}], () => [{ type: i0.ChangeDetectorRef }],
|
|
523
|
-
|
|
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 }); })();
|
|
524
1166
|
/**
|
|
525
1167
|
* Function to prevent tree shaking of the ComponentStudioDashboardComponent.
|
|
526
1168
|
*/
|