@memberjunction/ng-artifacts 5.40.1 → 5.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/__tests__/interactive-form-apply.service.test.js +6 -1
- package/dist/lib/__tests__/interactive-form-apply.service.test.js.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +14 -2
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +165 -62
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts +19 -0
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -0
- package/dist/lib/components/plugins/component-permission-evaluation.js +64 -0
- package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -0
- package/dist/lib/services/interactive-form-apply.service.d.ts +15 -0
- package/dist/lib/services/interactive-form-apply.service.d.ts.map +1 -1
- package/dist/lib/services/interactive-form-apply.service.js +91 -18
- package/dist/lib/services/interactive-form-apply.service.js.map +1 -1
- package/package.json +19 -19
|
@@ -11,6 +11,7 @@ import { BuildComponentCompleteCode } from '@memberjunction/interactive-componen
|
|
|
11
11
|
import { isFormRole, getDeclaredFormEntityName } from '@memberjunction/interactive-component-types/forms';
|
|
12
12
|
import { CompositeKey, DataSnapshot, LogError, RunView } from '@memberjunction/core';
|
|
13
13
|
import { DataRequirementsViewerComponent } from './data-requirements-viewer/data-requirements-viewer.component';
|
|
14
|
+
import { evaluateComponentPermissions } from './component-permission-evaluation';
|
|
14
15
|
import * as i0 from "@angular/core";
|
|
15
16
|
import * as i1 from "@memberjunction/ng-react";
|
|
16
17
|
import * as i2 from "@angular/common";
|
|
@@ -19,7 +20,7 @@ import * as i4 from "./component-feedback-panel/component-feedback-panel.compone
|
|
|
19
20
|
const _c0 = ["reactComponent"];
|
|
20
21
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
21
22
|
function ComponentArtifactViewerComponent_Conditional_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
-
i0.ɵɵelementStart(0, "details",
|
|
23
|
+
i0.ɵɵelementStart(0, "details", 8)(1, "summary");
|
|
23
24
|
i0.ɵɵtext(2, "Technical Details");
|
|
24
25
|
i0.ɵɵelementEnd();
|
|
25
26
|
i0.ɵɵelementStart(3, "pre");
|
|
@@ -32,14 +33,14 @@ function ComponentArtifactViewerComponent_Conditional_2_Conditional_13_Template(
|
|
|
32
33
|
} }
|
|
33
34
|
function ComponentArtifactViewerComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
34
35
|
i0.ɵɵelementStart(0, "div", 3);
|
|
35
|
-
i0.ɵɵelement(1, "i",
|
|
36
|
+
i0.ɵɵelement(1, "i", 6);
|
|
36
37
|
i0.ɵɵelementStart(2, "h3");
|
|
37
38
|
i0.ɵɵtext(3);
|
|
38
39
|
i0.ɵɵelementEnd();
|
|
39
40
|
i0.ɵɵelementStart(4, "p");
|
|
40
41
|
i0.ɵɵtext(5, "This component could not be loaded. This usually happens when:");
|
|
41
42
|
i0.ɵɵelementEnd();
|
|
42
|
-
i0.ɵɵelementStart(6, "ul",
|
|
43
|
+
i0.ɵɵelementStart(6, "ul", 7)(7, "li");
|
|
43
44
|
i0.ɵɵtext(8, "The component registry is unavailable or unreachable");
|
|
44
45
|
i0.ɵɵelementEnd();
|
|
45
46
|
i0.ɵɵelementStart(9, "li");
|
|
@@ -48,7 +49,7 @@ function ComponentArtifactViewerComponent_Conditional_2_Template(rf, ctx) { if (
|
|
|
48
49
|
i0.ɵɵelementStart(11, "li");
|
|
49
50
|
i0.ɵɵtext(12, "There was a network error during component retrieval");
|
|
50
51
|
i0.ɵɵelementEnd()();
|
|
51
|
-
i0.ɵɵconditionalCreate(13, ComponentArtifactViewerComponent_Conditional_2_Conditional_13_Template, 5, 1, "details",
|
|
52
|
+
i0.ɵɵconditionalCreate(13, ComponentArtifactViewerComponent_Conditional_2_Conditional_13_Template, 5, 1, "details", 8);
|
|
52
53
|
i0.ɵɵelementEnd();
|
|
53
54
|
} if (rf & 2) {
|
|
54
55
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -58,12 +59,12 @@ function ComponentArtifactViewerComponent_Conditional_2_Template(rf, ctx) { if (
|
|
|
58
59
|
i0.ɵɵconditional(ctx_r0.errorDetails ? 13 : -1);
|
|
59
60
|
} }
|
|
60
61
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
-
i0.ɵɵelementStart(0, "span",
|
|
62
|
+
i0.ɵɵelementStart(0, "span", 14);
|
|
62
63
|
i0.ɵɵtext(1, "Mock");
|
|
63
64
|
i0.ɵɵelementEnd();
|
|
64
65
|
} }
|
|
65
66
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
66
|
-
i0.ɵɵelementStart(0, "span",
|
|
67
|
+
i0.ɵɵelementStart(0, "span", 16);
|
|
67
68
|
i0.ɵɵtext(1);
|
|
68
69
|
i0.ɵɵelementEnd();
|
|
69
70
|
} if (rf & 2) {
|
|
@@ -72,8 +73,8 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_10_Template(
|
|
|
72
73
|
i0.ɵɵtextInterpolate(ctx_r0.formEntityInfo.DisplayName || ctx_r0.formEntityInfo.Name);
|
|
73
74
|
} }
|
|
74
75
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
75
|
-
i0.ɵɵelementStart(0, "span",
|
|
76
|
-
i0.ɵɵelement(1, "i",
|
|
76
|
+
i0.ɵɵelementStart(0, "span", 17);
|
|
77
|
+
i0.ɵɵelement(1, "i", 22);
|
|
77
78
|
i0.ɵɵelementEnd();
|
|
78
79
|
} if (rf & 2) {
|
|
79
80
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -81,17 +82,17 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_11_Template(
|
|
|
81
82
|
} }
|
|
82
83
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
83
84
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
84
|
-
i0.ɵɵelementStart(0, "button",
|
|
85
|
+
i0.ɵɵelementStart(0, "button", 23);
|
|
85
86
|
i0.ɵɵlistener("click", function ComponentArtifactViewerComponent_Conditional_3_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onApplyClicked()); });
|
|
86
|
-
i0.ɵɵelement(1, "i",
|
|
87
|
+
i0.ɵɵelement(1, "i", 24);
|
|
87
88
|
i0.ɵɵtext(2, " Apply to my form ");
|
|
88
89
|
i0.ɵɵelementEnd();
|
|
89
90
|
} }
|
|
90
91
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
91
92
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
92
|
-
i0.ɵɵelementStart(0, "li",
|
|
93
|
+
i0.ɵɵelementStart(0, "li", 30);
|
|
93
94
|
i0.ɵɵlistener("click", function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_For_2_Template_li_click_0_listener() { const r_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onPickerSelect(r_r6)); });
|
|
94
|
-
i0.ɵɵelement(1, "i",
|
|
95
|
+
i0.ɵɵelement(1, "i", 31);
|
|
95
96
|
i0.ɵɵelementStart(2, "span");
|
|
96
97
|
i0.ɵɵtext(3);
|
|
97
98
|
i0.ɵɵelementEnd()();
|
|
@@ -101,8 +102,8 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Condition
|
|
|
101
102
|
i0.ɵɵtextInterpolate(r_r6.Label);
|
|
102
103
|
} }
|
|
103
104
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
104
|
-
i0.ɵɵelementStart(0, "ul",
|
|
105
|
-
i0.ɵɵrepeaterCreate(1, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_For_2_Template, 4, 1, "li",
|
|
105
|
+
i0.ɵɵelementStart(0, "ul", 27);
|
|
106
|
+
i0.ɵɵrepeaterCreate(1, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_For_2_Template, 4, 1, "li", 29, _forTrack0);
|
|
106
107
|
i0.ɵɵelementEnd();
|
|
107
108
|
} if (rf & 2) {
|
|
108
109
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -110,23 +111,23 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Condition
|
|
|
110
111
|
i0.ɵɵrepeater(ctx_r0.recordSearchResults);
|
|
111
112
|
} }
|
|
112
113
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
113
|
-
i0.ɵɵelementStart(0, "div",
|
|
114
|
+
i0.ɵɵelementStart(0, "div", 28);
|
|
114
115
|
i0.ɵɵtext(1, "No matches.");
|
|
115
116
|
i0.ɵɵelementEnd();
|
|
116
117
|
} }
|
|
117
118
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
-
i0.ɵɵelementStart(0, "div",
|
|
119
|
+
i0.ɵɵelementStart(0, "div", 28);
|
|
119
120
|
i0.ɵɵtext(1, "Start typing to search.");
|
|
120
121
|
i0.ɵɵelementEnd();
|
|
121
122
|
} }
|
|
122
123
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
123
124
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
124
|
-
i0.ɵɵelementStart(0, "div",
|
|
125
|
+
i0.ɵɵelementStart(0, "div", 25);
|
|
125
126
|
i0.ɵɵlistener("click", function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
126
|
-
i0.ɵɵelementStart(1, "input",
|
|
127
|
+
i0.ɵɵelementStart(1, "input", 26);
|
|
127
128
|
i0.ɵɵlistener("input", function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template_input_input_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onPickerSearchInput($event.target.value)); });
|
|
128
129
|
i0.ɵɵelementEnd();
|
|
129
|
-
i0.ɵɵconditionalCreate(2, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_Template, 3, 0, "ul",
|
|
130
|
+
i0.ɵɵconditionalCreate(2, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_Template, 3, 0, "ul", 27)(3, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_3_Template, 2, 0, "div", 28)(4, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_4_Template, 2, 0, "div", 28);
|
|
130
131
|
i0.ɵɵelementEnd();
|
|
131
132
|
} if (rf & 2) {
|
|
132
133
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -136,8 +137,8 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template(
|
|
|
136
137
|
i0.ɵɵconditional(ctx_r0.recordSearchResults.length > 0 ? 2 : ctx_r0.recordSearchTerm.length > 0 ? 3 : 4);
|
|
137
138
|
} }
|
|
138
139
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
139
|
-
i0.ɵɵelementStart(0, "div",
|
|
140
|
-
i0.ɵɵelement(1, "mj-interactive-form",
|
|
140
|
+
i0.ɵɵelementStart(0, "div", 21);
|
|
141
|
+
i0.ɵɵelement(1, "mj-interactive-form", 32);
|
|
141
142
|
i0.ɵɵelementEnd();
|
|
142
143
|
} if (rf & 2) {
|
|
143
144
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -146,7 +147,7 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_15_Template(
|
|
|
146
147
|
} }
|
|
147
148
|
function ComponentArtifactViewerComponent_Conditional_3_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
148
149
|
i0.ɵɵelementStart(0, "div", 3);
|
|
149
|
-
i0.ɵɵelement(1, "i",
|
|
150
|
+
i0.ɵɵelement(1, "i", 33);
|
|
150
151
|
i0.ɵɵelementStart(2, "h3");
|
|
151
152
|
i0.ɵɵtext(3, "Form preview unavailable");
|
|
152
153
|
i0.ɵɵelementEnd();
|
|
@@ -160,27 +161,27 @@ function ComponentArtifactViewerComponent_Conditional_3_Conditional_16_Template(
|
|
|
160
161
|
} }
|
|
161
162
|
function ComponentArtifactViewerComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
162
163
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
163
|
-
i0.ɵɵelementStart(0, "div",
|
|
164
|
-
i0.ɵɵelement(1, "i",
|
|
165
|
-
i0.ɵɵelementStart(2, "span",
|
|
164
|
+
i0.ɵɵelementStart(0, "div", 9);
|
|
165
|
+
i0.ɵɵelement(1, "i", 10);
|
|
166
|
+
i0.ɵɵelementStart(2, "span", 11);
|
|
166
167
|
i0.ɵɵtext(3, "Previewing record:");
|
|
167
168
|
i0.ɵɵelementEnd();
|
|
168
|
-
i0.ɵɵelementStart(4, "button",
|
|
169
|
+
i0.ɵɵelementStart(4, "button", 12);
|
|
169
170
|
i0.ɵɵlistener("click", function ComponentArtifactViewerComponent_Conditional_3_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showRecordPicker = !ctx_r0.showRecordPicker); });
|
|
170
|
-
i0.ɵɵelement(5, "i",
|
|
171
|
+
i0.ɵɵelement(5, "i", 13);
|
|
171
172
|
i0.ɵɵelementStart(6, "strong");
|
|
172
173
|
i0.ɵɵtext(7);
|
|
173
174
|
i0.ɵɵelementEnd();
|
|
174
|
-
i0.ɵɵconditionalCreate(8, ComponentArtifactViewerComponent_Conditional_3_Conditional_8_Template, 2, 0, "span",
|
|
175
|
-
i0.ɵɵelement(9, "i",
|
|
175
|
+
i0.ɵɵconditionalCreate(8, ComponentArtifactViewerComponent_Conditional_3_Conditional_8_Template, 2, 0, "span", 14);
|
|
176
|
+
i0.ɵɵelement(9, "i", 15);
|
|
176
177
|
i0.ɵɵelementEnd();
|
|
177
|
-
i0.ɵɵconditionalCreate(10, ComponentArtifactViewerComponent_Conditional_3_Conditional_10_Template, 2, 1, "span",
|
|
178
|
-
i0.ɵɵconditionalCreate(11, ComponentArtifactViewerComponent_Conditional_3_Conditional_11_Template, 2, 1, "span",
|
|
179
|
-
i0.ɵɵelement(12, "span",
|
|
180
|
-
i0.ɵɵconditionalCreate(13, ComponentArtifactViewerComponent_Conditional_3_Conditional_13_Template, 3, 0, "button",
|
|
178
|
+
i0.ɵɵconditionalCreate(10, ComponentArtifactViewerComponent_Conditional_3_Conditional_10_Template, 2, 1, "span", 16);
|
|
179
|
+
i0.ɵɵconditionalCreate(11, ComponentArtifactViewerComponent_Conditional_3_Conditional_11_Template, 2, 1, "span", 17);
|
|
180
|
+
i0.ɵɵelement(12, "span", 18);
|
|
181
|
+
i0.ɵɵconditionalCreate(13, ComponentArtifactViewerComponent_Conditional_3_Conditional_13_Template, 3, 0, "button", 19);
|
|
181
182
|
i0.ɵɵelementEnd();
|
|
182
|
-
i0.ɵɵconditionalCreate(14, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template, 5, 2, "div",
|
|
183
|
-
i0.ɵɵconditionalCreate(15, ComponentArtifactViewerComponent_Conditional_3_Conditional_15_Template, 2, 2, "div",
|
|
183
|
+
i0.ɵɵconditionalCreate(14, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Template, 5, 2, "div", 20);
|
|
184
|
+
i0.ɵɵconditionalCreate(15, ComponentArtifactViewerComponent_Conditional_3_Conditional_15_Template, 2, 2, "div", 21)(16, ComponentArtifactViewerComponent_Conditional_3_Conditional_16_Template, 6, 1, "div", 3);
|
|
184
185
|
} if (rf & 2) {
|
|
185
186
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
186
187
|
i0.ɵɵadvance(7);
|
|
@@ -198,18 +199,84 @@ function ComponentArtifactViewerComponent_Conditional_3_Template(rf, ctx) { if (
|
|
|
198
199
|
i0.ɵɵadvance();
|
|
199
200
|
i0.ɵɵconditional(ctx_r0.formRecord && ctx_r0.component ? 15 : 16);
|
|
200
201
|
} }
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
i0.ɵɵ
|
|
204
|
-
i0.ɵɵ
|
|
202
|
+
function ComponentArtifactViewerComponent_Conditional_4_Conditional_7_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
203
|
+
i0.ɵɵelementStart(0, "li");
|
|
204
|
+
i0.ɵɵelement(1, "i", 39);
|
|
205
|
+
i0.ɵɵtext(2);
|
|
206
|
+
i0.ɵɵelementEnd();
|
|
207
|
+
} if (rf & 2) {
|
|
208
|
+
const entity_r7 = ctx.$implicit;
|
|
209
|
+
i0.ɵɵadvance(2);
|
|
210
|
+
i0.ɵɵtextInterpolate1(" ", entity_r7);
|
|
211
|
+
} }
|
|
212
|
+
function ComponentArtifactViewerComponent_Conditional_4_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
213
|
+
i0.ɵɵelementStart(0, "div", 36)(1, "span", 38);
|
|
214
|
+
i0.ɵɵtext(2, "Entities");
|
|
215
|
+
i0.ɵɵelementEnd();
|
|
216
|
+
i0.ɵɵelementStart(3, "ul");
|
|
217
|
+
i0.ɵɵrepeaterCreate(4, ComponentArtifactViewerComponent_Conditional_4_Conditional_7_For_5_Template, 3, 1, "li", null, i0.ɵɵrepeaterTrackByIdentity);
|
|
218
|
+
i0.ɵɵelementEnd()();
|
|
219
|
+
} if (rf & 2) {
|
|
220
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
221
|
+
i0.ɵɵadvance(4);
|
|
222
|
+
i0.ɵɵrepeater(ctx_r0.permissionResult.missingEntities);
|
|
223
|
+
} }
|
|
224
|
+
function ComponentArtifactViewerComponent_Conditional_4_Conditional_8_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
225
|
+
i0.ɵɵelementStart(0, "li");
|
|
226
|
+
i0.ɵɵelement(1, "i", 40);
|
|
227
|
+
i0.ɵɵtext(2);
|
|
228
|
+
i0.ɵɵelementEnd();
|
|
229
|
+
} if (rf & 2) {
|
|
230
|
+
const query_r8 = ctx.$implicit;
|
|
231
|
+
i0.ɵɵadvance(2);
|
|
232
|
+
i0.ɵɵtextInterpolate1(" ", query_r8);
|
|
233
|
+
} }
|
|
234
|
+
function ComponentArtifactViewerComponent_Conditional_4_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
235
|
+
i0.ɵɵelementStart(0, "div", 36)(1, "span", 38);
|
|
236
|
+
i0.ɵɵtext(2, "Queries");
|
|
237
|
+
i0.ɵɵelementEnd();
|
|
238
|
+
i0.ɵɵelementStart(3, "ul");
|
|
239
|
+
i0.ɵɵrepeaterCreate(4, ComponentArtifactViewerComponent_Conditional_4_Conditional_8_For_5_Template, 3, 1, "li", null, i0.ɵɵrepeaterTrackByIdentity);
|
|
240
|
+
i0.ɵɵelementEnd()();
|
|
241
|
+
} if (rf & 2) {
|
|
242
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
243
|
+
i0.ɵɵadvance(4);
|
|
244
|
+
i0.ɵɵrepeater(ctx_r0.permissionResult.missingQueries);
|
|
245
|
+
} }
|
|
246
|
+
function ComponentArtifactViewerComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
247
|
+
i0.ɵɵelementStart(0, "div", 4)(1, "div", 34);
|
|
248
|
+
i0.ɵɵelement(2, "i", 35);
|
|
249
|
+
i0.ɵɵelementEnd();
|
|
250
|
+
i0.ɵɵelementStart(3, "h3");
|
|
251
|
+
i0.ɵɵtext(4, "Insufficient Permissions");
|
|
252
|
+
i0.ɵɵelementEnd();
|
|
253
|
+
i0.ɵɵelementStart(5, "p");
|
|
254
|
+
i0.ɵɵtext(6, "This component requires data access that you don't currently have:");
|
|
255
|
+
i0.ɵɵelementEnd();
|
|
256
|
+
i0.ɵɵconditionalCreate(7, ComponentArtifactViewerComponent_Conditional_4_Conditional_7_Template, 6, 0, "div", 36);
|
|
257
|
+
i0.ɵɵconditionalCreate(8, ComponentArtifactViewerComponent_Conditional_4_Conditional_8_Template, 6, 0, "div", 36);
|
|
258
|
+
i0.ɵɵelementStart(9, "p", 37);
|
|
259
|
+
i0.ɵɵtext(10, "Contact your administrator to request access.");
|
|
260
|
+
i0.ɵɵelementEnd()();
|
|
261
|
+
} if (rf & 2) {
|
|
262
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
263
|
+
i0.ɵɵadvance(7);
|
|
264
|
+
i0.ɵɵconditional(ctx_r0.permissionResult.missingEntities.length > 0 ? 7 : -1);
|
|
265
|
+
i0.ɵɵadvance();
|
|
266
|
+
i0.ɵɵconditional(ctx_r0.permissionResult.missingQueries.length > 0 ? 8 : -1);
|
|
267
|
+
} }
|
|
268
|
+
function ComponentArtifactViewerComponent_Conditional_5_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
269
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
270
|
+
i0.ɵɵelementStart(0, "mj-react-component", 43, 0);
|
|
271
|
+
i0.ɵɵlistener("componentEvent", function ComponentArtifactViewerComponent_Conditional_5_Conditional_0_Template_mj_react_component_componentEvent_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onComponentEvent($event)); })("openEntityRecord", function ComponentArtifactViewerComponent_Conditional_5_Conditional_0_Template_mj_react_component_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("initialized", function ComponentArtifactViewerComponent_Conditional_5_Conditional_0_Template_mj_react_component_initialized_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onReactComponentInitialized()); });
|
|
205
272
|
i0.ɵɵelementEnd();
|
|
206
273
|
} if (rf & 2) {
|
|
207
274
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
208
275
|
i0.ɵɵproperty("component", ctx_r0.component);
|
|
209
276
|
} }
|
|
210
|
-
function
|
|
211
|
-
i0.ɵɵelementStart(0, "div",
|
|
212
|
-
i0.ɵɵelement(1, "i",
|
|
277
|
+
function ComponentArtifactViewerComponent_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
278
|
+
i0.ɵɵelementStart(0, "div", 42);
|
|
279
|
+
i0.ɵɵelement(1, "i", 44);
|
|
213
280
|
i0.ɵɵelementStart(2, "h3");
|
|
214
281
|
i0.ɵɵtext(3, "Component Specification");
|
|
215
282
|
i0.ɵɵelementEnd();
|
|
@@ -220,9 +287,9 @@ function ComponentArtifactViewerComponent_Conditional_4_Conditional_1_Template(r
|
|
|
220
287
|
i0.ɵɵtext(7, "View the Functional, Data, or Spec tabs for details.");
|
|
221
288
|
i0.ɵɵelementEnd()();
|
|
222
289
|
} }
|
|
223
|
-
function
|
|
290
|
+
function ComponentArtifactViewerComponent_Conditional_5_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
224
291
|
i0.ɵɵelementStart(0, "div", 3);
|
|
225
|
-
i0.ɵɵelement(1, "i",
|
|
292
|
+
i0.ɵɵelement(1, "i", 33);
|
|
226
293
|
i0.ɵɵelementStart(2, "h3");
|
|
227
294
|
i0.ɵɵtext(3, "No Component Loaded");
|
|
228
295
|
i0.ɵɵelementEnd();
|
|
@@ -230,16 +297,16 @@ function ComponentArtifactViewerComponent_Conditional_4_Conditional_2_Template(r
|
|
|
230
297
|
i0.ɵɵtext(5, "The component data is missing or invalid.");
|
|
231
298
|
i0.ɵɵelementEnd()();
|
|
232
299
|
} }
|
|
233
|
-
function
|
|
234
|
-
i0.ɵɵconditionalCreate(0,
|
|
300
|
+
function ComponentArtifactViewerComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
301
|
+
i0.ɵɵconditionalCreate(0, ComponentArtifactViewerComponent_Conditional_5_Conditional_0_Template, 2, 1, "mj-react-component", 41)(1, ComponentArtifactViewerComponent_Conditional_5_Conditional_1_Template, 8, 0, "div", 42)(2, ComponentArtifactViewerComponent_Conditional_5_Conditional_2_Template, 6, 0, "div", 3);
|
|
235
302
|
} if (rf & 2) {
|
|
236
303
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
237
304
|
i0.ɵɵconditional(ctx_r0.component && (ctx_r0.component.code || ctx_r0.component.namespace) ? 0 : ctx_r0.component ? 1 : 2);
|
|
238
305
|
} }
|
|
239
|
-
function
|
|
240
|
-
const
|
|
241
|
-
i0.ɵɵelementStart(0, "mj-component-feedback-panel",
|
|
242
|
-
i0.ɵɵlistener("Closed", function
|
|
306
|
+
function ComponentArtifactViewerComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
307
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
308
|
+
i0.ɵɵelementStart(0, "mj-component-feedback-panel", 45);
|
|
309
|
+
i0.ɵɵlistener("Closed", function ComponentArtifactViewerComponent_Conditional_6_Template_mj_component_feedback_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ShowFeedbackPanel = false); });
|
|
243
310
|
i0.ɵɵelementEnd();
|
|
244
311
|
} if (rf & 2) {
|
|
245
312
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -255,6 +322,7 @@ function ComponentArtifactViewerComponent_Conditional_5_Template(rf, ctx) { if (
|
|
|
255
322
|
*/
|
|
256
323
|
let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
|
|
257
324
|
adapter;
|
|
325
|
+
cdr;
|
|
258
326
|
reactComponent;
|
|
259
327
|
tabsChanged = new EventEmitter();
|
|
260
328
|
openEntityRecord = new EventEmitter();
|
|
@@ -302,6 +370,8 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
302
370
|
hasError = false;
|
|
303
371
|
errorMessage = '';
|
|
304
372
|
errorDetails = '';
|
|
373
|
+
// Permission state
|
|
374
|
+
permissionResult = null;
|
|
305
375
|
/**
|
|
306
376
|
* Whether this plugin has content to display in the Display tab.
|
|
307
377
|
* Returns true only if the component has code that can be rendered.
|
|
@@ -315,9 +385,10 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
315
385
|
// Use this.component directly - it's available synchronously after loadComponentSpec()
|
|
316
386
|
return !!this.component?.namespace || !!this.component?.code;
|
|
317
387
|
}
|
|
318
|
-
constructor(adapter) {
|
|
388
|
+
constructor(adapter, cdr) {
|
|
319
389
|
super();
|
|
320
390
|
this.adapter = adapter;
|
|
391
|
+
this.cdr = cdr;
|
|
321
392
|
}
|
|
322
393
|
async ngOnChanges(changes) {
|
|
323
394
|
// When artifactVersion input changes, reload the component spec
|
|
@@ -343,9 +414,11 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
343
414
|
try {
|
|
344
415
|
// Clear cached resolved spec from previous version so stale data doesn't persist
|
|
345
416
|
this._cachedResolvedSpec = null;
|
|
417
|
+
this.permissionResult = null;
|
|
346
418
|
if (this.artifactVersion?.Content) {
|
|
347
419
|
this.component = SafeJSONParse(this.artifactVersion.Content);
|
|
348
420
|
this.extractComponentParts();
|
|
421
|
+
this.evaluatePermissions();
|
|
349
422
|
// Form-aware detection. Done here (not in ngAfterViewInit) so the
|
|
350
423
|
// template's `@if (isFormArtifact)` branch decides which preview
|
|
351
424
|
// to mount on the very first render — no flash of the non-form
|
|
@@ -363,6 +436,26 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
363
436
|
this.errorDetails = error instanceof Error ? error.message : String(error);
|
|
364
437
|
}
|
|
365
438
|
}
|
|
439
|
+
/**
|
|
440
|
+
* Evaluate whether the current user has sufficient permissions for
|
|
441
|
+
* all entities and queries referenced in the component's dataRequirements.
|
|
442
|
+
* Uses the best available spec: resolved (from registry) > cached > stripped artifact.
|
|
443
|
+
* Runs synchronously against already-loaded client-side metadata.
|
|
444
|
+
*/
|
|
445
|
+
evaluatePermissions() {
|
|
446
|
+
const spec = this.resolvedComponentSpec;
|
|
447
|
+
if (!spec)
|
|
448
|
+
return;
|
|
449
|
+
const provider = this.ProviderToUse;
|
|
450
|
+
const currentUser = provider.CurrentUser;
|
|
451
|
+
if (!currentUser)
|
|
452
|
+
return; // No user context — skip check
|
|
453
|
+
this.permissionResult = evaluateComponentPermissions(spec, currentUser, provider);
|
|
454
|
+
}
|
|
455
|
+
/** Whether the component should be blocked from rendering due to missing permissions. */
|
|
456
|
+
get isPermissionBlocked() {
|
|
457
|
+
return !!this.permissionResult && !this.permissionResult.canRun;
|
|
458
|
+
}
|
|
366
459
|
/**
|
|
367
460
|
* Component initialization.
|
|
368
461
|
* Note: loadComponentSpec() is called in ngOnChanges which runs before ngOnInit,
|
|
@@ -469,6 +562,11 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
469
562
|
// Cache the resolved spec so it's available even after the React component is destroyed
|
|
470
563
|
this._cachedResolvedSpec = this.reactComponent.resolvedComponentSpec;
|
|
471
564
|
this.tabsChanged.emit();
|
|
565
|
+
// Re-evaluate permissions against the resolved spec — the stripped artifact
|
|
566
|
+
// spec has no dataRequirements, so the initial check in loadComponentSpec()
|
|
567
|
+
// passes trivially. The resolved spec from the registry contains the full
|
|
568
|
+
// dataRequirements with entity and query references.
|
|
569
|
+
this.evaluatePermissions();
|
|
472
570
|
}
|
|
473
571
|
}
|
|
474
572
|
onComponentEvent(event) {
|
|
@@ -586,6 +684,11 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
586
684
|
this.formRecordIsReal = false;
|
|
587
685
|
this.formRecordLabel = 'Mock data';
|
|
588
686
|
}
|
|
687
|
+
// This runs after an await on a RunView that resolves outside Angular's zone,
|
|
688
|
+
// so nothing would refresh the view until the next user event — leaving the
|
|
689
|
+
// "Could not bind a record" message up until the user clicks. Force CD so the
|
|
690
|
+
// auto-loaded record binds and the form mounts immediately on first render.
|
|
691
|
+
this.cdr.detectChanges();
|
|
589
692
|
}
|
|
590
693
|
/**
|
|
591
694
|
* Load the first row by NameField (then __mj_CreatedAt) so different users
|
|
@@ -707,25 +810,25 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
707
810
|
entityName: this.formEntityInfo.Name,
|
|
708
811
|
});
|
|
709
812
|
}
|
|
710
|
-
static ɵfac = function ComponentArtifactViewerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ComponentArtifactViewerComponent)(i0.ɵɵdirectiveInject(i1.AngularAdapterService)); };
|
|
813
|
+
static ɵfac = function ComponentArtifactViewerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ComponentArtifactViewerComponent)(i0.ɵɵdirectiveInject(i1.AngularAdapterService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
711
814
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentArtifactViewerComponent, selectors: [["mj-component-artifact-viewer"]], viewQuery: function ComponentArtifactViewerComponent_Query(rf, ctx) { if (rf & 1) {
|
|
712
815
|
i0.ɵɵviewQuery(_c0, 5);
|
|
713
816
|
} if (rf & 2) {
|
|
714
817
|
let _t;
|
|
715
818
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reactComponent = _t.first);
|
|
716
|
-
} }, outputs: { tabsChanged: "tabsChanged", openEntityRecord: "openEntityRecord", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls:
|
|
819
|
+
} }, outputs: { tabsChanged: "tabsChanged", openEntityRecord: "openEntityRecord", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 7, vars: 3, consts: [["reactComponent", ""], [1, "component-artifact-viewer", 3, "ngClass"], [1, "component-preview"], [1, "error-state"], [1, "permission-warning"], [3, "ComponentSpec", "ReactContainerElement"], [1, "fa-solid", "fa-exclamation-triangle"], [2, "text-align", "left", "max-width", "500px", "color", "var(--mj-text-muted)", "line-height", "1.6"], [2, "margin-top", "20px"], [1, "form-artifact-toolstrip"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-info"], [1, "form-artifact-toolstrip-label"], ["type", "button", 1, "form-artifact-picker-chip", 3, "click"], [1, "fa-solid", "fa-magnifying-glass"], [1, "form-artifact-picker-chip-badge"], [1, "fa-solid", "fa-chevron-down"], [1, "form-artifact-toolstrip-entity"], [1, "form-artifact-toolstrip-warning", 3, "title"], [2, "flex", "1"], ["type", "button", 1, "form-artifact-apply-btn"], [1, "form-artifact-picker-panel"], [1, "form-artifact-form-host"], [1, "fa-solid", "fa-triangle-exclamation"], ["type", "button", 1, "form-artifact-apply-btn", 3, "click"], [1, "fa-solid", "fa-circle-check"], [1, "form-artifact-picker-panel", 3, "click"], ["type", "text", "placeholder", "Search records by name\u2026", 1, "form-artifact-picker-search", 3, "input", "value"], [1, "form-artifact-picker-results"], [1, "form-artifact-picker-empty"], [1, "form-artifact-picker-row"], [1, "form-artifact-picker-row", 3, "click"], [1, "fa-solid", "fa-circle-dot"], [3, "componentSpec", "record"], [1, "fa-solid", "fa-exclamation-circle"], [1, "permission-warning-icon"], [1, "fa-solid", "fa-shield-halved"], [1, "permission-warning-section"], [1, "permission-warning-hint"], [1, "permission-warning-section-label"], [1, "fa-solid", "fa-table"], [1, "fa-solid", "fa-database"], [3, "component"], [1, "no-code-state"], [3, "componentEvent", "openEntityRecord", "initialized", "component"], [1, "fa-solid", "fa-file-lines"], [3, "Closed", "ComponentSpec", "ReactContainerElement"]], template: function ComponentArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
717
820
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2);
|
|
718
|
-
i0.ɵɵconditionalCreate(2, ComponentArtifactViewerComponent_Conditional_2_Template, 14, 2, "div", 3)(3, ComponentArtifactViewerComponent_Conditional_3_Template, 17, 7)(4, ComponentArtifactViewerComponent_Conditional_4_Template, 3, 1);
|
|
821
|
+
i0.ɵɵconditionalCreate(2, ComponentArtifactViewerComponent_Conditional_2_Template, 14, 2, "div", 3)(3, ComponentArtifactViewerComponent_Conditional_3_Template, 17, 7)(4, ComponentArtifactViewerComponent_Conditional_4_Template, 11, 2, "div", 4)(5, ComponentArtifactViewerComponent_Conditional_5_Template, 3, 1);
|
|
719
822
|
i0.ɵɵelementEnd();
|
|
720
|
-
i0.ɵɵconditionalCreate(
|
|
823
|
+
i0.ɵɵconditionalCreate(6, ComponentArtifactViewerComponent_Conditional_6_Template, 1, 2, "mj-component-feedback-panel", 5);
|
|
721
824
|
i0.ɵɵelementEnd();
|
|
722
825
|
} if (rf & 2) {
|
|
723
826
|
i0.ɵɵproperty("ngClass", ctx.cssClass);
|
|
724
827
|
i0.ɵɵadvance(2);
|
|
725
|
-
i0.ɵɵconditional(ctx.hasError ? 2 : ctx.isFormArtifact ? 3 : 4);
|
|
726
|
-
i0.ɵɵadvance(
|
|
727
|
-
i0.ɵɵconditional(ctx.ShowFeedbackPanel && ctx.resolvedComponentSpec ?
|
|
728
|
-
} }, dependencies: [i2.NgClass, i1.MJReactComponent, i3.InteractiveFormComponent, i4.ComponentFeedbackPanelComponent], styles: [".component-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface);\n}\n\n.component-preview[_ngcontent-%COMP%] {\n flex: 1;\n padding: 15px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n\n\n.component-preview[_ngcontent-%COMP%] mj-react-component[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-status-error);\n flex: 1;\n min-height: 300px;\n}\n.error-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n}\n.error-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n}\n.error-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: var(--mj-text-muted);\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] {\n margin-top: 16px;\n text-align: left;\n max-width: 600px;\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] {\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-bottom: 8px;\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.no-code-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-muted);\n flex: 1;\n}\n.no-code-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-brand-primary);\n}\n.no-code-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-secondary);\n}\n.no-code-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n\n\n\n\n\n.form-artifact-toolstrip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n.form-artifact-toolstrip-label[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n.form-artifact-toolstrip-entity[_ngcontent-%COMP%] {\n margin-left: 4px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n}\n.form-artifact-toolstrip-warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text);\n}\n\n.form-artifact-picker-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.form-artifact-picker-chip[_ngcontent-%COMP%]:hover, \n.form-artifact-picker-chip[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-border-focus);\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-chip[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n.form-artifact-picker-chip-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 999px;\n}\n\n.form-artifact-apply-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n.form-artifact-apply-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.form-artifact-picker-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-artifact-picker-search[_ngcontent-%COMP%] {\n width: 100%;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.form-artifact-picker-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-results[_ngcontent-%COMP%] {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.form-artifact-picker-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n}\n.form-artifact-picker-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.form-artifact-picker-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n.form-artifact-picker-empty[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.form-artifact-form-host[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}"] });
|
|
828
|
+
i0.ɵɵconditional(ctx.hasError ? 2 : ctx.isFormArtifact ? 3 : ctx.isPermissionBlocked ? 4 : 5);
|
|
829
|
+
i0.ɵɵadvance(4);
|
|
830
|
+
i0.ɵɵconditional(ctx.ShowFeedbackPanel && ctx.resolvedComponentSpec ? 6 : -1);
|
|
831
|
+
} }, dependencies: [i2.NgClass, i1.MJReactComponent, i3.InteractiveFormComponent, i4.ComponentFeedbackPanelComponent], styles: [".component-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface);\n}\n\n.component-preview[_ngcontent-%COMP%] {\n flex: 1;\n padding: 15px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n\n\n.component-preview[_ngcontent-%COMP%] mj-react-component[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-status-error);\n flex: 1;\n min-height: 300px;\n}\n.error-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n}\n.error-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n}\n.error-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: var(--mj-text-muted);\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] {\n margin-top: 16px;\n text-align: left;\n max-width: 600px;\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] {\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-bottom: 8px;\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n.error-state[_ngcontent-%COMP%] details[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.no-code-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-muted);\n flex: 1;\n}\n.no-code-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-brand-primary);\n}\n.no-code-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-secondary);\n}\n.no-code-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n\n\n\n\n\n.form-artifact-toolstrip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n.form-artifact-toolstrip-label[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n.form-artifact-toolstrip-entity[_ngcontent-%COMP%] {\n margin-left: 4px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n}\n.form-artifact-toolstrip-warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text);\n}\n\n.form-artifact-picker-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.form-artifact-picker-chip[_ngcontent-%COMP%]:hover, \n.form-artifact-picker-chip[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-border-focus);\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-chip[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n.form-artifact-picker-chip-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 999px;\n}\n\n.form-artifact-apply-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n.form-artifact-apply-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.form-artifact-picker-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-artifact-picker-search[_ngcontent-%COMP%] {\n width: 100%;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.form-artifact-picker-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-results[_ngcontent-%COMP%] {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.form-artifact-picker-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n}\n.form-artifact-picker-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.form-artifact-picker-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n.form-artifact-picker-empty[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.form-artifact-form-host[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n\n\n\n\n\n\n\n.permission-warning[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n flex: 1;\n min-height: 300px;\n}\n.permission-warning-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-status-warning-text, #b45309);\n}\n.permission-warning[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-primary);\n}\n.permission-warning[_ngcontent-%COMP%] > p[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n color: var(--mj-text-muted);\n}\n.permission-warning-section[_ngcontent-%COMP%] {\n text-align: left;\n max-width: 400px;\n width: 100%;\n margin-bottom: 12px;\n}\n.permission-warning-section-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n.permission-warning-section[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.permission-warning-section[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken, var(--mj-bg-surface));\n border-radius: 6px;\n}\n.permission-warning-section[_ngcontent-%COMP%] li[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text, #b45309);\n font-size: 12px;\n}\n.permission-warning-hint[_ngcontent-%COMP%] {\n margin-top: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}"] });
|
|
729
832
|
};
|
|
730
833
|
ComponentArtifactViewerComponent = __decorate([
|
|
731
834
|
RegisterClass(BaseArtifactViewerPluginComponent, 'ComponentArtifactViewerPlugin')
|
|
@@ -733,8 +836,8 @@ ComponentArtifactViewerComponent = __decorate([
|
|
|
733
836
|
export { ComponentArtifactViewerComponent };
|
|
734
837
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentArtifactViewerComponent, [{
|
|
735
838
|
type: Component,
|
|
736
|
-
args: [{ standalone: false, selector: 'mj-component-artifact-viewer', template: "<div class=\"component-artifact-viewer\" [ngClass]=\"cssClass\">\n <!-- Component Preview (full screen) -->\n <div class=\"component-preview\">\n @if (hasError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>{{ errorMessage }}</h3>\n <p>This component could not be loaded. This usually happens when:</p>\n <ul style=\"text-align: left; max-width: 500px; color: var(--mj-text-muted); line-height: 1.6;\">\n <li>The component registry is unavailable or unreachable</li>\n <li>The component version does not exist in the registry</li>\n <li>There was a network error during component retrieval</li>\n </ul>\n @if (errorDetails) {\n <details style=\"margin-top: 20px;\">\n <summary>Technical Details</summary>\n <pre>{{ errorDetails }}</pre>\n </details>\n }\n </div>\n } @else if (isFormArtifact) {\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FORM-AWARE BRANCH\n Spec declares componentRole: 'form'. Render via\n <mj-interactive-form> bound to a real Top-1 record\n (or a synthetic NewRecord fallback). Picker chip\n lets the user swap records; Apply promotes the\n spec to an EntityFormOverride.\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <div class=\"form-artifact-toolstrip\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n <span class=\"form-artifact-toolstrip-label\">Previewing record:</span>\n <button\n type=\"button\"\n class=\"form-artifact-picker-chip\"\n (click)=\"showRecordPicker = !showRecordPicker\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <strong>{{ formRecordLabel || 'No record' }}</strong>\n @if (!formRecordIsReal) {\n <span class=\"form-artifact-picker-chip-badge\">Mock</span>\n }\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n @if (formEntityInfo) {\n <span class=\"form-artifact-toolstrip-entity\">{{ formEntityInfo.DisplayName || formEntityInfo.Name }}</span>\n }\n @if (formInitError) {\n <span class=\"form-artifact-toolstrip-warning\" [title]=\"formInitError\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </span>\n }\n <span style=\"flex: 1;\"></span>\n @if (formEntityInfo) {\n <button\n type=\"button\"\n class=\"form-artifact-apply-btn\"\n (click)=\"onApplyClicked()\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Apply to my form\n </button>\n }\n </div>\n\n @if (showRecordPicker && formEntityInfo) {\n <div class=\"form-artifact-picker-panel\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"text\"\n class=\"form-artifact-picker-search\"\n placeholder=\"Search records by name\u2026\"\n [value]=\"recordSearchTerm\"\n (input)=\"onPickerSearchInput($any($event.target).value)\" />\n @if (recordSearchResults.length > 0) {\n <ul class=\"form-artifact-picker-results\">\n @for (r of recordSearchResults; track r.ID) {\n <li\n class=\"form-artifact-picker-row\"\n (click)=\"onPickerSelect(r)\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n <span>{{ r.Label }}</span>\n </li>\n }\n </ul>\n } @else if (recordSearchTerm.length > 0) {\n <div class=\"form-artifact-picker-empty\">No matches.</div>\n } @else {\n <div class=\"form-artifact-picker-empty\">Start typing to search.</div>\n }\n </div>\n }\n\n @if (formRecord && component) {\n <div class=\"form-artifact-form-host\">\n <mj-interactive-form\n [componentSpec]=\"component\"\n [record]=\"formRecord\">\n </mj-interactive-form>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>Form preview unavailable</h3>\n <p>{{ formInitError || 'Could not bind a record to this form.' }}</p>\n </div>\n }\n } @else {\n <!-- Default (non-form) interactive component path -->\n @if (component && (component.code || component.namespace)) {\n <mj-react-component\n #reactComponent\n [component]=\"component\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (initialized)=\"onReactComponentInitialized()\">\n </mj-react-component>\n } @else if (component) {\n <!-- Component spec exists but no code - show informational message -->\n <div class=\"no-code-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <h3>Component Specification</h3>\n <p>This component has specifications but no executable code yet.</p>\n <p>View the Functional, Data, or Spec tabs for details.</p>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>No Component Loaded</h3>\n <p>The component data is missing or invalid.</p>\n </div>\n }\n }\n </div>\n\n <!-- Feedback overlay panel (invoked from header button via AskUserForFeedback) -->\n @if (ShowFeedbackPanel && resolvedComponentSpec) {\n <mj-component-feedback-panel\n [ComponentSpec]=\"resolvedComponentSpec\"\n [ReactContainerElement]=\"reactComponent?.container?.nativeElement || null\"\n (Closed)=\"ShowFeedbackPanel = false\">\n </mj-component-feedback-panel>\n }\n</div>\n", styles: [".component-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface);\n}\n\n.component-preview {\n flex: 1;\n padding: 15px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n/* Ensure React component takes full height */\n.component-preview mj-react-component {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-status-error);\n flex: 1;\n min-height: 300px;\n}\n.error-state i {\n font-size: 48px;\n margin-bottom: 16px;\n}\n.error-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n}\n.error-state p {\n margin: 0 0 12px 0;\n color: var(--mj-text-muted);\n}\n.error-state details {\n margin-top: 16px;\n text-align: left;\n max-width: 600px;\n}\n.error-state details summary {\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-bottom: 8px;\n}\n.error-state details summary:hover {\n color: var(--mj-text-primary);\n}\n.error-state details pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* State for component spec without executable code */\n.no-code-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-muted);\n flex: 1;\n}\n.no-code-state i {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-brand-primary);\n}\n.no-code-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-secondary);\n}\n.no-code-state p {\n margin: 0 0 8px 0;\n color: var(--mj-text-muted);\n}\n\n\n/* ====================================================================\n FORM-AWARE BRANCH (componentRole === 'form')\n Top strip: record-picker chip + Apply button.\n Below: dropdown picker panel.\n Below: <mj-interactive-form> bound to the picked record.\n ==================================================================== */\n\n.form-artifact-toolstrip {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n.form-artifact-toolstrip-label {\n font-weight: 600;\n}\n.form-artifact-toolstrip-entity {\n margin-left: 4px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n}\n.form-artifact-toolstrip-warning {\n color: var(--mj-status-warning-text);\n}\n\n.form-artifact-picker-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.form-artifact-picker-chip:hover,\n.form-artifact-picker-chip:focus {\n border-color: var(--mj-border-focus);\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-chip strong {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n.form-artifact-picker-chip-badge {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 999px;\n}\n\n.form-artifact-apply-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n.form-artifact-apply-btn:hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.form-artifact-picker-panel {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-artifact-picker-search {\n width: 100%;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.form-artifact-picker-search:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-results {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.form-artifact-picker-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n}\n.form-artifact-picker-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n.form-artifact-picker-row i {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n.form-artifact-picker-empty {\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.form-artifact-form-host {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n"] }]
|
|
737
|
-
}], () => [{ type: i1.AngularAdapterService }], { reactComponent: [{
|
|
839
|
+
args: [{ standalone: false, selector: 'mj-component-artifact-viewer', template: "<div class=\"component-artifact-viewer\" [ngClass]=\"cssClass\">\n <!-- Component Preview (full screen) -->\n <div class=\"component-preview\">\n @if (hasError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>{{ errorMessage }}</h3>\n <p>This component could not be loaded. This usually happens when:</p>\n <ul style=\"text-align: left; max-width: 500px; color: var(--mj-text-muted); line-height: 1.6;\">\n <li>The component registry is unavailable or unreachable</li>\n <li>The component version does not exist in the registry</li>\n <li>There was a network error during component retrieval</li>\n </ul>\n @if (errorDetails) {\n <details style=\"margin-top: 20px;\">\n <summary>Technical Details</summary>\n <pre>{{ errorDetails }}</pre>\n </details>\n }\n </div>\n } @else if (isFormArtifact) {\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FORM-AWARE BRANCH\n Spec declares componentRole: 'form'. Render via\n <mj-interactive-form> bound to a real Top-1 record\n (or a synthetic NewRecord fallback). Picker chip\n lets the user swap records; Apply promotes the\n spec to an EntityFormOverride.\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <div class=\"form-artifact-toolstrip\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n <span class=\"form-artifact-toolstrip-label\">Previewing record:</span>\n <button\n type=\"button\"\n class=\"form-artifact-picker-chip\"\n (click)=\"showRecordPicker = !showRecordPicker\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <strong>{{ formRecordLabel || 'No record' }}</strong>\n @if (!formRecordIsReal) {\n <span class=\"form-artifact-picker-chip-badge\">Mock</span>\n }\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n @if (formEntityInfo) {\n <span class=\"form-artifact-toolstrip-entity\">{{ formEntityInfo.DisplayName || formEntityInfo.Name }}</span>\n }\n @if (formInitError) {\n <span class=\"form-artifact-toolstrip-warning\" [title]=\"formInitError\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </span>\n }\n <span style=\"flex: 1;\"></span>\n @if (formEntityInfo) {\n <button\n type=\"button\"\n class=\"form-artifact-apply-btn\"\n (click)=\"onApplyClicked()\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Apply to my form\n </button>\n }\n </div>\n\n @if (showRecordPicker && formEntityInfo) {\n <div class=\"form-artifact-picker-panel\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"text\"\n class=\"form-artifact-picker-search\"\n placeholder=\"Search records by name\u2026\"\n [value]=\"recordSearchTerm\"\n (input)=\"onPickerSearchInput($any($event.target).value)\" />\n @if (recordSearchResults.length > 0) {\n <ul class=\"form-artifact-picker-results\">\n @for (r of recordSearchResults; track r.ID) {\n <li\n class=\"form-artifact-picker-row\"\n (click)=\"onPickerSelect(r)\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n <span>{{ r.Label }}</span>\n </li>\n }\n </ul>\n } @else if (recordSearchTerm.length > 0) {\n <div class=\"form-artifact-picker-empty\">No matches.</div>\n } @else {\n <div class=\"form-artifact-picker-empty\">Start typing to search.</div>\n }\n </div>\n }\n\n @if (formRecord && component) {\n <div class=\"form-artifact-form-host\">\n <mj-interactive-form\n [componentSpec]=\"component\"\n [record]=\"formRecord\">\n </mj-interactive-form>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>Form preview unavailable</h3>\n <p>{{ formInitError || 'Could not bind a record to this form.' }}</p>\n </div>\n }\n } @else if (isPermissionBlocked) {\n <!-- Permission warning \u2014 user lacks access to one or more data sources -->\n <div class=\"permission-warning\">\n <div class=\"permission-warning-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <h3>Insufficient Permissions</h3>\n <p>This component requires data access that you don't currently have:</p>\n\n @if (permissionResult!.missingEntities.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Entities</span>\n <ul>\n @for (entity of permissionResult!.missingEntities; track entity) {\n <li><i class=\"fa-solid fa-table\"></i> {{ entity }}</li>\n }\n </ul>\n </div>\n }\n\n @if (permissionResult!.missingQueries.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Queries</span>\n <ul>\n @for (query of permissionResult!.missingQueries; track query) {\n <li><i class=\"fa-solid fa-database\"></i> {{ query }}</li>\n }\n </ul>\n </div>\n }\n\n <p class=\"permission-warning-hint\">Contact your administrator to request access.</p>\n </div>\n } @else {\n <!-- Default (non-form) interactive component path -->\n @if (component && (component.code || component.namespace)) {\n <mj-react-component\n #reactComponent\n [component]=\"component\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (initialized)=\"onReactComponentInitialized()\">\n </mj-react-component>\n } @else if (component) {\n <!-- Component spec exists but no code - show informational message -->\n <div class=\"no-code-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <h3>Component Specification</h3>\n <p>This component has specifications but no executable code yet.</p>\n <p>View the Functional, Data, or Spec tabs for details.</p>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>No Component Loaded</h3>\n <p>The component data is missing or invalid.</p>\n </div>\n }\n }\n </div>\n\n <!-- Feedback overlay panel (invoked from header button via AskUserForFeedback) -->\n @if (ShowFeedbackPanel && resolvedComponentSpec) {\n <mj-component-feedback-panel\n [ComponentSpec]=\"resolvedComponentSpec\"\n [ReactContainerElement]=\"reactComponent?.container?.nativeElement || null\"\n (Closed)=\"ShowFeedbackPanel = false\">\n </mj-component-feedback-panel>\n }\n</div>\n", styles: [".component-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface);\n}\n\n.component-preview {\n flex: 1;\n padding: 15px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n/* Ensure React component takes full height */\n.component-preview mj-react-component {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-status-error);\n flex: 1;\n min-height: 300px;\n}\n.error-state i {\n font-size: 48px;\n margin-bottom: 16px;\n}\n.error-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n}\n.error-state p {\n margin: 0 0 12px 0;\n color: var(--mj-text-muted);\n}\n.error-state details {\n margin-top: 16px;\n text-align: left;\n max-width: 600px;\n}\n.error-state details summary {\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-bottom: 8px;\n}\n.error-state details summary:hover {\n color: var(--mj-text-primary);\n}\n.error-state details pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* State for component spec without executable code */\n.no-code-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-muted);\n flex: 1;\n}\n.no-code-state i {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-brand-primary);\n}\n.no-code-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-secondary);\n}\n.no-code-state p {\n margin: 0 0 8px 0;\n color: var(--mj-text-muted);\n}\n\n\n/* ====================================================================\n FORM-AWARE BRANCH (componentRole === 'form')\n Top strip: record-picker chip + Apply button.\n Below: dropdown picker panel.\n Below: <mj-interactive-form> bound to the picked record.\n ==================================================================== */\n\n.form-artifact-toolstrip {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n.form-artifact-toolstrip-label {\n font-weight: 600;\n}\n.form-artifact-toolstrip-entity {\n margin-left: 4px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n}\n.form-artifact-toolstrip-warning {\n color: var(--mj-status-warning-text);\n}\n\n.form-artifact-picker-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.form-artifact-picker-chip:hover,\n.form-artifact-picker-chip:focus {\n border-color: var(--mj-border-focus);\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-chip strong {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n.form-artifact-picker-chip-badge {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 999px;\n}\n\n.form-artifact-apply-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n.form-artifact-apply-btn:hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.form-artifact-picker-panel {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-artifact-picker-search {\n width: 100%;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.form-artifact-picker-search:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-results {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.form-artifact-picker-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n}\n.form-artifact-picker-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n.form-artifact-picker-row i {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n.form-artifact-picker-empty {\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.form-artifact-form-host {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n/* ====================================================================\n PERMISSION WARNING\n Shown before rendering when the user lacks read access to one or\n more entities/queries required by the component.\n ==================================================================== */\n\n.permission-warning {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n flex: 1;\n min-height: 300px;\n}\n.permission-warning-icon {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-status-warning-text, #b45309);\n}\n.permission-warning h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-primary);\n}\n.permission-warning > p {\n margin: 0 0 16px 0;\n color: var(--mj-text-muted);\n}\n.permission-warning-section {\n text-align: left;\n max-width: 400px;\n width: 100%;\n margin-bottom: 12px;\n}\n.permission-warning-section-label {\n display: block;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n.permission-warning-section ul {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.permission-warning-section li {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken, var(--mj-bg-surface));\n border-radius: 6px;\n}\n.permission-warning-section li i {\n color: var(--mj-status-warning-text, #b45309);\n font-size: 12px;\n}\n.permission-warning-hint {\n margin-top: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n"] }]
|
|
840
|
+
}], () => [{ type: i1.AngularAdapterService }, { type: i0.ChangeDetectorRef }], { reactComponent: [{
|
|
738
841
|
type: ViewChild,
|
|
739
842
|
args: ['reactComponent']
|
|
740
843
|
}], tabsChanged: [{
|
|
@@ -744,5 +847,5 @@ export { ComponentArtifactViewerComponent };
|
|
|
744
847
|
}], applyFormRequested: [{
|
|
745
848
|
type: Output
|
|
746
849
|
}] }); })();
|
|
747
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentArtifactViewerComponent, { className: "ComponentArtifactViewerComponent", filePath: "src/lib/components/plugins/component-artifact-viewer.component.ts", lineNumber:
|
|
850
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentArtifactViewerComponent, { className: "ComponentArtifactViewerComponent", filePath: "src/lib/components/plugins/component-artifact-viewer.component.ts", lineNumber: 26 }); })();
|
|
748
851
|
//# sourceMappingURL=component-artifact-viewer.component.js.map
|