@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.
@@ -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", 7)(1, "summary");
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", 5);
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", 6)(7, "li");
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", 7);
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", 13);
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", 15);
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", 16);
76
- i0.ɵɵelement(1, "i", 21);
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", 22);
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", 23);
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", 29);
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", 30);
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", 26);
105
- i0.ɵɵrepeaterCreate(1, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_2_For_2_Template, 4, 1, "li", 28, _forTrack0);
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", 27);
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", 27);
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", 24);
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", 25);
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", 26)(3, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_3_Template, 2, 0, "div", 27)(4, ComponentArtifactViewerComponent_Conditional_3_Conditional_14_Conditional_4_Template, 2, 0, "div", 27);
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", 20);
140
- i0.ɵɵelement(1, "mj-interactive-form", 31);
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", 32);
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", 8);
164
- i0.ɵɵelement(1, "i", 9);
165
- i0.ɵɵelementStart(2, "span", 10);
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", 11);
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", 12);
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", 13);
175
- i0.ɵɵelement(9, "i", 14);
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", 15);
178
- i0.ɵɵconditionalCreate(11, ComponentArtifactViewerComponent_Conditional_3_Conditional_11_Template, 2, 1, "span", 16);
179
- i0.ɵɵelement(12, "span", 17);
180
- i0.ɵɵconditionalCreate(13, ComponentArtifactViewerComponent_Conditional_3_Conditional_13_Template, 3, 0, "button", 18);
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", 19);
183
- i0.ɵɵconditionalCreate(15, ComponentArtifactViewerComponent_Conditional_3_Conditional_15_Template, 2, 2, "div", 20)(16, ComponentArtifactViewerComponent_Conditional_3_Conditional_16_Template, 6, 1, "div", 3);
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 ComponentArtifactViewerComponent_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
202
- const _r7 = i0.ɵɵgetCurrentView();
203
- i0.ɵɵelementStart(0, "mj-react-component", 35, 0);
204
- i0.ɵɵlistener("componentEvent", function ComponentArtifactViewerComponent_Conditional_4_Conditional_0_Template_mj_react_component_componentEvent_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onComponentEvent($event)); })("openEntityRecord", function ComponentArtifactViewerComponent_Conditional_4_Conditional_0_Template_mj_react_component_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("initialized", function ComponentArtifactViewerComponent_Conditional_4_Conditional_0_Template_mj_react_component_initialized_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onReactComponentInitialized()); });
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 ComponentArtifactViewerComponent_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
211
- i0.ɵɵelementStart(0, "div", 34);
212
- i0.ɵɵelement(1, "i", 36);
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 ComponentArtifactViewerComponent_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
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", 32);
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 ComponentArtifactViewerComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
234
- i0.ɵɵconditionalCreate(0, ComponentArtifactViewerComponent_Conditional_4_Conditional_0_Template, 2, 1, "mj-react-component", 33)(1, ComponentArtifactViewerComponent_Conditional_4_Conditional_1_Template, 8, 0, "div", 34)(2, ComponentArtifactViewerComponent_Conditional_4_Conditional_2_Template, 6, 0, "div", 3);
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 ComponentArtifactViewerComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
240
- const _r8 = i0.ɵɵgetCurrentView();
241
- i0.ɵɵelementStart(0, "mj-component-feedback-panel", 37);
242
- i0.ɵɵlistener("Closed", function ComponentArtifactViewerComponent_Conditional_5_Template_mj_component_feedback_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ShowFeedbackPanel = false); });
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: 6, vars: 3, consts: [["reactComponent", ""], [1, "component-artifact-viewer", 3, "ngClass"], [1, "component-preview"], [1, "error-state"], [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"], [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) {
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(5, ComponentArtifactViewerComponent_Conditional_5_Template, 1, 2, "mj-component-feedback-panel", 4);
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(3);
727
- i0.ɵɵconditional(ctx.ShowFeedbackPanel && ctx.resolvedComponentSpec ? 5 : -1);
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: 25 }); })();
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