@memberjunction/ng-artifacts 5.43.0 → 5.44.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/README.md +6 -0
- package/dist/lib/artifacts.module.d.ts +28 -25
- package/dist/lib/artifacts.module.d.ts.map +1 -1
- package/dist/lib/artifacts.module.js +22 -2
- package/dist/lib/artifacts.module.js.map +1 -1
- package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-history.component.js +26 -29
- package/dist/lib/components/artifact-version-history.component.js.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +3 -0
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +198 -112
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +11 -0
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js +37 -12
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +40 -51
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +27 -47
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +89 -95
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +227 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +630 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -0
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +11 -0
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.js +37 -12
- package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +18 -4
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.js +54 -21
- package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts +19 -5
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.js +54 -22
- package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +21 -18
- package/dist/__tests__/exports.test.d.ts +0 -2
- package/dist/__tests__/exports.test.d.ts.map +0 -1
- package/dist/__tests__/exports.test.js +0 -17
- package/dist/__tests__/exports.test.js.map +0 -1
- package/dist/__tests__/image-artifact-viewer.test.d.ts +0 -2
- package/dist/__tests__/image-artifact-viewer.test.d.ts.map +0 -1
- package/dist/__tests__/image-artifact-viewer.test.js +0 -62
- package/dist/__tests__/image-artifact-viewer.test.js.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -7
- package/dist/__tests__/index.test.js.map +0 -1
- package/dist/lib/__tests__/artifact-snapshots.test.d.ts +0 -2
- package/dist/lib/__tests__/artifact-snapshots.test.d.ts.map +0 -1
- package/dist/lib/__tests__/artifact-snapshots.test.js +0 -155
- package/dist/lib/__tests__/artifact-snapshots.test.js.map +0 -1
- package/dist/lib/__tests__/interactive-form-apply.service.test.d.ts +0 -2
- package/dist/lib/__tests__/interactive-form-apply.service.test.d.ts.map +0 -1
- package/dist/lib/__tests__/interactive-form-apply.service.test.js +0 -211
- package/dist/lib/__tests__/interactive-form-apply.service.test.js.map +0 -1
|
@@ -15,7 +15,8 @@ import * as i3 from "../services/artifact-icon.service";
|
|
|
15
15
|
import * as i4 from "@angular/common";
|
|
16
16
|
import * as i5 from "@memberjunction/ng-markdown";
|
|
17
17
|
import * as i6 from "@memberjunction/ng-code-editor";
|
|
18
|
-
import * as i7 from "
|
|
18
|
+
import * as i7 from "@memberjunction/ng-ui-components";
|
|
19
|
+
import * as i8 from "./artifact-type-plugin-viewer.component";
|
|
19
20
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
20
21
|
const _forTrack1 = ($index, $item) => $item.id;
|
|
21
22
|
function ArtifactViewerPanelComponent_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -179,15 +180,10 @@ function ArtifactViewerPanelComponent_Conditional_3_Template(rf, ctx) { if (rf &
|
|
|
179
180
|
i0.ɵɵelementEnd()();
|
|
180
181
|
} }
|
|
181
182
|
function ArtifactViewerPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
182
|
-
i0.ɵɵ
|
|
183
|
-
i0.ɵɵelement(1, "i", 38);
|
|
184
|
-
i0.ɵɵelementStart(2, "span");
|
|
185
|
-
i0.ɵɵtext(3);
|
|
186
|
-
i0.ɵɵelementEnd()();
|
|
183
|
+
i0.ɵɵelement(0, "mj-empty-state", 4);
|
|
187
184
|
} if (rf & 2) {
|
|
188
185
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
189
|
-
i0.ɵɵ
|
|
190
|
-
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
186
|
+
i0.ɵɵproperty("Message", ctx_r1.error);
|
|
191
187
|
} }
|
|
192
188
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
193
189
|
i0.ɵɵelement(0, "i");
|
|
@@ -198,9 +194,9 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditio
|
|
|
198
194
|
} }
|
|
199
195
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
200
196
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
201
|
-
i0.ɵɵelementStart(0, "button",
|
|
197
|
+
i0.ɵɵelementStart(0, "button", 52);
|
|
202
198
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template_button_click_0_listener() { const tab_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SetActiveTab(tab_r12)); });
|
|
203
|
-
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditional_1_Template, 1, 2, "i",
|
|
199
|
+
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditional_1_Template, 1, 2, "i", 53);
|
|
204
200
|
i0.ɵɵtext(2);
|
|
205
201
|
i0.ɵɵelementEnd();
|
|
206
202
|
} if (rf & 2) {
|
|
@@ -213,8 +209,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template
|
|
|
213
209
|
i0.ɵɵtextInterpolate1(" ", tab_r12, " ");
|
|
214
210
|
} }
|
|
215
211
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
216
|
-
i0.ɵɵelementStart(0, "div",
|
|
217
|
-
i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template, 3, 4, "button",
|
|
212
|
+
i0.ɵɵelementStart(0, "div", 39);
|
|
213
|
+
i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template, 3, 4, "button", 51, i0.ɵɵrepeaterTrackByIdentity);
|
|
218
214
|
i0.ɵɵelementEnd();
|
|
219
215
|
} if (rf & 2) {
|
|
220
216
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -223,7 +219,7 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template(rf, c
|
|
|
223
219
|
} }
|
|
224
220
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
225
221
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
226
|
-
i0.ɵɵelementStart(0, "div",
|
|
222
|
+
i0.ɵɵelementStart(0, "div", 54)(1, "mj-artifact-type-plugin-viewer", 55);
|
|
227
223
|
i0.ɵɵlistener("openEntityRecord", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_openEntityRecord_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onOpenEntityRecord($event)); })("navigationRequest", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_navigationRequest_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onNavigationRequest($event)); })("pluginLoaded", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_pluginLoaded_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onPluginLoaded()); })("tabsChanged", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_tabsChanged_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onTabsChanged()); })("applyFormRequested", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_applyFormRequested_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.applyFormRequested.emit($event)); });
|
|
228
224
|
i0.ɵɵelementEnd()();
|
|
229
225
|
} if (rf & 2) {
|
|
@@ -233,8 +229,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template(rf, c
|
|
|
233
229
|
i0.ɵɵproperty("artifactVersion", ctx_r1.artifactVersion)("artifactTypeName", ctx_r1.artifactTypeName)("contentType", ctx_r1.contentType)("readonly", true);
|
|
234
230
|
} }
|
|
235
231
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
236
|
-
i0.ɵɵelementStart(0, "div",
|
|
237
|
-
i0.ɵɵelement(1, "mj-markdown",
|
|
232
|
+
i0.ɵɵelementStart(0, "div", 61);
|
|
233
|
+
i0.ɵɵelement(1, "mj-markdown", 63);
|
|
238
234
|
i0.ɵɵelementEnd();
|
|
239
235
|
} if (rf & 2) {
|
|
240
236
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -242,31 +238,31 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_
|
|
|
242
238
|
i0.ɵɵproperty("data", ctx_r1.displayMarkdown)("enableCollapsibleHeadings", true)("enableLineNumbers", true)("enableSmartypants", true)("enableHtml", true);
|
|
243
239
|
} }
|
|
244
240
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
245
|
-
i0.ɵɵelement(0, "div",
|
|
241
|
+
i0.ɵɵelement(0, "div", 62);
|
|
246
242
|
} if (rf & 2) {
|
|
247
243
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
248
244
|
i0.ɵɵproperty("innerHTML", ctx_r1.displayHtml, i0.ɵɵsanitizeHtml);
|
|
249
245
|
} }
|
|
250
246
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
251
247
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
252
|
-
i0.ɵɵelementStart(0, "div",
|
|
248
|
+
i0.ɵɵelementStart(0, "div", 56)(1, "button", 57);
|
|
253
249
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onPrintDisplayContent()); });
|
|
254
|
-
i0.ɵɵelement(2, "i",
|
|
250
|
+
i0.ɵɵelement(2, "i", 58);
|
|
255
251
|
i0.ɵɵtext(3, " Print ");
|
|
256
252
|
i0.ɵɵelementEnd();
|
|
257
|
-
i0.ɵɵelementStart(4, "button",
|
|
253
|
+
i0.ɵɵelementStart(4, "button", 59);
|
|
258
254
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onCopyDisplayContent()); });
|
|
259
|
-
i0.ɵɵelement(5, "i",
|
|
255
|
+
i0.ɵɵelement(5, "i", 60);
|
|
260
256
|
i0.ɵɵtext(6, " Copy ");
|
|
261
257
|
i0.ɵɵelementEnd()();
|
|
262
|
-
i0.ɵɵconditionalCreate(7, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template, 2, 5, "div",
|
|
258
|
+
i0.ɵɵconditionalCreate(7, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template, 2, 5, "div", 61)(8, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_8_Template, 1, 1, "div", 62);
|
|
263
259
|
} if (rf & 2) {
|
|
264
260
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
265
261
|
i0.ɵɵadvance(7);
|
|
266
262
|
i0.ɵɵconditional(ctx_r1.displayMarkdown ? 7 : ctx_r1.displayHtml ? 8 : -1);
|
|
267
263
|
} }
|
|
268
264
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
269
|
-
i0.ɵɵelementStart(0, "div",
|
|
265
|
+
i0.ɵɵelementStart(0, "div", 42);
|
|
270
266
|
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template, 9, 1);
|
|
271
267
|
i0.ɵɵelementEnd();
|
|
272
268
|
} if (rf & 2) {
|
|
@@ -275,7 +271,7 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template(rf, c
|
|
|
275
271
|
i0.ɵɵconditional(ctx_r1.displayMarkdown || ctx_r1.displayHtml ? 1 : -1);
|
|
276
272
|
} }
|
|
277
273
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
278
|
-
i0.ɵɵelementStart(0, "div",
|
|
274
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "label");
|
|
279
275
|
i0.ɵɵtext(2, "Artifact Description");
|
|
280
276
|
i0.ɵɵelementEnd();
|
|
281
277
|
i0.ɵɵelementStart(3, "span");
|
|
@@ -287,7 +283,7 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_29_Template(rf,
|
|
|
287
283
|
i0.ɵɵtextInterpolate(ctx_r1.artifact.Description);
|
|
288
284
|
} }
|
|
289
285
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
290
|
-
i0.ɵɵelementStart(0, "div",
|
|
286
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "label");
|
|
291
287
|
i0.ɵɵtext(2, "Version Description");
|
|
292
288
|
i0.ɵɵelementEnd();
|
|
293
289
|
i0.ɵɵelementStart(3, "span");
|
|
@@ -308,15 +304,15 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditi
|
|
|
308
304
|
i0.ɵɵtextInterpolate(attr_r15.Value);
|
|
309
305
|
} }
|
|
310
306
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
311
|
-
i0.ɵɵelementStart(0, "span",
|
|
307
|
+
i0.ɵɵelementStart(0, "span", 66);
|
|
312
308
|
i0.ɵɵtext(1, "Empty");
|
|
313
309
|
i0.ɵɵelementEnd();
|
|
314
310
|
} }
|
|
315
311
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
316
|
-
i0.ɵɵelementStart(0, "div",
|
|
312
|
+
i0.ɵɵelementStart(0, "div", 65)(1, "label");
|
|
317
313
|
i0.ɵɵtext(2);
|
|
318
314
|
i0.ɵɵelementEnd();
|
|
319
|
-
i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template, 2, 0, "span",
|
|
315
|
+
i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template, 2, 0, "span", 66);
|
|
320
316
|
i0.ɵɵelementEnd();
|
|
321
317
|
} if (rf & 2) {
|
|
322
318
|
const attr_r15 = ctx.$implicit;
|
|
@@ -326,11 +322,11 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Templat
|
|
|
326
322
|
i0.ɵɵconditional(attr_r15.Value ? 3 : 4);
|
|
327
323
|
} }
|
|
328
324
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
329
|
-
i0.ɵɵelementStart(0, "div",
|
|
325
|
+
i0.ɵɵelementStart(0, "div", 47)(1, "h4");
|
|
330
326
|
i0.ɵɵtext(2, "Version Attributes");
|
|
331
327
|
i0.ɵɵelementEnd();
|
|
332
|
-
i0.ɵɵelementStart(3, "div",
|
|
333
|
-
i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template, 5, 2, "div",
|
|
328
|
+
i0.ɵɵelementStart(3, "div", 64);
|
|
329
|
+
i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template, 5, 2, "div", 65, _forTrack0);
|
|
334
330
|
i0.ɵɵelementEnd()();
|
|
335
331
|
} if (rf & 2) {
|
|
336
332
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -338,26 +334,26 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template(rf,
|
|
|
338
334
|
i0.ɵɵrepeater(ctx_r1.filteredAttributes);
|
|
339
335
|
} }
|
|
340
336
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
341
|
-
i0.ɵɵelement(0, "i",
|
|
337
|
+
i0.ɵɵelement(0, "i", 70);
|
|
342
338
|
} }
|
|
343
339
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
344
|
-
i0.ɵɵelement(0, "i",
|
|
340
|
+
i0.ɵɵelement(0, "i", 71);
|
|
345
341
|
} }
|
|
346
342
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
347
343
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
348
|
-
i0.ɵɵelementStart(0, "div",
|
|
344
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
349
345
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template_div_click_0_listener() { const link_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(link_r17.hasAccess ? ctx_r1.onNavigateToLink(link_r17) : null); });
|
|
350
|
-
i0.ɵɵelementStart(1, "div",
|
|
351
|
-
i0.ɵɵconditionalCreate(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template, 1, 0, "i",
|
|
346
|
+
i0.ɵɵelementStart(1, "div", 69);
|
|
347
|
+
i0.ɵɵconditionalCreate(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template, 1, 0, "i", 70)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_3_Template, 1, 0, "i", 71);
|
|
352
348
|
i0.ɵɵelementEnd();
|
|
353
|
-
i0.ɵɵelementStart(4, "div",
|
|
349
|
+
i0.ɵɵelementStart(4, "div", 72)(5, "div", 73);
|
|
354
350
|
i0.ɵɵtext(6);
|
|
355
351
|
i0.ɵɵelementEnd();
|
|
356
|
-
i0.ɵɵelementStart(7, "div",
|
|
352
|
+
i0.ɵɵelementStart(7, "div", 74);
|
|
357
353
|
i0.ɵɵtext(8);
|
|
358
354
|
i0.ɵɵelementEnd()();
|
|
359
|
-
i0.ɵɵelementStart(9, "div",
|
|
360
|
-
i0.ɵɵelement(10, "i",
|
|
355
|
+
i0.ɵɵelementStart(9, "div", 75);
|
|
356
|
+
i0.ɵɵelement(10, "i", 76);
|
|
361
357
|
i0.ɵɵelementEnd()();
|
|
362
358
|
} if (rf & 2) {
|
|
363
359
|
const link_r17 = ctx.$implicit;
|
|
@@ -371,8 +367,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Templat
|
|
|
371
367
|
i0.ɵɵtextInterpolate(link_r17.type === "conversation" ? "Conversation" : "Collection");
|
|
372
368
|
} }
|
|
373
369
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
374
|
-
i0.ɵɵelementStart(0, "div",
|
|
375
|
-
i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template, 11, 8, "div",
|
|
370
|
+
i0.ɵɵelementStart(0, "div", 49);
|
|
371
|
+
i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template, 11, 8, "div", 67, _forTrack1);
|
|
376
372
|
i0.ɵɵelementEnd();
|
|
377
373
|
} if (rf & 2) {
|
|
378
374
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -380,18 +376,14 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_Template(rf,
|
|
|
380
376
|
i0.ɵɵrepeater(ctx_r1.linksToShow);
|
|
381
377
|
} }
|
|
382
378
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
383
|
-
i0.ɵɵ
|
|
384
|
-
i0.ɵɵelement(1, "i", 78);
|
|
385
|
-
i0.ɵɵelementStart(2, "p");
|
|
386
|
-
i0.ɵɵtext(3, "No links available");
|
|
387
|
-
i0.ɵɵelementEnd()();
|
|
379
|
+
i0.ɵɵelement(0, "mj-empty-state", 50);
|
|
388
380
|
} }
|
|
389
381
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
390
382
|
i0.ɵɵelementContainer(0);
|
|
391
383
|
} }
|
|
392
384
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
393
|
-
i0.ɵɵelementStart(0, "div",
|
|
394
|
-
i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_ng_container_1_Template, 1, 0, "ng-container",
|
|
385
|
+
i0.ɵɵelementStart(0, "div", 77);
|
|
386
|
+
i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_ng_container_1_Template, 1, 0, "ng-container", 78);
|
|
395
387
|
i0.ɵɵelementEnd();
|
|
396
388
|
} if (rf & 2) {
|
|
397
389
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -399,8 +391,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0
|
|
|
399
391
|
i0.ɵɵproperty("ngComponentOutlet", ctx)("ngComponentOutletInputs", ctx_r1.GetComponentInputs(ctx_r1.activeTab));
|
|
400
392
|
} }
|
|
401
393
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template(rf, ctx) { if (rf & 1) {
|
|
402
|
-
i0.ɵɵelementStart(0, "div",
|
|
403
|
-
i0.ɵɵelement(1, "mj-markdown",
|
|
394
|
+
i0.ɵɵelementStart(0, "div", 80);
|
|
395
|
+
i0.ɵɵelement(1, "mj-markdown", 63);
|
|
404
396
|
i0.ɵɵelementEnd();
|
|
405
397
|
} if (rf & 2) {
|
|
406
398
|
const tabData_r18 = i0.ɵɵnextContext();
|
|
@@ -409,13 +401,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
|
|
|
409
401
|
} }
|
|
410
402
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
411
403
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
412
|
-
i0.ɵɵelementStart(0, "div",
|
|
404
|
+
i0.ɵɵelementStart(0, "div", 81)(1, "div", 85)(2, "button", 86);
|
|
413
405
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onCopyToClipboard()); });
|
|
414
|
-
i0.ɵɵelement(3, "i",
|
|
406
|
+
i0.ɵɵelement(3, "i", 60);
|
|
415
407
|
i0.ɵɵtext(4, " Copy ");
|
|
416
408
|
i0.ɵɵelementEnd()();
|
|
417
|
-
i0.ɵɵelementStart(5, "div",
|
|
418
|
-
i0.ɵɵelement(6, "mj-code-editor",
|
|
409
|
+
i0.ɵɵelementStart(5, "div", 87);
|
|
410
|
+
i0.ɵɵelement(6, "mj-code-editor", 88);
|
|
419
411
|
i0.ɵɵelementEnd()();
|
|
420
412
|
} if (rf & 2) {
|
|
421
413
|
const tabData_r18 = i0.ɵɵnextContext();
|
|
@@ -424,13 +416,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
|
|
|
424
416
|
} }
|
|
425
417
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
426
418
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
427
|
-
i0.ɵɵelementStart(0, "div",
|
|
419
|
+
i0.ɵɵelementStart(0, "div", 82)(1, "div", 89)(2, "button", 90);
|
|
428
420
|
i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onCopyToClipboard()); });
|
|
429
|
-
i0.ɵɵelement(3, "i",
|
|
421
|
+
i0.ɵɵelement(3, "i", 60);
|
|
430
422
|
i0.ɵɵtext(4, " Copy ");
|
|
431
423
|
i0.ɵɵelementEnd()();
|
|
432
|
-
i0.ɵɵelementStart(5, "div",
|
|
433
|
-
i0.ɵɵelement(6, "mj-code-editor",
|
|
424
|
+
i0.ɵɵelementStart(5, "div", 91);
|
|
425
|
+
i0.ɵɵelement(6, "mj-code-editor", 88);
|
|
434
426
|
i0.ɵɵelementEnd()();
|
|
435
427
|
} if (rf & 2) {
|
|
436
428
|
const tabData_r18 = i0.ɵɵnextContext();
|
|
@@ -438,13 +430,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
|
|
|
438
430
|
i0.ɵɵproperty("value", tabData_r18.content)("language", tabData_r18.language || "typescript")("readonly", true)("lineWrapping", true);
|
|
439
431
|
} }
|
|
440
432
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_4_Template(rf, ctx) { if (rf & 1) {
|
|
441
|
-
i0.ɵɵelement(0, "div",
|
|
433
|
+
i0.ɵɵelement(0, "div", 83);
|
|
442
434
|
} if (rf & 2) {
|
|
443
435
|
const tabData_r18 = i0.ɵɵnextContext();
|
|
444
436
|
i0.ɵɵproperty("innerHTML", tabData_r18.content, i0.ɵɵsanitizeHtml);
|
|
445
437
|
} }
|
|
446
438
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_5_Template(rf, ctx) { if (rf & 1) {
|
|
447
|
-
i0.ɵɵelementStart(0, "pre",
|
|
439
|
+
i0.ɵɵelementStart(0, "pre", 84);
|
|
448
440
|
i0.ɵɵtext(1);
|
|
449
441
|
i0.ɵɵelementEnd();
|
|
450
442
|
} if (rf & 2) {
|
|
@@ -453,8 +445,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
|
|
|
453
445
|
i0.ɵɵtextInterpolate(tabData_r18.content);
|
|
454
446
|
} }
|
|
455
447
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
456
|
-
i0.ɵɵelementStart(0, "div",
|
|
457
|
-
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template, 2, 5, "div",
|
|
448
|
+
i0.ɵɵelementStart(0, "div", 79);
|
|
449
|
+
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template, 2, 5, "div", 80)(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template, 7, 4, "div", 81)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template, 7, 4, "div", 82)(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_4_Template, 1, 1, "div", 83)(5, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_5_Template, 2, 1, "pre", 84);
|
|
458
450
|
i0.ɵɵelementEnd();
|
|
459
451
|
} if (rf & 2) {
|
|
460
452
|
let tmp_5_0;
|
|
@@ -462,58 +454,58 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
|
|
|
462
454
|
i0.ɵɵconditional((tmp_5_0 = ctx.type) === "markdown" ? 1 : tmp_5_0 === "json" ? 2 : tmp_5_0 === "code" ? 3 : tmp_5_0 === "html" ? 4 : tmp_5_0 === "plaintext" ? 5 : -1);
|
|
463
455
|
} }
|
|
464
456
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
465
|
-
i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template, 6, 1, "div",
|
|
457
|
+
i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template, 6, 1, "div", 79);
|
|
466
458
|
} if (rf & 2) {
|
|
467
459
|
let tmp_3_0;
|
|
468
460
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
469
461
|
i0.ɵɵconditional((tmp_3_0 = ctx_r1.GetTabContent(ctx_r1.activeTab)) ? 0 : -1, tmp_3_0);
|
|
470
462
|
} }
|
|
471
463
|
function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
472
|
-
i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template, 2, 2, "div",
|
|
464
|
+
i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template, 2, 2, "div", 77)(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Template, 1, 1);
|
|
473
465
|
} if (rf & 2) {
|
|
474
466
|
let tmp_2_0;
|
|
475
467
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
476
468
|
i0.ɵɵconditional((tmp_2_0 = ctx_r1.GetComponentTabType(ctx_r1.activeTab)) ? 0 : 1, tmp_2_0);
|
|
477
469
|
} }
|
|
478
470
|
function ArtifactViewerPanelComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
479
|
-
i0.ɵɵelementStart(0, "div",
|
|
480
|
-
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template, 3, 0, "div",
|
|
481
|
-
i0.ɵɵelementStart(2, "div",
|
|
482
|
-
i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template, 2, 6, "div",
|
|
483
|
-
i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template, 2, 1, "div",
|
|
484
|
-
i0.ɵɵelementStart(5, "div",
|
|
471
|
+
i0.ɵɵelementStart(0, "div", 38);
|
|
472
|
+
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template, 3, 0, "div", 39);
|
|
473
|
+
i0.ɵɵelementStart(2, "div", 40);
|
|
474
|
+
i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template, 2, 6, "div", 41);
|
|
475
|
+
i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template, 2, 1, "div", 42);
|
|
476
|
+
i0.ɵɵelementStart(5, "div", 43)(6, "div", 44)(7, "div", 45)(8, "label");
|
|
485
477
|
i0.ɵɵtext(9, "Type");
|
|
486
478
|
i0.ɵɵelementEnd();
|
|
487
479
|
i0.ɵɵelementStart(10, "span");
|
|
488
480
|
i0.ɵɵtext(11);
|
|
489
481
|
i0.ɵɵelementEnd()();
|
|
490
|
-
i0.ɵɵelementStart(12, "div",
|
|
482
|
+
i0.ɵɵelementStart(12, "div", 45)(13, "label");
|
|
491
483
|
i0.ɵɵtext(14, "Version");
|
|
492
484
|
i0.ɵɵelementEnd();
|
|
493
485
|
i0.ɵɵelementStart(15, "span");
|
|
494
486
|
i0.ɵɵtext(16);
|
|
495
487
|
i0.ɵɵelementEnd()();
|
|
496
|
-
i0.ɵɵelementStart(17, "div",
|
|
488
|
+
i0.ɵɵelementStart(17, "div", 45)(18, "label");
|
|
497
489
|
i0.ɵɵtext(19, "Created");
|
|
498
490
|
i0.ɵɵelementEnd();
|
|
499
491
|
i0.ɵɵelementStart(20, "span");
|
|
500
492
|
i0.ɵɵtext(21);
|
|
501
493
|
i0.ɵɵpipe(22, "date");
|
|
502
494
|
i0.ɵɵelementEnd()();
|
|
503
|
-
i0.ɵɵelementStart(23, "div",
|
|
495
|
+
i0.ɵɵelementStart(23, "div", 45)(24, "label");
|
|
504
496
|
i0.ɵɵtext(25, "Updated");
|
|
505
497
|
i0.ɵɵelementEnd();
|
|
506
498
|
i0.ɵɵelementStart(26, "span");
|
|
507
499
|
i0.ɵɵtext(27);
|
|
508
500
|
i0.ɵɵpipe(28, "date");
|
|
509
501
|
i0.ɵɵelementEnd()();
|
|
510
|
-
i0.ɵɵconditionalCreate(29, ArtifactViewerPanelComponent_Conditional_5_Conditional_29_Template, 5, 1, "div",
|
|
511
|
-
i0.ɵɵconditionalCreate(30, ArtifactViewerPanelComponent_Conditional_5_Conditional_30_Template, 5, 1, "div",
|
|
502
|
+
i0.ɵɵconditionalCreate(29, ArtifactViewerPanelComponent_Conditional_5_Conditional_29_Template, 5, 1, "div", 46);
|
|
503
|
+
i0.ɵɵconditionalCreate(30, ArtifactViewerPanelComponent_Conditional_5_Conditional_30_Template, 5, 1, "div", 46);
|
|
512
504
|
i0.ɵɵelementEnd();
|
|
513
|
-
i0.ɵɵconditionalCreate(31, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template, 6, 0, "div",
|
|
505
|
+
i0.ɵɵconditionalCreate(31, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template, 6, 0, "div", 47);
|
|
514
506
|
i0.ɵɵelementEnd();
|
|
515
|
-
i0.ɵɵelementStart(32, "div",
|
|
516
|
-
i0.ɵɵconditionalCreate(33, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_Template, 3, 0, "div",
|
|
507
|
+
i0.ɵɵelementStart(32, "div", 48);
|
|
508
|
+
i0.ɵɵconditionalCreate(33, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_Template, 3, 0, "div", 49)(34, ArtifactViewerPanelComponent_Conditional_5_Conditional_34_Template, 1, 0, "mj-empty-state", 50);
|
|
517
509
|
i0.ɵɵelementEnd();
|
|
518
510
|
i0.ɵɵconditionalCreate(35, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Template, 2, 1);
|
|
519
511
|
i0.ɵɵelementEnd()();
|
|
@@ -585,6 +577,7 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
585
577
|
applyFormRequested = new EventEmitter();
|
|
586
578
|
pluginViewer;
|
|
587
579
|
destroy$ = new Subject();
|
|
580
|
+
artifactLoadToken = 0;
|
|
588
581
|
artifact = null;
|
|
589
582
|
artifactVersion = null;
|
|
590
583
|
allVersions = [];
|
|
@@ -790,21 +783,43 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
790
783
|
this.destroy$.next();
|
|
791
784
|
this.destroy$.complete();
|
|
792
785
|
}
|
|
786
|
+
isCurrentArtifactLoad(artifactId, loadToken) {
|
|
787
|
+
return loadToken === this.artifactLoadToken && UUIDsEqual(artifactId, this.artifactId);
|
|
788
|
+
}
|
|
789
|
+
clearLoadedArtifactState() {
|
|
790
|
+
this.artifact = null;
|
|
791
|
+
this.artifactVersion = null;
|
|
792
|
+
this.allVersions = [];
|
|
793
|
+
this.versionAttributes = [];
|
|
794
|
+
this.jsonContent = '';
|
|
795
|
+
this.displayMarkdown = null;
|
|
796
|
+
this.displayHtml = null;
|
|
797
|
+
this.artifactCollections = [];
|
|
798
|
+
this.currentVersionCollections = [];
|
|
799
|
+
this.primaryCollection = null;
|
|
800
|
+
this.artifactTypeDriverClass = null;
|
|
801
|
+
this.artifactContentCategory = null;
|
|
802
|
+
this.clearLinksData();
|
|
803
|
+
}
|
|
793
804
|
async loadArtifact(targetVersionNumber) {
|
|
805
|
+
const artifactId = this.artifactId;
|
|
806
|
+
const loadToken = ++this.artifactLoadToken;
|
|
807
|
+
const isCurrentLoad = () => this.isCurrentArtifactLoad(artifactId, loadToken);
|
|
794
808
|
try {
|
|
795
809
|
this.isLoading = true;
|
|
796
810
|
this.error = null;
|
|
797
|
-
|
|
798
|
-
this.clearLinksData();
|
|
811
|
+
this.clearLoadedArtifactState();
|
|
799
812
|
const md = this.ProviderToUse;
|
|
800
813
|
// Load artifact — assign to local first to avoid mid-cycle icon flicker
|
|
801
814
|
const artifactEntity = await md.GetEntityObject('MJ: Artifacts', this.currentUser);
|
|
802
|
-
const loaded = await artifactEntity.Load(
|
|
815
|
+
const loaded = await artifactEntity.Load(artifactId);
|
|
816
|
+
if (!isCurrentLoad()) {
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
803
819
|
if (!loaded) {
|
|
804
820
|
this.error = 'Failed to load artifact';
|
|
805
821
|
return;
|
|
806
822
|
}
|
|
807
|
-
this.artifact = artifactEntity;
|
|
808
823
|
// PERF: Batch load version metadata, collection associations, and conversation links
|
|
809
824
|
// in a single RunViews call. Content is excluded here — loaded on-demand for the selected version.
|
|
810
825
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
@@ -812,7 +827,7 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
812
827
|
{
|
|
813
828
|
// [0] Version metadata (lightweight — no Content field)
|
|
814
829
|
EntityName: 'MJ: Artifact Versions',
|
|
815
|
-
ExtraFilter: `ArtifactID='${
|
|
830
|
+
ExtraFilter: `ArtifactID='${artifactId}'`,
|
|
816
831
|
OrderBy: 'VersionNumber DESC',
|
|
817
832
|
Fields: ['ID', 'ArtifactID', 'VersionNumber', 'Name', 'Description', '__mj_CreatedAt', '__mj_UpdatedAt'],
|
|
818
833
|
ResultType: 'simple'
|
|
@@ -821,7 +836,7 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
821
836
|
// [1] Collection associations for all versions of this artifact
|
|
822
837
|
EntityName: 'MJ: Collection Artifacts',
|
|
823
838
|
ExtraFilter: `ArtifactVersionID IN (
|
|
824
|
-
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${
|
|
839
|
+
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${artifactId}'
|
|
825
840
|
)`,
|
|
826
841
|
Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],
|
|
827
842
|
ResultType: 'simple'
|
|
@@ -830,19 +845,22 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
830
845
|
// [2] Conversation detail artifact links (for Links tab)
|
|
831
846
|
EntityName: 'MJ: Conversation Detail Artifacts',
|
|
832
847
|
ExtraFilter: `ArtifactVersionID IN (
|
|
833
|
-
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${
|
|
848
|
+
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${artifactId}'
|
|
834
849
|
)`,
|
|
835
850
|
Fields: ['ID', 'ConversationDetailID', 'ArtifactVersionID'],
|
|
836
851
|
MaxRows: 1,
|
|
837
852
|
ResultType: 'simple'
|
|
838
853
|
}
|
|
839
854
|
], this.currentUser);
|
|
855
|
+
if (!isCurrentLoad()) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
840
858
|
const [versionsResult, collectionsResult, convDetailResult] = batchResults;
|
|
841
859
|
if (!versionsResult.Success || !versionsResult.Results || versionsResult.Results.length === 0) {
|
|
842
860
|
this.error = 'No artifact version found';
|
|
843
861
|
return;
|
|
844
862
|
}
|
|
845
|
-
|
|
863
|
+
this.artifact = artifactEntity;
|
|
846
864
|
this.allVersions = versionsResult.Results;
|
|
847
865
|
// Determine which version to display
|
|
848
866
|
let selectedVersion;
|
|
@@ -854,9 +872,12 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
854
872
|
this.selectedVersionNumber = versionToLoad.VersionNumber || 1;
|
|
855
873
|
// PERF: Start artifact type resolution and selected version content load in parallel
|
|
856
874
|
const [, selectedVersionEntity] = await Promise.all([
|
|
857
|
-
this.loadArtifactType(),
|
|
875
|
+
this.loadArtifactType(artifactEntity.Type, artifactId, loadToken),
|
|
858
876
|
this.loadVersionContent(versionToLoad.ID)
|
|
859
877
|
]);
|
|
878
|
+
if (!isCurrentLoad()) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
860
881
|
if (selectedVersionEntity) {
|
|
861
882
|
this.artifactVersion = selectedVersionEntity;
|
|
862
883
|
this.jsonContent = this.FormatJSON(selectedVersionEntity.Content || '{}');
|
|
@@ -867,17 +888,26 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
867
888
|
}
|
|
868
889
|
// PERF: Process collection and links data in parallel (uses already-fetched batch data)
|
|
869
890
|
await Promise.all([
|
|
870
|
-
this.processCollectionAssociations(collectionsResult),
|
|
871
|
-
this.processLinksData(collectionsResult, convDetailResult)
|
|
891
|
+
this.processCollectionAssociations(collectionsResult, artifactId, loadToken),
|
|
892
|
+
this.processLinksData(collectionsResult, convDetailResult, artifactId, loadToken)
|
|
872
893
|
]);
|
|
894
|
+
if (!isCurrentLoad()) {
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
873
897
|
// Load version attributes (depends on selected version being set)
|
|
874
|
-
await this.loadVersionAttributes();
|
|
898
|
+
await this.loadVersionAttributes(artifactId, loadToken);
|
|
875
899
|
}
|
|
876
900
|
catch (err) {
|
|
901
|
+
if (!isCurrentLoad()) {
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
877
904
|
console.error('Error loading artifact:', err);
|
|
878
905
|
this.error = 'Error loading artifact: ' + err.message;
|
|
879
906
|
}
|
|
880
907
|
finally {
|
|
908
|
+
if (!isCurrentLoad()) {
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
881
911
|
this.isLoading = false;
|
|
882
912
|
this.updateArtifactIcon();
|
|
883
913
|
this.cdr.detectChanges();
|
|
@@ -908,19 +938,26 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
908
938
|
this.hasAccessToOriginConversation = false;
|
|
909
939
|
this.originConversationVersionId = null;
|
|
910
940
|
}
|
|
911
|
-
async loadArtifactType() {
|
|
912
|
-
|
|
941
|
+
async loadArtifactType(artifactTypeName = this.artifact?.Type, artifactId = this.artifactId, loadToken = this.artifactLoadToken) {
|
|
942
|
+
const isCurrentLoad = () => this.isCurrentArtifactLoad(artifactId, loadToken);
|
|
913
943
|
this.artifactTypeDriverClass = null;
|
|
914
944
|
this.artifactContentCategory = null;
|
|
915
|
-
if (!
|
|
945
|
+
if (!artifactTypeName) {
|
|
916
946
|
return;
|
|
917
947
|
}
|
|
918
948
|
try {
|
|
919
949
|
await ArtifactMetadataEngine.Instance.Config(false, this.currentUser);
|
|
920
|
-
|
|
950
|
+
if (!isCurrentLoad()) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
const artifactType = ArtifactMetadataEngine.Instance.FindArtifactType(artifactTypeName);
|
|
921
954
|
if (artifactType) {
|
|
922
955
|
// Resolve DriverClass by traversing parent hierarchy if needed
|
|
923
|
-
|
|
956
|
+
const driverClass = await this.resolveDriverClassForType(artifactType);
|
|
957
|
+
if (!isCurrentLoad()) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
this.artifactTypeDriverClass = driverClass;
|
|
924
961
|
this.artifactContentCategory = artifactType.ContentCategory;
|
|
925
962
|
}
|
|
926
963
|
}
|
|
@@ -929,7 +966,8 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
929
966
|
// Don't fail the whole load if we can't get the artifact type
|
|
930
967
|
}
|
|
931
968
|
}
|
|
932
|
-
async loadVersionAttributes() {
|
|
969
|
+
async loadVersionAttributes(artifactId = this.artifactId, loadToken = this.artifactLoadToken) {
|
|
970
|
+
const isCurrentLoad = () => this.isCurrentArtifactLoad(artifactId, loadToken);
|
|
933
971
|
if (!this.artifactVersion)
|
|
934
972
|
return;
|
|
935
973
|
try {
|
|
@@ -939,6 +977,9 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
939
977
|
ExtraFilter: `ArtifactVersionID='${this.artifactVersion.ID}'`,
|
|
940
978
|
ResultType: 'simple'
|
|
941
979
|
}, this.currentUser);
|
|
980
|
+
if (!isCurrentLoad()) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
942
983
|
if (result.Success && result.Results) {
|
|
943
984
|
this.versionAttributes = result.Results;
|
|
944
985
|
// Check for displayMarkdown or displayHtml attributes
|
|
@@ -956,10 +997,15 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
956
997
|
}
|
|
957
998
|
}
|
|
958
999
|
catch (err) {
|
|
1000
|
+
if (!isCurrentLoad()) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
959
1003
|
console.error('Error loading version attributes:', err);
|
|
960
1004
|
}
|
|
961
1005
|
finally {
|
|
962
|
-
|
|
1006
|
+
if (isCurrentLoad()) {
|
|
1007
|
+
this.cdr.detectChanges(); // zone.js 0.15: async RunView doesn't trigger CD
|
|
1008
|
+
}
|
|
963
1009
|
}
|
|
964
1010
|
}
|
|
965
1011
|
get displayName() {
|
|
@@ -1093,9 +1139,10 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1093
1139
|
* Process pre-fetched collection association data.
|
|
1094
1140
|
* Accepts the batch result from loadArtifact() to avoid duplicate queries.
|
|
1095
1141
|
*/
|
|
1096
|
-
async processCollectionAssociations(collectionsResult) {
|
|
1097
|
-
if (!
|
|
1142
|
+
async processCollectionAssociations(collectionsResult, artifactId = this.artifactId, loadToken = this.artifactLoadToken) {
|
|
1143
|
+
if (!artifactId)
|
|
1098
1144
|
return;
|
|
1145
|
+
const isCurrentLoad = () => this.isCurrentArtifactLoad(artifactId, loadToken);
|
|
1099
1146
|
try {
|
|
1100
1147
|
// If no pre-fetched data, fetch it (used by selectVersion/saveToCollections reload)
|
|
1101
1148
|
let collectionRows;
|
|
@@ -1107,13 +1154,16 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1107
1154
|
const result = await rv.RunView({
|
|
1108
1155
|
EntityName: 'MJ: Collection Artifacts',
|
|
1109
1156
|
ExtraFilter: `ArtifactVersionID IN (
|
|
1110
|
-
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${
|
|
1157
|
+
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${artifactId}'
|
|
1111
1158
|
)`,
|
|
1112
1159
|
Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],
|
|
1113
1160
|
ResultType: 'simple'
|
|
1114
1161
|
}, this.currentUser);
|
|
1115
1162
|
collectionRows = (result.Success ? result.Results : []);
|
|
1116
1163
|
}
|
|
1164
|
+
if (!isCurrentLoad()) {
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1117
1167
|
// Store as simple objects — these are read-only display data
|
|
1118
1168
|
this.artifactCollections = collectionRows;
|
|
1119
1169
|
// Filter to get only collections containing the CURRENT version
|
|
@@ -1134,8 +1184,12 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1134
1184
|
this.artifactCollections[0].CollectionID;
|
|
1135
1185
|
if (collectionId) {
|
|
1136
1186
|
const md = this.ProviderToUse;
|
|
1137
|
-
|
|
1138
|
-
await
|
|
1187
|
+
const primaryCollection = await md.GetEntityObject('MJ: Collections', this.currentUser);
|
|
1188
|
+
await primaryCollection.Load(collectionId);
|
|
1189
|
+
if (!isCurrentLoad()) {
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
this.primaryCollection = primaryCollection;
|
|
1139
1193
|
}
|
|
1140
1194
|
}
|
|
1141
1195
|
else {
|
|
@@ -1143,10 +1197,15 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1143
1197
|
}
|
|
1144
1198
|
}
|
|
1145
1199
|
catch (err) {
|
|
1200
|
+
if (!isCurrentLoad()) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1146
1203
|
console.error('Error processing collection associations:', err);
|
|
1147
1204
|
}
|
|
1148
1205
|
finally {
|
|
1149
|
-
|
|
1206
|
+
if (isCurrentLoad()) {
|
|
1207
|
+
this.cdr.detectChanges();
|
|
1208
|
+
}
|
|
1150
1209
|
}
|
|
1151
1210
|
}
|
|
1152
1211
|
/**
|
|
@@ -1341,9 +1400,10 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1341
1400
|
* Process links data using pre-fetched batch results from loadArtifact().
|
|
1342
1401
|
* Reuses collection data from the same batch to avoid duplicate queries.
|
|
1343
1402
|
*/
|
|
1344
|
-
async processLinksData(collectionsResult, convDetailResult) {
|
|
1345
|
-
if (!
|
|
1403
|
+
async processLinksData(collectionsResult, convDetailResult, artifactId = this.artifactId, loadToken = this.artifactLoadToken) {
|
|
1404
|
+
if (!artifactId)
|
|
1346
1405
|
return;
|
|
1406
|
+
const isCurrentLoad = () => this.isCurrentArtifactLoad(artifactId, loadToken);
|
|
1347
1407
|
// Clear old links data first to prevent stale data from previous artifact
|
|
1348
1408
|
this.clearLinksData();
|
|
1349
1409
|
try {
|
|
@@ -1358,13 +1418,16 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1358
1418
|
const result = await rv.RunView({
|
|
1359
1419
|
EntityName: 'MJ: Collection Artifacts',
|
|
1360
1420
|
ExtraFilter: `ArtifactVersionID IN (
|
|
1361
|
-
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${
|
|
1421
|
+
SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${artifactId}'
|
|
1362
1422
|
)`,
|
|
1363
1423
|
Fields: ['ID', 'CollectionID', 'ArtifactVersionID'],
|
|
1364
1424
|
ResultType: 'simple'
|
|
1365
1425
|
}, this.currentUser);
|
|
1366
1426
|
collectionRows = (result.Success ? result.Results : []);
|
|
1367
1427
|
}
|
|
1428
|
+
if (!isCurrentLoad()) {
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1368
1431
|
// Get unique collection IDs and load collection details
|
|
1369
1432
|
const collectionIds = [...new Set(collectionRows.map(ca => (ca['CollectionID'] || ca.CollectionID)))].filter(Boolean);
|
|
1370
1433
|
if (collectionIds.length > 0) {
|
|
@@ -1375,6 +1438,9 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1375
1438
|
Fields: ['ID', 'Name', 'UserID', 'Description'],
|
|
1376
1439
|
ResultType: 'simple'
|
|
1377
1440
|
}, this.currentUser);
|
|
1441
|
+
if (!isCurrentLoad()) {
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1378
1444
|
if (collectionsEntityResult.Success && collectionsEntityResult.Results) {
|
|
1379
1445
|
this.allCollections = collectionsEntityResult.Results;
|
|
1380
1446
|
}
|
|
@@ -1398,19 +1464,30 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1398
1464
|
convDetailRows = (result.Success ? result.Results : []);
|
|
1399
1465
|
}
|
|
1400
1466
|
}
|
|
1467
|
+
if (!isCurrentLoad()) {
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1401
1470
|
// Load origin conversation if we have a link
|
|
1402
1471
|
if (convDetailRows.length > 0) {
|
|
1403
1472
|
const conversationDetailId = (convDetailRows[0]['ConversationDetailID'] || convDetailRows[0].ConversationDetailID);
|
|
1404
1473
|
const artifactVersionId = (convDetailRows[0]['ArtifactVersionID'] || convDetailRows[0].ArtifactVersionID);
|
|
1474
|
+
if (!isCurrentLoad()) {
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1405
1477
|
this.originConversationVersionId = artifactVersionId;
|
|
1406
1478
|
// Load conversation detail to get conversation ID
|
|
1407
1479
|
const conversationDetail = await md.GetEntityObject('MJ: Conversation Details', this.currentUser);
|
|
1408
1480
|
const detailLoaded = await conversationDetail.Load(conversationDetailId);
|
|
1481
|
+
if (!isCurrentLoad()) {
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1409
1484
|
if (detailLoaded && conversationDetail.ConversationID) {
|
|
1410
1485
|
const conversation = await md.GetEntityObject('MJ: Conversations', this.currentUser);
|
|
1411
1486
|
const loaded = await conversation.Load(conversationDetail.ConversationID);
|
|
1487
|
+
if (!isCurrentLoad()) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1412
1490
|
if (loaded) {
|
|
1413
|
-
this.originConversation = conversation;
|
|
1414
1491
|
// Check if user has access (is owner or participant)
|
|
1415
1492
|
const userIsOwner = UUIDsEqual(conversation.UserID, this.currentUser.ID);
|
|
1416
1493
|
const participantResult = await rv.RunView({
|
|
@@ -1420,19 +1497,28 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1420
1497
|
Fields: ['ID'],
|
|
1421
1498
|
ResultType: 'simple'
|
|
1422
1499
|
}, this.currentUser);
|
|
1500
|
+
if (!isCurrentLoad()) {
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1423
1503
|
const userIsParticipant = participantResult.Success &&
|
|
1424
1504
|
participantResult.Results &&
|
|
1425
1505
|
participantResult.Results.length > 0;
|
|
1506
|
+
this.originConversation = conversation;
|
|
1426
1507
|
this.hasAccessToOriginConversation = userIsOwner || userIsParticipant;
|
|
1427
1508
|
}
|
|
1428
1509
|
}
|
|
1429
1510
|
}
|
|
1430
1511
|
}
|
|
1431
1512
|
catch (error) {
|
|
1513
|
+
if (!isCurrentLoad()) {
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1432
1516
|
console.error('Error loading links data:', error);
|
|
1433
1517
|
}
|
|
1434
1518
|
finally {
|
|
1435
|
-
|
|
1519
|
+
if (isCurrentLoad()) {
|
|
1520
|
+
this.cdr.detectChanges();
|
|
1521
|
+
}
|
|
1436
1522
|
}
|
|
1437
1523
|
}
|
|
1438
1524
|
/**
|
|
@@ -1678,12 +1764,12 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1678
1764
|
} if (rf & 2) {
|
|
1679
1765
|
let _t;
|
|
1680
1766
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pluginViewer = _t.first);
|
|
1681
|
-
} }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", showHeader: "showHeader", showTabs: "showTabs", showCloseButton: "showCloseButton", showMaximizeButton: "showMaximizeButton", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId", canShare: "canShare", canEdit: "canEdit", isMaximized: "isMaximized" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink", shareRequested: "shareRequested", maximizeToggled: "maximizeToggled", openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest", analyzeRequested: "analyzeRequested", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 6, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-content"], [1, "loading-state"], [
|
|
1767
|
+
} }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", showHeader: "showHeader", showTabs: "showTabs", showCloseButton: "showCloseButton", showMaximizeButton: "showMaximizeButton", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId", canShare: "canShare", canEdit: "canEdit", isMaximized: "isMaximized" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink", shareRequested: "shareRequested", maximizeToggled: "maximizeToggled", openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest", analyzeRequested: "analyzeRequested", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 6, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-content"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load artifact", "Size", "compact", 3, "Message"], [1, "artifact-content-wrapper", 3, "no-tabs"], [1, "panel-header-left"], [1, "fas", 3, "ngClass"], [1, "header-description"], [1, "panel-header-right"], [1, "version-selector", 3, "click"], [1, "fas", "fa-history"], [1, "version-label"], [1, "fas", "fa-chevron-down", "dropdown-icon", 3, "open"], [1, "version-dropdown"], ["title", "Inspect & rate components", 1, "feedback-btn"], [1, "save-to-collection-btn", 3, "in-collection", "title"], ["title", "Share", 1, "share-btn"], ["title", "Analyze this artifact with AI", 1, "analyze-btn", 3, "click"], [1, "fas", "fa-magnifying-glass-chart"], [1, "maximize-btn", 3, "title"], ["title", "Close", 1, "close-btn"], [1, "fas", "fa-chevron-down", "dropdown-icon"], [1, "version-dropdown", 3, "click"], [1, "version-option", 3, "selected"], [1, "version-option", 3, "click"], [1, "version-number"], [1, "version-date"], [1, "fas", "fa-check"], ["title", "Inspect & rate components", 1, "feedback-btn", 3, "click"], [1, "fas", "fa-star-half-stroke"], [1, "save-to-collection-btn", 3, "click", "title"], ["title", "Share", 1, "share-btn", 3, "click"], [1, "fas", "fa-share-nodes"], [1, "maximize-btn", 3, "click", "title"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "fas", "fa-spinner", "fa-spin"], [1, "artifact-content-wrapper"], [1, "tab-navigation"], [1, "tab-content"], [1, "plugin-container", 3, "plugin-hidden"], [1, "display-content"], [1, "details-content"], [1, "artifact-meta"], [1, "meta-item"], [1, "meta-item", "full-width"], [1, "attributes-section"], [1, "links-container"], [1, "links-section"], ["Icon", "fa-solid fa-link", "Title", "No links available", "Size", "compact"], [1, "tab-btn", 3, "active"], [1, "tab-btn", 3, "click"], [3, "class"], [1, "plugin-container"], [3, "openEntityRecord", "navigationRequest", "pluginLoaded", "tabsChanged", "applyFormRequested", "artifactVersion", "artifactTypeName", "contentType", "readonly"], [1, "display-toolbar"], ["title", "Print", 1, "btn-icon", 3, "click"], [1, "fas", "fa-print"], ["title", "Copy Content", 1, "btn-icon", 3, "click"], [1, "fas", "fa-copy"], [1, "markdown-content"], [1, "html-content", 3, "innerHTML"], [3, "data", "enableCollapsibleHeadings", "enableLineNumbers", "enableSmartypants", "enableHtml"], [1, "attributes-list"], [1, "attribute-item"], [1, "attribute-empty-pill"], [1, "link-item", 3, "disabled", "clickable", "title"], [1, "link-item", 3, "click", "title"], [1, "link-icon"], [1, "fas", "fa-comments"], [1, "fas", "fa-folder"], [1, "link-content"], [1, "link-name"], [1, "link-type"], [1, "link-actions"], [1, "fas", "fa-arrow-right"], [1, "component-tab-content"], [4, "ngComponentOutlet", "ngComponentOutletInputs"], [1, "dynamic-tab-content"], [1, "markdown-viewer"], [1, "json-viewer"], [1, "code-viewer"], [1, "html-viewer", 3, "innerHTML"], [1, "plaintext-viewer"], [1, "json-toolbar"], ["title", "Copy JSON", 1, "btn-icon", 3, "click"], [1, "json-editor-container"], [2, "width", "100%", "height", "100%", 3, "value", "language", "readonly", "lineWrapping"], [1, "code-toolbar"], ["title", "Copy Code", 1, "btn-icon", 3, "click"], [1, "code-editor-container"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1682
1768
|
i0.ɵɵelementStart(0, "div", 0);
|
|
1683
1769
|
i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_1_Template, 20, 13, "div", 1);
|
|
1684
1770
|
i0.ɵɵelementStart(2, "div", 2);
|
|
1685
1771
|
i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_3_Template, 4, 0, "div", 3);
|
|
1686
|
-
i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_4_Template,
|
|
1772
|
+
i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_4_Template, 1, 1, "mj-empty-state", 4);
|
|
1687
1773
|
i0.ɵɵconditionalCreate(5, ArtifactViewerPanelComponent_Conditional_5_Template, 36, 24, "div", 5);
|
|
1688
1774
|
i0.ɵɵelementEnd()();
|
|
1689
1775
|
} if (rf & 2) {
|
|
@@ -1696,11 +1782,11 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1696
1782
|
i0.ɵɵconditional(ctx.error ? 4 : -1);
|
|
1697
1783
|
i0.ɵɵadvance();
|
|
1698
1784
|
i0.ɵɵconditional(!ctx.isLoading && !ctx.error && ctx.artifact ? 5 : -1);
|
|
1699
|
-
} }, dependencies: [i4.NgClass, i4.NgComponentOutlet, i5.MarkdownComponent, i6.CodeEditorComponent, i7.ArtifactTypePluginViewerComponent, i4.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon.open[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-family: monospace;\n}\n\n.version-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option[_ngcontent-%COMP%] .version-number[_ngcontent-%COMP%] {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.analyze-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.maximize-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state[_ngcontent-%COMP%], \n.error-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.error-state[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.artifact-meta[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select[_ngcontent-%COMP%]:focus, \n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider[_ngcontent-%COMP%]::before, \n.divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n padding: 0 12px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] .form-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden[_ngcontent-%COMP%], \n.tab-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] mj-artifact-type-plugin-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content[_ngcontent-%COMP%], \n.html-content[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; \n\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content[_ngcontent-%COMP%] .artifact-meta[_ngcontent-%COMP%] {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content[_ngcontent-%COMP%] .meta-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.attributes-section[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.links-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.links-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.link-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover .link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n.links-container[_ngcontent-%COMP%] .empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.links-container[_ngcontent-%COMP%] .empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.links-container[_ngcontent-%COMP%] .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n.dynamic-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n\n\n.component-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 24px; }\n.markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] { font-size: 20px; }\n.markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { font-size: 18px; }\n\n.markdown-viewer[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] ul[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n}\n\n.code-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n\n\n@media (max-width: 768px) {\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%] {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 12px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 8px;\n }\n}"] });
|
|
1785
|
+
} }, dependencies: [i4.NgClass, i4.NgComponentOutlet, i5.MarkdownComponent, i6.CodeEditorComponent, i7.MJEmptyStateComponent, i8.ArtifactTypePluginViewerComponent, i4.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon.open[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-family: monospace;\n}\n\n.version-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option[_ngcontent-%COMP%] .version-number[_ngcontent-%COMP%] {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.analyze-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.maximize-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.artifact-meta[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select[_ngcontent-%COMP%]:focus, \n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider[_ngcontent-%COMP%]::before, \n.divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n padding: 0 12px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] .form-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden[_ngcontent-%COMP%], \n.tab-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] mj-artifact-type-plugin-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content[_ngcontent-%COMP%], \n.html-content[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; \n\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content[_ngcontent-%COMP%] .artifact-meta[_ngcontent-%COMP%] {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content[_ngcontent-%COMP%] .meta-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.attributes-section[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.links-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.links-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.link-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover .link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n\n\n.dynamic-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n\n\n.component-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 24px; }\n.markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] { font-size: 20px; }\n.markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { font-size: 18px; }\n\n.markdown-viewer[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] ul[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n}\n\n.code-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n\n\n@media (max-width: 768px) {\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%] {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 12px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 8px;\n }\n}"] });
|
|
1700
1786
|
}
|
|
1701
1787
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArtifactViewerPanelComponent, [{
|
|
1702
1788
|
type: Component,
|
|
1703
|
-
args: [{ standalone: false, selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <div class=\"error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ error }}</span>\n </div>\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\"\n (applyFormRequested)=\"applyFormRequested.emit($event)\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fas fa-link\"></i>\n <p>No links available</p>\n </div>\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header h3 i {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable {\n cursor: pointer;\n}\n\n.version-selector.clickable:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector i {\n font-size: 11px;\n}\n\n.version-selector .dropdown-icon {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector .dropdown-icon.open {\n transform: rotate(180deg);\n}\n\n.version-label {\n font-family: monospace;\n}\n\n.version-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option .version-number {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option .version-date {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn i {\n font-size: 14px;\n}\n\n.analyze-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn i {\n font-size: 14px;\n}\n\n.maximize-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn i {\n font-size: 14px;\n}\n\n.panel-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state,\n.error-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.error-state {\n color: var(--mj-status-error);\n}\n\n.loading-state i {\n font-size: 24px;\n}\n\n.artifact-meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon i {\n font-size: 14px;\n}\n\n/* Library Dialog Styles */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header h3 i {\n color: var(--mj-status-warning);\n}\n\n.modal-body {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section {\n margin-bottom: 20px;\n}\n\n.form-section label {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider::before,\n.divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider span {\n padding: 0 12px;\n}\n\n.create-collection-row {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row .form-input {\n flex: 1;\n}\n\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n/* Plugin Container */\n.plugin-container {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden,\n.tab-hidden {\n display: none;\n}\n\n/* Ensure artifact viewer component takes full height */\n.plugin-container mj-artifact-type-plugin-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content,\n.html-content {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; /* top right bottom left */\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content .artifact-meta {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content .meta-item.full-width {\n grid-column: 1 / -1;\n}\n\n.attributes-section {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Links Tab */\n.links-container {\n padding: 20px;\n}\n\n.links-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable {\n cursor: pointer;\n}\n\n.link-item.clickable:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content {\n flex: 1;\n min-width: 0;\n}\n\n.link-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions i {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable:hover .link-actions i {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n.links-container .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.links-container .empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.links-container .empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n/* Dynamic Tab Content Styles */\n.dynamic-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n/* Custom component tab content */\n.component-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer h1, .markdown-viewer h2, .markdown-viewer h3 {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer h1 { font-size: 24px; }\n.markdown-viewer h2 { font-size: 20px; }\n.markdown-viewer h3 { font-size: 18px; }\n\n.markdown-viewer p {\n margin-bottom: 12px;\n}\n\n.markdown-viewer ul, .markdown-viewer ol {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer pre code {\n background: none;\n padding: 0;\n}\n\n.code-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n /* Add top border with slight visual separation from top nav */\n .artifact-viewer-panel {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n /* Create a small dark strip above the blue border to separate from top nav */\n .artifact-viewer-panel::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn i {\n font-size: 13px;\n }\n\n .panel-header {\n padding: 12px;\n }\n\n .dynamic-tab-content {\n padding: 12px;\n }\n\n .markdown-viewer {\n padding: 12px;\n }\n}\n\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .tab-navigation {\n padding: 0 4px;\n }\n\n .tab-btn {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn i {\n font-size: 12px;\n }\n\n .panel-header {\n padding: 8px;\n }\n\n .dynamic-tab-content {\n padding: 8px;\n }\n\n .markdown-viewer {\n padding: 8px;\n }\n}\n"] }]
|
|
1789
|
+
args: [{ standalone: false, selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load artifact\"\n [Message]=\"error\"\n Size=\"compact\" />\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\"\n (applyFormRequested)=\"applyFormRequested.emit($event)\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-link\"\n Title=\"No links available\"\n Size=\"compact\" />\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header h3 i {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable {\n cursor: pointer;\n}\n\n.version-selector.clickable:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector i {\n font-size: 11px;\n}\n\n.version-selector .dropdown-icon {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector .dropdown-icon.open {\n transform: rotate(180deg);\n}\n\n.version-label {\n font-family: monospace;\n}\n\n.version-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option .version-number {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option .version-date {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn i {\n font-size: 14px;\n}\n\n.analyze-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn i {\n font-size: 14px;\n}\n\n.maximize-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn i {\n font-size: 14px;\n}\n\n.panel-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n font-size: 24px;\n}\n\n.artifact-meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon i {\n font-size: 14px;\n}\n\n/* Library Dialog Styles */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header h3 i {\n color: var(--mj-status-warning);\n}\n\n.modal-body {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section {\n margin-bottom: 20px;\n}\n\n.form-section label {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider::before,\n.divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider span {\n padding: 0 12px;\n}\n\n.create-collection-row {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row .form-input {\n flex: 1;\n}\n\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n/* Plugin Container */\n.plugin-container {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden,\n.tab-hidden {\n display: none;\n}\n\n/* Ensure artifact viewer component takes full height */\n.plugin-container mj-artifact-type-plugin-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content,\n.html-content {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; /* top right bottom left */\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content .artifact-meta {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content .meta-item.full-width {\n grid-column: 1 / -1;\n}\n\n.attributes-section {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Links Tab */\n.links-container {\n padding: 20px;\n}\n\n.links-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable {\n cursor: pointer;\n}\n\n.link-item.clickable:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content {\n flex: 1;\n min-width: 0;\n}\n\n.link-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions i {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable:hover .link-actions i {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n/* Dynamic Tab Content Styles */\n.dynamic-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n/* Custom component tab content */\n.component-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer h1, .markdown-viewer h2, .markdown-viewer h3 {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer h1 { font-size: 24px; }\n.markdown-viewer h2 { font-size: 20px; }\n.markdown-viewer h3 { font-size: 18px; }\n\n.markdown-viewer p {\n margin-bottom: 12px;\n}\n\n.markdown-viewer ul, .markdown-viewer ol {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer pre code {\n background: none;\n padding: 0;\n}\n\n.code-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n /* Add top border with slight visual separation from top nav */\n .artifact-viewer-panel {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n /* Create a small dark strip above the blue border to separate from top nav */\n .artifact-viewer-panel::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn i {\n font-size: 13px;\n }\n\n .panel-header {\n padding: 12px;\n }\n\n .dynamic-tab-content {\n padding: 12px;\n }\n\n .markdown-viewer {\n padding: 12px;\n }\n}\n\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .tab-navigation {\n padding: 0 4px;\n }\n\n .tab-btn {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn i {\n font-size: 12px;\n }\n\n .panel-header {\n padding: 8px;\n }\n\n .dynamic-tab-content {\n padding: 8px;\n }\n\n .markdown-viewer {\n padding: 8px;\n }\n}\n"] }]
|
|
1704
1790
|
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }, { type: i3.ArtifactIconService }], { artifactId: [{
|
|
1705
1791
|
type: Input
|
|
1706
1792
|
}], currentUser: [{
|