@memberjunction/ng-artifacts 2.108.0 → 2.109.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.
@@ -1,16 +1,19 @@
1
- import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
1
+ import { Component, Input, Output, EventEmitter, ViewChild, SecurityContext } from '@angular/core';
2
2
  import { Metadata, RunView, LogError } from '@memberjunction/core';
3
+ import { ParseJSONRecursive } from '@memberjunction/global';
3
4
  import { ArtifactMetadataEngine } from '@memberjunction/core-entities';
4
5
  import { MJNotificationService } from '@memberjunction/ng-notifications';
5
6
  import { Subject } from 'rxjs';
6
7
  import { takeUntil } from 'rxjs/operators';
7
8
  import { ArtifactTypePluginViewerComponent } from './artifact-type-plugin-viewer.component';
9
+ import { marked } from 'marked';
8
10
  import * as i0 from "@angular/core";
9
- import * as i1 from "@angular/forms";
10
- import * as i2 from "ngx-markdown";
11
- import * as i3 from "@memberjunction/ng-code-editor";
12
- import * as i4 from "./artifact-type-plugin-viewer.component";
13
- import * as i5 from "@angular/common";
11
+ import * as i1 from "@memberjunction/ng-notifications";
12
+ import * as i2 from "@angular/platform-browser";
13
+ import * as i3 from "ngx-markdown";
14
+ import * as i4 from "@memberjunction/ng-code-editor";
15
+ import * as i5 from "./artifact-type-plugin-viewer.component";
16
+ import * as i6 from "@angular/common";
14
17
  const _forTrack0 = ($index, $item) => $item.ID;
15
18
  const _forTrack1 = ($index, $item) => $item.id;
16
19
  function ArtifactViewerPanelComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
@@ -91,105 +94,79 @@ function ArtifactViewerPanelComponent_Conditional_19_Template(rf, ctx) { if (rf
91
94
  i0.ɵɵadvance(3);
92
95
  i0.ɵɵtextInterpolate(ctx_r0.error);
93
96
  } }
94
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
95
- const _r7 = i0.ɵɵgetCurrentView();
96
- i0.ɵɵelementStart(0, "button", 31);
97
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setActiveTab("display")); });
98
- i0.ɵɵelement(1, "i", 38);
99
- i0.ɵɵtext(2, " Display ");
100
- i0.ɵɵelementEnd();
101
- } if (rf & 2) {
102
- const ctx_r0 = i0.ɵɵnextContext(2);
103
- i0.ɵɵclassProp("active", ctx_r0.activeTab === "display");
104
- } }
105
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
106
- const _r8 = i0.ɵɵgetCurrentView();
107
- i0.ɵɵelementStart(0, "button", 31);
108
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setActiveTab("json")); });
109
- i0.ɵɵelement(1, "i", 39);
110
- i0.ɵɵtext(2, " JSON ");
111
- i0.ɵɵelementEnd();
97
+ function ArtifactViewerPanelComponent_Conditional_20_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
98
+ i0.ɵɵelement(0, "i");
112
99
  } if (rf & 2) {
100
+ const tab_r7 = i0.ɵɵnextContext().$implicit;
113
101
  const ctx_r0 = i0.ɵɵnextContext(2);
114
- i0.ɵɵclassProp("active", ctx_r0.activeTab === "json");
102
+ i0.ɵɵclassMap(ctx_r0.GetTabIcon(tab_r7));
115
103
  } }
116
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template(rf, ctx) { if (rf & 1) {
117
- const _r9 = i0.ɵɵgetCurrentView();
118
- i0.ɵɵelementStart(0, "button", 31);
119
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setActiveTab("links")); });
120
- i0.ɵɵelement(1, "i", 40);
121
- i0.ɵɵtext(2, " Links ");
104
+ function ArtifactViewerPanelComponent_Conditional_20_For_3_Template(rf, ctx) { if (rf & 1) {
105
+ const _r6 = i0.ɵɵgetCurrentView();
106
+ i0.ɵɵelementStart(0, "button", 35);
107
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_For_3_Template_button_click_0_listener() { const tab_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.SetActiveTab(tab_r7)); });
108
+ i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_For_3_Conditional_1_Template, 1, 2, "i", 36);
109
+ i0.ɵɵtext(2);
122
110
  i0.ɵɵelementEnd();
123
111
  } if (rf & 2) {
112
+ const tab_r7 = ctx.$implicit;
124
113
  const ctx_r0 = i0.ɵɵnextContext(2);
125
- i0.ɵɵclassProp("active", ctx_r0.activeTab === "links");
114
+ i0.ɵɵclassProp("active", ctx_r0.activeTab === tab_r7.toLowerCase());
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵconditional(ctx_r0.GetTabIcon(tab_r7) ? 1 : -1);
117
+ i0.ɵɵadvance();
118
+ i0.ɵɵtextInterpolate1(" ", tab_r7, " ");
126
119
  } }
127
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵelement(0, "mj-artifact-type-plugin-viewer", 41);
120
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
121
+ i0.ɵɵelement(0, "mj-artifact-type-plugin-viewer", 37);
129
122
  } if (rf & 2) {
130
123
  const ctx_r0 = i0.ɵɵnextContext(3);
131
124
  i0.ɵɵproperty("artifactVersion", ctx_r0.artifactVersion)("artifactTypeName", ctx_r0.artifactTypeName)("contentType", ctx_r0.contentType)("readonly", true);
132
125
  } }
133
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
134
- i0.ɵɵelementStart(0, "div", 47);
135
- i0.ɵɵelement(1, "markdown", 49);
126
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
127
+ i0.ɵɵelementStart(0, "div", 43);
128
+ i0.ɵɵelement(1, "markdown", 45);
136
129
  i0.ɵɵelementEnd();
137
130
  } if (rf & 2) {
138
131
  const ctx_r0 = i0.ɵɵnextContext(4);
139
132
  i0.ɵɵadvance();
140
133
  i0.ɵɵproperty("data", ctx_r0.displayMarkdown);
141
134
  } }
142
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
143
- i0.ɵɵelement(0, "div", 48);
135
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
136
+ i0.ɵɵelement(0, "div", 44);
144
137
  } if (rf & 2) {
145
138
  const ctx_r0 = i0.ɵɵnextContext(4);
146
139
  i0.ɵɵproperty("innerHTML", ctx_r0.displayHtml, i0.ɵɵsanitizeHtml);
147
140
  } }
148
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
149
- const _r10 = i0.ɵɵgetCurrentView();
150
- i0.ɵɵelementStart(0, "div", 42)(1, "button", 43);
151
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onPrintDisplayContent()); });
152
- i0.ɵɵelement(2, "i", 44);
141
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Template(rf, ctx) { if (rf & 1) {
142
+ const _r8 = i0.ɵɵgetCurrentView();
143
+ i0.ɵɵelementStart(0, "div", 38)(1, "button", 39);
144
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onPrintDisplayContent()); });
145
+ i0.ɵɵelement(2, "i", 40);
153
146
  i0.ɵɵtext(3, " Print ");
154
147
  i0.ɵɵelementEnd();
155
- i0.ɵɵelementStart(4, "button", 45);
156
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onCopyDisplayContent()); });
157
- i0.ɵɵelement(5, "i", 46);
148
+ i0.ɵɵelementStart(4, "button", 41);
149
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onCopyDisplayContent()); });
150
+ i0.ɵɵelement(5, "i", 42);
158
151
  i0.ɵɵtext(6, " Copy ");
159
152
  i0.ɵɵelementEnd()();
160
- i0.ɵɵtemplate(7, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Conditional_7_Template, 2, 1, "div", 47)(8, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Conditional_8_Template, 1, 1, "div", 48);
153
+ i0.ɵɵtemplate(7, ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Conditional_7_Template, 2, 1, "div", 43)(8, ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Conditional_8_Template, 1, 1, "div", 44);
161
154
  } if (rf & 2) {
162
155
  const ctx_r0 = i0.ɵɵnextContext(3);
163
156
  i0.ɵɵadvance(7);
164
157
  i0.ɵɵconditional(ctx_r0.displayMarkdown ? 7 : ctx_r0.displayHtml ? 8 : -1);
165
158
  } }
166
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template(rf, ctx) { if (rf & 1) {
167
- i0.ɵɵelementStart(0, "div", 34);
168
- i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_1_Template, 1, 4, "mj-artifact-type-plugin-viewer", 41)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Template, 9, 1);
159
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Template(rf, ctx) { if (rf & 1) {
160
+ i0.ɵɵelementStart(0, "div", 32);
161
+ i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_1_Template, 1, 4, "mj-artifact-type-plugin-viewer", 37)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Conditional_2_Template, 9, 1);
169
162
  i0.ɵɵelementEnd();
170
163
  } if (rf & 2) {
171
164
  const ctx_r0 = i0.ɵɵnextContext(2);
172
165
  i0.ɵɵadvance();
173
166
  i0.ɵɵconditional(ctx_r0.hasPlugin && ctx_r0.artifactVersion && ctx_r0.artifactTypeName ? 1 : ctx_r0.displayMarkdown || ctx_r0.displayHtml ? 2 : -1);
174
167
  } }
175
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template(rf, ctx) { if (rf & 1) {
176
- const _r11 = i0.ɵɵgetCurrentView();
177
- i0.ɵɵelementStart(0, "div", 35)(1, "div", 50)(2, "button", 51);
178
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onCopyToClipboard()); });
179
- i0.ɵɵelement(3, "i", 46);
180
- i0.ɵɵtext(4, " Copy ");
181
- i0.ɵɵelementEnd()();
182
- i0.ɵɵelementStart(5, "div", 52)(6, "mj-code-editor", 53);
183
- i0.ɵɵtwoWayListener("ngModelChange", function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template_mj_code_editor_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.jsonContent, $event) || (ctx_r0.jsonContent = $event); return i0.ɵɵresetView($event); });
184
- i0.ɵɵelementEnd()()();
185
- } if (rf & 2) {
186
- const ctx_r0 = i0.ɵɵnextContext(2);
187
- i0.ɵɵadvance(6);
188
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.jsonContent);
189
- i0.ɵɵproperty("language", "json")("readonly", true);
190
- } }
191
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_24_Template(rf, ctx) { if (rf & 1) {
192
- i0.ɵɵelementStart(0, "div", 56)(1, "label");
168
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_24_Template(rf, ctx) { if (rf & 1) {
169
+ i0.ɵɵelementStart(0, "div", 48)(1, "label");
193
170
  i0.ɵɵtext(2, "Artifact Description");
194
171
  i0.ɵɵelementEnd();
195
172
  i0.ɵɵelementStart(3, "span");
@@ -200,8 +177,8 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_
200
177
  i0.ɵɵadvance(4);
201
178
  i0.ɵɵtextInterpolate(ctx_r0.artifact.Description);
202
179
  } }
203
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_25_Template(rf, ctx) { if (rf & 1) {
204
- i0.ɵɵelementStart(0, "div", 56)(1, "label");
180
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_25_Template(rf, ctx) { if (rf & 1) {
181
+ i0.ɵɵelementStart(0, "div", 48)(1, "label");
205
182
  i0.ɵɵtext(2, "Version Description");
206
183
  i0.ɵɵelementEnd();
207
184
  i0.ɵɵelementStart(3, "span");
@@ -212,75 +189,75 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_
212
189
  i0.ɵɵadvance(4);
213
190
  i0.ɵɵtextInterpolate(ctx_r0.artifactVersion == null ? null : ctx_r0.artifactVersion.Description);
214
191
  } }
215
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
192
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
216
193
  i0.ɵɵelementStart(0, "span");
217
194
  i0.ɵɵtext(1);
218
195
  i0.ɵɵelementEnd();
219
196
  } if (rf & 2) {
220
- const attr_r12 = i0.ɵɵnextContext().$implicit;
197
+ const attr_r9 = i0.ɵɵnextContext().$implicit;
221
198
  i0.ɵɵadvance();
222
- i0.ɵɵtextInterpolate(attr_r12.Value);
199
+ i0.ɵɵtextInterpolate(attr_r9.Value);
223
200
  } }
224
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
225
- i0.ɵɵelementStart(0, "span", 60);
201
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
202
+ i0.ɵɵelementStart(0, "span", 52);
226
203
  i0.ɵɵtext(1, "Empty");
227
204
  i0.ɵɵelementEnd();
228
205
  } }
229
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Template(rf, ctx) { if (rf & 1) {
230
- i0.ɵɵelementStart(0, "div", 59)(1, "label");
206
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Template(rf, ctx) { if (rf & 1) {
207
+ i0.ɵɵelementStart(0, "div", 51)(1, "label");
231
208
  i0.ɵɵtext(2);
232
209
  i0.ɵɵelementEnd();
233
- i0.ɵɵtemplate(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Conditional_4_Template, 2, 0, "span", 60);
210
+ i0.ɵɵtemplate(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Conditional_4_Template, 2, 0, "span", 52);
234
211
  i0.ɵɵelementEnd();
235
212
  } if (rf & 2) {
236
- const attr_r12 = ctx.$implicit;
213
+ const attr_r9 = ctx.$implicit;
237
214
  i0.ɵɵadvance(2);
238
- i0.ɵɵtextInterpolate(attr_r12.Name);
215
+ i0.ɵɵtextInterpolate(attr_r9.Name);
239
216
  i0.ɵɵadvance();
240
- i0.ɵɵconditional(attr_r12.Value ? 3 : 4);
217
+ i0.ɵɵconditional(attr_r9.Value ? 3 : 4);
241
218
  } }
242
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_Template(rf, ctx) { if (rf & 1) {
243
- i0.ɵɵelementStart(0, "div", 57)(1, "h4");
219
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_Template(rf, ctx) { if (rf & 1) {
220
+ i0.ɵɵelementStart(0, "div", 49)(1, "h4");
244
221
  i0.ɵɵtext(2, "Version Attributes");
245
222
  i0.ɵɵelementEnd();
246
- i0.ɵɵelementStart(3, "div", 58);
247
- i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Template, 5, 2, "div", 59, _forTrack0);
223
+ i0.ɵɵelementStart(3, "div", 50);
224
+ i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_For_5_Template, 5, 2, "div", 51, _forTrack0);
248
225
  i0.ɵɵelementEnd()();
249
226
  } if (rf & 2) {
250
227
  const ctx_r0 = i0.ɵɵnextContext(3);
251
228
  i0.ɵɵadvance(4);
252
229
  i0.ɵɵrepeater(ctx_r0.filteredAttributes);
253
230
  } }
254
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Template(rf, ctx) { if (rf & 1) {
255
- i0.ɵɵelementStart(0, "div", 36)(1, "div", 54)(2, "div", 55)(3, "label");
231
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Template(rf, ctx) { if (rf & 1) {
232
+ i0.ɵɵelementStart(0, "div", 33)(1, "div", 46)(2, "div", 47)(3, "label");
256
233
  i0.ɵɵtext(4, "Type");
257
234
  i0.ɵɵelementEnd();
258
235
  i0.ɵɵelementStart(5, "span");
259
236
  i0.ɵɵtext(6);
260
237
  i0.ɵɵelementEnd()();
261
- i0.ɵɵelementStart(7, "div", 55)(8, "label");
238
+ i0.ɵɵelementStart(7, "div", 47)(8, "label");
262
239
  i0.ɵɵtext(9, "Version");
263
240
  i0.ɵɵelementEnd();
264
241
  i0.ɵɵelementStart(10, "span");
265
242
  i0.ɵɵtext(11);
266
243
  i0.ɵɵelementEnd()();
267
- i0.ɵɵelementStart(12, "div", 55)(13, "label");
244
+ i0.ɵɵelementStart(12, "div", 47)(13, "label");
268
245
  i0.ɵɵtext(14, "Created");
269
246
  i0.ɵɵelementEnd();
270
247
  i0.ɵɵelementStart(15, "span");
271
248
  i0.ɵɵtext(16);
272
249
  i0.ɵɵpipe(17, "date");
273
250
  i0.ɵɵelementEnd()();
274
- i0.ɵɵelementStart(18, "div", 55)(19, "label");
251
+ i0.ɵɵelementStart(18, "div", 47)(19, "label");
275
252
  i0.ɵɵtext(20, "Updated");
276
253
  i0.ɵɵelementEnd();
277
254
  i0.ɵɵelementStart(21, "span");
278
255
  i0.ɵɵtext(22);
279
256
  i0.ɵɵpipe(23, "date");
280
257
  i0.ɵɵelementEnd()();
281
- i0.ɵɵtemplate(24, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_24_Template, 5, 1, "div", 56)(25, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_25_Template, 5, 1, "div", 56);
258
+ i0.ɵɵtemplate(24, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_24_Template, 5, 1, "div", 48)(25, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_25_Template, 5, 1, "div", 48);
282
259
  i0.ɵɵelementEnd();
283
- i0.ɵɵtemplate(26, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_Template, 6, 0, "div", 57);
260
+ i0.ɵɵtemplate(26, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Conditional_26_Template, 6, 0, "div", 49);
284
261
  i0.ɵɵelementEnd();
285
262
  } if (rf & 2) {
286
263
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -299,97 +276,148 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Template(rf,
299
276
  i0.ɵɵadvance();
300
277
  i0.ɵɵconditional(ctx_r0.filteredAttributes.length > 0 ? 26 : -1);
301
278
  } }
302
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
303
- i0.ɵɵelement(0, "i", 65);
279
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
280
+ i0.ɵɵelement(0, "i", 57);
304
281
  } }
305
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
306
- i0.ɵɵelement(0, "i", 66);
282
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
283
+ i0.ɵɵelement(0, "i", 58);
307
284
  } }
308
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
309
- const _r13 = i0.ɵɵgetCurrentView();
310
- i0.ɵɵelementStart(0, "div", 63)(1, "div", 64);
311
- i0.ɵɵtemplate(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Conditional_2_Template, 1, 0, "i", 65)(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Conditional_3_Template, 1, 0, "i", 66);
285
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
286
+ const _r10 = i0.ɵɵgetCurrentView();
287
+ i0.ɵɵelementStart(0, "div", 55)(1, "div", 56);
288
+ i0.ɵɵtemplate(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Conditional_2_Template, 1, 0, "i", 57)(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Conditional_3_Template, 1, 0, "i", 58);
312
289
  i0.ɵɵelementEnd();
313
- i0.ɵɵelementStart(4, "div", 67)(5, "div", 68);
290
+ i0.ɵɵelementStart(4, "div", 59)(5, "div", 60);
314
291
  i0.ɵɵtext(6);
315
292
  i0.ɵɵelementEnd();
316
- i0.ɵɵelementStart(7, "div", 69);
293
+ i0.ɵɵelementStart(7, "div", 61);
317
294
  i0.ɵɵtext(8);
318
295
  i0.ɵɵelementEnd()();
319
- i0.ɵɵelementStart(9, "div", 70)(10, "button", 71);
320
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Template_button_click_10_listener() { const link_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onNavigateToLink(link_r14)); });
321
- i0.ɵɵelement(11, "i", 72);
296
+ i0.ɵɵelementStart(9, "div", 62)(10, "button", 63);
297
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Template_button_click_10_listener() { const link_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onNavigateToLink(link_r11)); });
298
+ i0.ɵɵelement(11, "i", 64);
322
299
  i0.ɵɵelementEnd()()();
323
300
  } if (rf & 2) {
324
- const link_r14 = ctx.$implicit;
301
+ const link_r11 = ctx.$implicit;
325
302
  i0.ɵɵadvance(2);
326
- i0.ɵɵconditional(link_r14.type === "conversation" ? 2 : 3);
303
+ i0.ɵɵconditional(link_r11.type === "conversation" ? 2 : 3);
327
304
  i0.ɵɵadvance(4);
328
- i0.ɵɵtextInterpolate(link_r14.name);
305
+ i0.ɵɵtextInterpolate(link_r11.name);
329
306
  i0.ɵɵadvance(2);
330
- i0.ɵɵtextInterpolate(link_r14.type === "conversation" ? "Conversation" : "Collection");
307
+ i0.ɵɵtextInterpolate(link_r11.type === "conversation" ? "Conversation" : "Collection");
331
308
  i0.ɵɵadvance(2);
332
- i0.ɵɵproperty("disabled", !link_r14.hasAccess)("title", link_r14.hasAccess ? "Open" : "No access");
309
+ i0.ɵɵproperty("disabled", !link_r11.hasAccess)("title", link_r11.hasAccess ? "Open" : "No access");
333
310
  } }
334
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
335
- i0.ɵɵelementStart(0, "div", 61);
336
- i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_For_2_Template, 12, 5, "div", 63, _forTrack1);
311
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
312
+ i0.ɵɵelementStart(0, "div", 53);
313
+ i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_For_2_Template, 12, 5, "div", 55, _forTrack1);
337
314
  i0.ɵɵelementEnd();
338
315
  } if (rf & 2) {
339
316
  const ctx_r0 = i0.ɵɵnextContext(3);
340
317
  i0.ɵɵadvance();
341
318
  i0.ɵɵrepeater(ctx_r0.linksToShow);
342
319
  } }
343
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
344
- i0.ɵɵelementStart(0, "div", 62);
345
- i0.ɵɵelement(1, "i", 40);
320
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
321
+ i0.ɵɵelementStart(0, "div", 54);
322
+ i0.ɵɵelement(1, "i", 65);
346
323
  i0.ɵɵelementStart(2, "p");
347
324
  i0.ɵɵtext(3, "No links available");
348
325
  i0.ɵɵelementEnd()();
349
326
  } }
350
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Template(rf, ctx) { if (rf & 1) {
351
- i0.ɵɵelementStart(0, "div", 37);
352
- i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_1_Template, 3, 0, "div", 61)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Conditional_2_Template, 4, 0, "div", 62);
327
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template(rf, ctx) { if (rf & 1) {
328
+ i0.ɵɵelementStart(0, "div", 34);
329
+ i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_1_Template, 3, 0, "div", 53)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Conditional_2_Template, 4, 0, "div", 54);
353
330
  i0.ɵɵelementEnd();
354
331
  } if (rf & 2) {
355
332
  const ctx_r0 = i0.ɵɵnextContext(2);
356
333
  i0.ɵɵadvance();
357
334
  i0.ɵɵconditional(ctx_r0.linksToShow.length > 0 ? 1 : 2);
358
335
  } }
336
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_1_Template(rf, ctx) { if (rf & 1) {
337
+ i0.ɵɵelement(0, "div", 67);
338
+ } if (rf & 2) {
339
+ const tabData_r12 = i0.ɵɵnextContext();
340
+ const ctx_r0 = i0.ɵɵnextContext(3);
341
+ i0.ɵɵproperty("innerHTML", ctx_r0.RenderMarkdown(tabData_r12.content), i0.ɵɵsanitizeHtml);
342
+ } }
343
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_2_Template(rf, ctx) { if (rf & 1) {
344
+ const _r13 = i0.ɵɵgetCurrentView();
345
+ i0.ɵɵelementStart(0, "div", 68)(1, "div", 72)(2, "button", 73);
346
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onCopyToClipboard()); });
347
+ i0.ɵɵelement(3, "i", 42);
348
+ i0.ɵɵtext(4, " Copy ");
349
+ i0.ɵɵelementEnd()();
350
+ i0.ɵɵelementStart(5, "div", 74);
351
+ i0.ɵɵelement(6, "mj-code-editor", 75);
352
+ i0.ɵɵelementEnd()();
353
+ } if (rf & 2) {
354
+ const tabData_r12 = i0.ɵɵnextContext();
355
+ i0.ɵɵadvance(6);
356
+ i0.ɵɵproperty("value", tabData_r12.content)("language", "json")("readonly", true)("lineWrapping", true);
357
+ } }
358
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_3_Template(rf, ctx) { if (rf & 1) {
359
+ i0.ɵɵelementStart(0, "div", 69);
360
+ i0.ɵɵelement(1, "mj-code-editor", 75);
361
+ i0.ɵɵelementEnd();
362
+ } if (rf & 2) {
363
+ const tabData_r12 = i0.ɵɵnextContext();
364
+ i0.ɵɵadvance();
365
+ i0.ɵɵproperty("value", tabData_r12.content)("language", tabData_r12.language || "typescript")("readonly", true)("lineWrapping", true);
366
+ } }
367
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_4_Template(rf, ctx) { if (rf & 1) {
368
+ i0.ɵɵelement(0, "div", 70);
369
+ } if (rf & 2) {
370
+ const tabData_r12 = i0.ɵɵnextContext();
371
+ i0.ɵɵproperty("innerHTML", tabData_r12.content, i0.ɵɵsanitizeHtml);
372
+ } }
373
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_5_Template(rf, ctx) { if (rf & 1) {
374
+ i0.ɵɵelementStart(0, "pre", 71);
375
+ i0.ɵɵtext(1);
376
+ i0.ɵɵelementEnd();
377
+ } if (rf & 2) {
378
+ const tabData_r12 = i0.ɵɵnextContext();
379
+ i0.ɵɵadvance();
380
+ i0.ɵɵtextInterpolate(tabData_r12.content);
381
+ } }
382
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
383
+ i0.ɵɵelementStart(0, "div", 66);
384
+ i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_1_Template, 1, 1, "div", 67)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_2_Template, 7, 4, "div", 68)(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_3_Template, 2, 4, "div", 69)(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_4_Template, 1, 1, "div", 70)(5, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Case_5_Template, 2, 1, "pre", 71);
385
+ i0.ɵɵelementEnd();
386
+ } if (rf & 2) {
387
+ let tmp_4_0;
388
+ i0.ɵɵadvance();
389
+ i0.ɵɵconditional((tmp_4_0 = ctx.type) === "markdown" ? 1 : tmp_4_0 === "json" ? 2 : tmp_4_0 === "code" ? 3 : tmp_4_0 === "html" ? 4 : tmp_4_0 === "plaintext" ? 5 : -1);
390
+ } }
391
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Template(rf, ctx) { if (rf & 1) {
392
+ i0.ɵɵtemplate(0, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_0_Template, 6, 1, "div", 66);
393
+ } if (rf & 2) {
394
+ let tmp_2_0;
395
+ const ctx_r0 = i0.ɵɵnextContext(2);
396
+ i0.ɵɵconditional((tmp_2_0 = ctx_r0.GetTabContent(ctx_r0.activeTab)) ? 0 : -1, tmp_2_0);
397
+ } }
359
398
  function ArtifactViewerPanelComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
360
- const _r6 = i0.ɵɵgetCurrentView();
361
399
  i0.ɵɵelementStart(0, "div", 17)(1, "div", 29);
362
- i0.ɵɵtemplate(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template, 3, 2, "button", 30)(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template, 3, 2, "button", 30);
363
- i0.ɵɵelementStart(4, "button", 31);
364
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setActiveTab("details")); });
365
- i0.ɵɵelement(5, "i", 32);
366
- i0.ɵɵtext(6, " Details ");
400
+ i0.ɵɵrepeaterCreate(2, ArtifactViewerPanelComponent_Conditional_20_For_3_Template, 3, 4, "button", 30, i0.ɵɵrepeaterTrackByIdentity);
367
401
  i0.ɵɵelementEnd();
368
- i0.ɵɵtemplate(7, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template, 3, 2, "button", 30);
369
- i0.ɵɵelementEnd();
370
- i0.ɵɵelementStart(8, "div", 33);
371
- i0.ɵɵtemplate(9, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template, 3, 1, "div", 34)(10, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template, 7, 3, "div", 35)(11, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Template, 27, 13, "div", 36)(12, ArtifactViewerPanelComponent_Conditional_20_Conditional_12_Template, 3, 1, "div", 37);
402
+ i0.ɵɵelementStart(4, "div", 31);
403
+ i0.ɵɵtemplate(5, ArtifactViewerPanelComponent_Conditional_20_Conditional_5_Template, 3, 1, "div", 32)(6, ArtifactViewerPanelComponent_Conditional_20_Conditional_6_Template, 27, 13, "div", 33)(7, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template, 3, 1, "div", 34)(8, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Template, 1, 1);
372
404
  i0.ɵɵelementEnd()();
373
405
  } if (rf & 2) {
374
406
  const ctx_r0 = i0.ɵɵnextContext();
375
407
  i0.ɵɵadvance(2);
376
- i0.ɵɵconditional(ctx_r0.hasDisplayTab ? 2 : -1);
377
- i0.ɵɵadvance();
378
- i0.ɵɵconditional(ctx_r0.hasJsonTab ? 3 : -1);
379
- i0.ɵɵadvance();
380
- i0.ɵɵclassProp("active", ctx_r0.activeTab === "details");
408
+ i0.ɵɵrepeater(ctx_r0.allTabs);
381
409
  i0.ɵɵadvance(3);
382
- i0.ɵɵconditional(ctx_r0.hasLinksTab ? 7 : -1);
383
- i0.ɵɵadvance(2);
384
- i0.ɵɵconditional(ctx_r0.activeTab === "display" && ctx_r0.hasDisplayTab ? 9 : -1);
410
+ i0.ɵɵconditional(ctx_r0.activeTab === "display" ? 5 : -1);
385
411
  i0.ɵɵadvance();
386
- i0.ɵɵconditional(ctx_r0.activeTab === "json" && ctx_r0.hasJsonTab ? 10 : -1);
412
+ i0.ɵɵconditional(ctx_r0.activeTab === "details" ? 6 : -1);
387
413
  i0.ɵɵadvance();
388
- i0.ɵɵconditional(ctx_r0.activeTab === "details" ? 11 : -1);
414
+ i0.ɵɵconditional(ctx_r0.activeTab === "links" ? 7 : -1);
389
415
  i0.ɵɵadvance();
390
- i0.ɵɵconditional(ctx_r0.activeTab === "links" ? 12 : -1);
416
+ i0.ɵɵconditional(ctx_r0.activeTab !== "display" && ctx_r0.activeTab !== "details" && ctx_r0.activeTab !== "links" ? 8 : -1);
391
417
  } }
392
418
  export class ArtifactViewerPanelComponent {
419
+ notificationService;
420
+ sanitizer;
393
421
  artifactId;
394
422
  currentUser;
395
423
  environmentId;
@@ -414,7 +442,7 @@ export class ArtifactViewerPanelComponent {
414
442
  artifactCollections = [];
415
443
  primaryCollection = null;
416
444
  // Tabbed interface
417
- activeTab = 'display';
445
+ activeTab = 'display'; // Changed to string to support dynamic tabs
418
446
  displayMarkdown = null;
419
447
  displayHtml = null;
420
448
  versionAttributes = [];
@@ -426,6 +454,64 @@ export class ArtifactViewerPanelComponent {
426
454
  // Cache plugin state to avoid losing it when switching tabs
427
455
  cachedPluginShouldShowRaw = false;
428
456
  cachedPluginIsElevated = false;
457
+ // Cache plugin tabs (populated once when plugin loads)
458
+ cachedPluginTabs = [];
459
+ // Dynamic tabs from plugin
460
+ get allTabs() {
461
+ // Start with Display tab
462
+ const tabs = ['Display'];
463
+ // Add cached plugin tabs
464
+ if (this.cachedPluginTabs.length > 0) {
465
+ const pluginTabLabels = this.cachedPluginTabs.map((t) => t.label);
466
+ tabs.push(...pluginTabLabels);
467
+ }
468
+ // Add base tabs
469
+ tabs.push('JSON', 'Details');
470
+ // Conditionally add Links tab if there are links to show
471
+ if (this.hasLinksTab) {
472
+ tabs.push('Links');
473
+ }
474
+ return tabs;
475
+ }
476
+ /**
477
+ * Called when plugin is loaded/changed to cache its tabs (avoids binding issues)
478
+ */
479
+ CachePluginTabs() {
480
+ const plugin = this.pluginViewer?.pluginInstance;
481
+ if (plugin?.GetAdditionalTabs) {
482
+ this.cachedPluginTabs = plugin.GetAdditionalTabs();
483
+ }
484
+ else {
485
+ this.cachedPluginTabs = [];
486
+ }
487
+ }
488
+ GetTabContent(tabName) {
489
+ // Check if this is a plugin-provided tab (use cached tabs - case-insensitive match)
490
+ const pluginTab = this.cachedPluginTabs.find((t) => t.label.toLowerCase() === tabName.toLowerCase());
491
+ if (pluginTab) {
492
+ const content = typeof pluginTab.content === 'function'
493
+ ? pluginTab.content()
494
+ : pluginTab.content;
495
+ return {
496
+ type: pluginTab.contentType,
497
+ content: content,
498
+ language: pluginTab.language
499
+ };
500
+ }
501
+ // Handle base tabs
502
+ switch (tabName.toLowerCase()) {
503
+ case 'json':
504
+ return { type: 'json', content: this.jsonContent, language: 'json' };
505
+ case 'details':
506
+ return { type: 'html', content: this.displayMarkdown || this.displayHtml || '' };
507
+ default:
508
+ return null;
509
+ }
510
+ }
511
+ constructor(notificationService, sanitizer) {
512
+ this.notificationService = notificationService;
513
+ this.sanitizer = sanitizer;
514
+ }
429
515
  async ngOnInit() {
430
516
  // Subscribe to refresh trigger for dynamic version changes
431
517
  if (this.refreshTrigger) {
@@ -456,7 +542,7 @@ export class ArtifactViewerPanelComponent {
456
542
  // Just switch to the version we already have
457
543
  this.artifactVersion = targetVersion;
458
544
  this.selectedVersionNumber = targetVersion.VersionNumber || 1;
459
- this.jsonContent = targetVersion.Content || '{}';
545
+ this.jsonContent = this.FormatJSON(targetVersion.Content || '{}');
460
546
  console.log(`📦 Switched to cached version ${this.selectedVersionNumber}`);
461
547
  // Load version attributes
462
548
  await this.loadVersionAttributes();
@@ -506,21 +592,21 @@ export class ArtifactViewerPanelComponent {
506
592
  console.log(`📦 Loading specified version ${targetVersionNumber}`);
507
593
  this.artifactVersion = targetVersion;
508
594
  this.selectedVersionNumber = targetVersion.VersionNumber || 1;
509
- this.jsonContent = targetVersion.Content || '{}';
595
+ this.jsonContent = this.FormatJSON(targetVersion.Content || '{}');
510
596
  }
511
597
  else {
512
598
  console.warn(`📦 Version ${targetVersionNumber} not found, defaulting to latest`);
513
599
  // Target version not found, default to latest
514
600
  this.artifactVersion = result.Results[0];
515
601
  this.selectedVersionNumber = this.artifactVersion.VersionNumber || 1;
516
- this.jsonContent = this.artifactVersion.Content || '{}';
602
+ this.jsonContent = this.FormatJSON(this.artifactVersion.Content || '{}');
517
603
  }
518
604
  }
519
605
  else {
520
606
  // No target version, default to latest version (first in DESC order)
521
607
  this.artifactVersion = result.Results[0];
522
608
  this.selectedVersionNumber = this.artifactVersion.VersionNumber || 1;
523
- this.jsonContent = this.artifactVersion.Content || '{}';
609
+ this.jsonContent = this.FormatJSON(this.artifactVersion.Content || '{}');
524
610
  }
525
611
  // Load version attributes
526
612
  await this.loadVersionAttributes();
@@ -540,6 +626,10 @@ export class ArtifactViewerPanelComponent {
540
626
  }
541
627
  finally {
542
628
  this.isLoading = false;
629
+ // Cache plugin tabs after loading (use setTimeout to ensure plugin is fully initialized)
630
+ setTimeout(() => {
631
+ this.CachePluginTabs();
632
+ }, 100);
543
633
  }
544
634
  }
545
635
  async loadArtifactType() {
@@ -783,11 +873,14 @@ export class ArtifactViewerPanelComponent {
783
873
  async selectVersion(version) {
784
874
  this.artifactVersion = version;
785
875
  this.selectedVersionNumber = version.VersionNumber || 1;
786
- this.jsonContent = version.Content || '{}';
876
+ this.jsonContent = this.FormatJSON(version.Content || '{}');
787
877
  this.showVersionDropdown = false;
788
878
  // Load attributes for the selected version
789
879
  await this.loadVersionAttributes();
790
- console.log(`📦 Switched to version ${this.selectedVersionNumber}`);
880
+ // Recache plugin tabs (version may have different metadata)
881
+ setTimeout(() => {
882
+ this.CachePluginTabs();
883
+ }, 100);
791
884
  }
792
885
  async onSaveToLibrary() {
793
886
  // Always show the collection picker modal
@@ -1031,13 +1124,86 @@ export class ArtifactViewerPanelComponent {
1031
1124
  return null;
1032
1125
  }
1033
1126
  }
1034
- static ɵfac = function ArtifactViewerPanelComponent_Factory(t) { return new (t || ArtifactViewerPanelComponent)(); };
1127
+ /**
1128
+ * Format JSON content using ParseJSONRecursive for deep parsing and formatting
1129
+ */
1130
+ FormatJSON(content) {
1131
+ try {
1132
+ // First parse the JSON string to an object
1133
+ const obj = JSON.parse(content);
1134
+ // Then use ParseJSONRecursive to extract any inline JSON strings
1135
+ const parseOptions = {
1136
+ extractInlineJson: true,
1137
+ maxDepth: 100,
1138
+ debug: false
1139
+ };
1140
+ const parsed = ParseJSONRecursive(obj, parseOptions);
1141
+ // Finally stringify with formatting
1142
+ return JSON.stringify(parsed, null, 2);
1143
+ }
1144
+ catch (e) {
1145
+ // Fallback to simple parse/stringify if ParseJSONRecursive fails
1146
+ try {
1147
+ const obj = JSON.parse(content);
1148
+ return JSON.stringify(obj, null, 2);
1149
+ }
1150
+ catch (e2) {
1151
+ // If even simple parse fails, return as-is
1152
+ return content;
1153
+ }
1154
+ }
1155
+ }
1156
+ /**
1157
+ * Get icon class for a tab
1158
+ */
1159
+ GetTabIcon(tabName) {
1160
+ // Base tabs
1161
+ const baseIcons = {
1162
+ 'Display': 'fas fa-eye',
1163
+ 'Code': 'fas fa-code',
1164
+ 'JSON': 'fas fa-file-code',
1165
+ 'Details': 'fas fa-info-circle',
1166
+ 'Links': 'fas fa-link'
1167
+ };
1168
+ if (baseIcons[tabName]) {
1169
+ return baseIcons[tabName];
1170
+ }
1171
+ // Check plugin tabs
1172
+ const plugin = this.pluginViewer?.pluginInstance;
1173
+ if (plugin?.GetAdditionalTabs) {
1174
+ const pluginTab = plugin.GetAdditionalTabs().find((t) => t.label === tabName);
1175
+ if (pluginTab?.icon) {
1176
+ return 'fas ' + pluginTab.icon; // Ensure full Font Awesome class
1177
+ }
1178
+ }
1179
+ return null;
1180
+ }
1181
+ /**
1182
+ * Render markdown to HTML (for markdown tabs)
1183
+ */
1184
+ RenderMarkdown(markdown) {
1185
+ try {
1186
+ const html = marked.parse(markdown);
1187
+ return this.sanitizer.sanitize(SecurityContext.HTML, html) || '';
1188
+ }
1189
+ catch (e) {
1190
+ console.error('Failed to render markdown:', e);
1191
+ return markdown;
1192
+ }
1193
+ }
1194
+ /**
1195
+ * Set active tab
1196
+ */
1197
+ SetActiveTab(tabName) {
1198
+ this.activeTab = tabName.toLowerCase();
1199
+ }
1200
+ static ɵfac = function ArtifactViewerPanelComponent_Factory(t) { return new (t || ArtifactViewerPanelComponent)(i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer)); };
1035
1201
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ArtifactViewerPanelComponent, selectors: [["mj-artifact-viewer-panel"]], viewQuery: function ArtifactViewerPanelComponent_Query(rf, ctx) { if (rf & 1) {
1036
1202
  i0.ɵɵviewQuery(ArtifactTypePluginViewerComponent, 5);
1037
1203
  } if (rf & 2) {
1038
1204
  let _t;
1039
1205
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pluginViewer = _t.first);
1040
- } }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink" }, features: [i0.ɵɵNgOnChangesFeature], decls: 21, vars: 11, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-header-left"], [1, "fas", "fa-cube"], [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", "Save to Collection", 1, "save-to-collection-btn"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "panel-content"], [1, "loading-state"], [1, "error-state"], [1, "artifact-content-wrapper"], [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", "Save to Collection", 1, "save-to-collection-btn", 3, "click"], [1, "far", "fa-bookmark"], [1, "fas", "fa-spinner", "fa-spin"], [1, "fas", "fa-exclamation-triangle"], [1, "tab-navigation"], [1, "tab-btn", 3, "active"], [1, "tab-btn", 3, "click"], [1, "fas", "fa-info-circle"], [1, "tab-content"], [1, "display-content"], [1, "json-viewer"], [1, "details-content"], [1, "links-container"], [1, "fas", "fa-eye"], [1, "fas", "fa-code"], [1, "fas", "fa-link"], [3, "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"], [1, "json-toolbar"], ["title", "Copy JSON", 1, "btn-icon", 3, "click"], [1, "json-editor-container"], [2, "width", "100%", "height", "100%", 3, "ngModelChange", "ngModel", "language", "readonly"], [1, "artifact-meta"], [1, "meta-item"], [1, "meta-item", "full-width"], [1, "attributes-section"], [1, "attributes-list"], [1, "attribute-item"], [1, "attribute-empty-pill"], [1, "links-section"], [1, "empty-state"], [1, "link-item"], [1, "link-icon"], [1, "fas", "fa-comments"], [1, "fas", "fa-folder"], [1, "link-content"], [1, "link-name"], [1, "link-type"], [1, "link-actions"], [1, "link-action-btn", 3, "click", "disabled", "title"], [1, "fas", "fa-arrow-right"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
1206
+ } }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink" }, features: [i0.ɵɵNgOnChangesFeature], decls: 21, vars: 11, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-header-left"], [1, "fas", "fa-cube"], [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", "Save to Collection", 1, "save-to-collection-btn"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "panel-content"], [1, "loading-state"], [1, "error-state"], [1, "artifact-content-wrapper"], [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", "Save to Collection", 1, "save-to-collection-btn", 3, "click"], [1, "far", "fa-bookmark"], [1, "fas", "fa-spinner", "fa-spin"], [1, "fas", "fa-exclamation-triangle"], [1, "tab-navigation"], [1, "tab-btn", 3, "active"], [1, "tab-content"], [1, "display-content"], [1, "details-content"], [1, "links-container"], [1, "tab-btn", 3, "click"], [3, "class"], [3, "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"], [1, "artifact-meta"], [1, "meta-item"], [1, "meta-item", "full-width"], [1, "attributes-section"], [1, "attributes-list"], [1, "attribute-item"], [1, "attribute-empty-pill"], [1, "links-section"], [1, "empty-state"], [1, "link-item"], [1, "link-icon"], [1, "fas", "fa-comments"], [1, "fas", "fa-folder"], [1, "link-content"], [1, "link-name"], [1, "link-type"], [1, "link-actions"], [1, "link-action-btn", 3, "click", "disabled", "title"], [1, "fas", "fa-arrow-right"], [1, "fas", "fa-link"], [1, "dynamic-tab-content"], [1, "markdown-viewer", 3, "innerHTML"], [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"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
1041
1207
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h3");
1042
1208
  i0.ɵɵelement(4, "i", 3);
1043
1209
  i0.ɵɵtext(5);
@@ -1058,7 +1224,7 @@ export class ArtifactViewerPanelComponent {
1058
1224
  i0.ɵɵelement(16, "i", 13);
1059
1225
  i0.ɵɵelementEnd()()();
1060
1226
  i0.ɵɵelementStart(17, "div", 14);
1061
- i0.ɵɵtemplate(18, ArtifactViewerPanelComponent_Conditional_18_Template, 4, 0, "div", 15)(19, ArtifactViewerPanelComponent_Conditional_19_Template, 4, 1, "div", 16)(20, ArtifactViewerPanelComponent_Conditional_20_Template, 13, 9, "div", 17);
1227
+ i0.ɵɵtemplate(18, ArtifactViewerPanelComponent_Conditional_18_Template, 4, 0, "div", 15)(19, ArtifactViewerPanelComponent_Conditional_19_Template, 4, 1, "div", 16)(20, ArtifactViewerPanelComponent_Conditional_20_Template, 9, 4, "div", 17);
1062
1228
  i0.ɵɵelementEnd()();
1063
1229
  } if (rf & 2) {
1064
1230
  i0.ɵɵadvance(5);
@@ -1081,12 +1247,12 @@ export class ArtifactViewerPanelComponent {
1081
1247
  i0.ɵɵconditional(ctx.error ? 19 : -1);
1082
1248
  i0.ɵɵadvance();
1083
1249
  i0.ɵɵconditional(!ctx.isLoading && !ctx.error && ctx.artifact ? 20 : -1);
1084
- } }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MarkdownComponent, i3.CodeEditorComponent, i4.ArtifactTypePluginViewerComponent, i5.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\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 #E5E7EB;\n background: white;\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: #6366F1;\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: #6B7280;\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: #F3F4F6;\n border-radius: 12px;\n font-size: 12px;\n color: #6B7280;\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: #E5E7EB;\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: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\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: #F9FAFB;\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: #10B981;\n margin-left: auto;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #9CA3AF;\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: #F3F4F6;\n color: #6B7280;\n}\n\n.save-to-collection-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: #6B7280;\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: #F3F4F6;\n color: #111827;\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: #6B7280;\n}\n\n.error-state[_ngcontent-%COMP%] {\n color: #DC2626;\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: #F9FAFB;\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: #6B7280;\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: #111827;\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: #EFF6FF;\n border-left: 3px solid #3B82F6;\n border-radius: 4px;\n color: #1E40AF;\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 #E5E7EB;\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: #F9FAFB;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: #374151;\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: #4F46E5;\n border-color: #4F46E5;\n color: white;\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: #4338CA;\n border-color: #4338CA;\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\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 #E5E7EB;\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: #F59E0B;\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 #E5E7EB;\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: #374151;\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 14px;\n color: #111827;\n background: white;\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: #4F46E5;\n box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: #9CA3AF;\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: #E5E7EB;\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: #4F46E5;\n color: white;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #4338CA;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #D1D5DB;\n color: #374151;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #F3F4F6;\n}\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid #E5E7EB;\n padding: 0 16px;\n background: white;\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: #6B7280;\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: #1e40af;\n background: #F9FAFB;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: #1e40af;\n border-bottom-color: #1e40af;\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 overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\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}\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: #F9FAFB;\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: #111827;\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: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: #6B7280;\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: #111827;\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n color: #9CA3AF;\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: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: #1e40af;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\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: white;\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #1e40af;\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: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.link-action-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n color: #1e40af;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.link-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #EFF6FF;\n border-color: #1e40af;\n}\n\n.link-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n color: #9CA3AF;\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: #9CA3AF;\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}"] });
1250
+ } }, dependencies: [i3.MarkdownComponent, i4.CodeEditorComponent, i5.ArtifactTypePluginViewerComponent, i6.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\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 #E5E7EB;\n background: white;\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: #6366F1;\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: #6B7280;\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: #F3F4F6;\n border-radius: 12px;\n font-size: 12px;\n color: #6B7280;\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: #E5E7EB;\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: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\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: #F9FAFB;\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: #10B981;\n margin-left: auto;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #9CA3AF;\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: #F3F4F6;\n color: #6B7280;\n}\n\n.save-to-collection-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: #6B7280;\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: #F3F4F6;\n color: #111827;\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: #6B7280;\n}\n\n.error-state[_ngcontent-%COMP%] {\n color: #DC2626;\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: #F9FAFB;\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: #6B7280;\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: #111827;\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: #EFF6FF;\n border-left: 3px solid #3B82F6;\n border-radius: 4px;\n color: #1E40AF;\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 #E5E7EB;\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: #F9FAFB;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: #374151;\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: #4F46E5;\n border-color: #4F46E5;\n color: white;\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: #4338CA;\n border-color: #4338CA;\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\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 #E5E7EB;\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: #F59E0B;\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 #E5E7EB;\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: #374151;\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 14px;\n color: #111827;\n background: white;\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: #4F46E5;\n box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: #9CA3AF;\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: #E5E7EB;\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: #4F46E5;\n color: white;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #4338CA;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #D1D5DB;\n color: #374151;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #F3F4F6;\n}\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid #E5E7EB;\n padding: 0 16px;\n background: white;\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: #6B7280;\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: #1e40af;\n background: #F9FAFB;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: #1e40af;\n border-bottom-color: #1e40af;\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 overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\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: #F9FAFB;\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: #111827;\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: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: #6B7280;\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: #111827;\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n color: #9CA3AF;\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: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: #1e40af;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\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: white;\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #1e40af;\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: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.link-action-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n color: #1e40af;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.link-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #EFF6FF;\n border-color: #1e40af;\n}\n\n.link-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n color: #9CA3AF;\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: #9CA3AF;\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.markdown-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: white;\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: #f3f4f6;\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: #f3f4f6;\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%], .plaintext-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: #f9fafb;\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: white;\n}"] });
1085
1251
  }
1086
1252
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArtifactViewerPanelComponent, [{
1087
1253
  type: Component,
1088
- args: [{ selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas fa-cube\"></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\" [class.clickable]=\"allVersions.length > 1\" (click)=\"toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1) {\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 (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n (click)=\"onSaveToLibrary()\"\n title=\"Save to Collection\">\n <i class=\"far fa-bookmark\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\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\">\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\">\n @if (hasDisplayTab) {\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'display'\" (click)=\"setActiveTab('display')\">\n <i class=\"fas fa-eye\"></i> Display\n </button>\n }\n @if (hasJsonTab) {\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'json'\" (click)=\"setActiveTab('json')\">\n <i class=\"fas fa-code\"></i> JSON\n </button>\n }\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'details'\" (click)=\"setActiveTab('details')\">\n <i class=\"fas fa-info-circle\"></i> Details\n </button>\n @if (hasLinksTab) {\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'links'\" (click)=\"setActiveTab('links')\">\n <i class=\"fas fa-link\"></i> Links\n </button>\n }\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Display Tab (uses plugin system OR extracted attributes) -->\n @if (activeTab === 'display' && hasDisplayTab) {\n <div class=\"display-content\">\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <!-- Use plugin viewer if available -->\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\">\n </mj-artifact-type-plugin-viewer>\n } @else 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 <markdown [data]=\"displayMarkdown\"></markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- JSON Tab (only shown for elevated displays with JSON content) -->\n @if (activeTab === 'json' && hasJsonTab) {\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 [(ngModel)]=\"jsonContent\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n\n <!-- Details Tab -->\n @if (activeTab === 'details') {\n <div class=\"details-content\">\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\n <!-- Links Tab -->\n @if (activeTab === 'links') {\n <div class=\"links-container\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\">\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 <button\n class=\"link-action-btn\"\n [disabled]=\"!link.hasAccess\"\n [title]=\"link.hasAccess ? 'Open' : 'No access'\"\n (click)=\"onNavigateToLink(link)\">\n <i class=\"fas fa-arrow-right\"></i>\n </button>\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 </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\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 #E5E7EB;\n background: white;\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: #6366F1;\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: #6B7280;\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: #F3F4F6;\n border-radius: 12px;\n font-size: 12px;\n color: #6B7280;\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: #E5E7EB;\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: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\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: #F9FAFB;\n}\n\n.version-option.selected {\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: #10B981;\n margin-left: auto;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #9CA3AF;\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: #F3F4F6;\n color: #6B7280;\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\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: #F3F4F6;\n color: #111827;\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: #6B7280;\n}\n\n.error-state {\n color: #DC2626;\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: #F9FAFB;\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: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: #111827;\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: #EFF6FF;\n border-left: 3px solid #3B82F6;\n border-radius: 4px;\n color: #1E40AF;\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 #E5E7EB;\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: #F9FAFB;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: #374151;\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n}\n\n.btn-icon.btn-primary {\n background: #4F46E5;\n border-color: #4F46E5;\n color: white;\n}\n\n.btn-icon.btn-primary:hover {\n background: #4338CA;\n border-color: #4338CA;\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\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 #E5E7EB;\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: #F59E0B;\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 #E5E7EB;\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: #374151;\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 14px;\n color: #111827;\n background: white;\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: #4F46E5;\n box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: #9CA3AF;\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: #E5E7EB;\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: #4F46E5;\n color: white;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #4338CA;\n}\n\n.btn-secondary {\n background: white;\n border: 1px solid #D1D5DB;\n color: #374151;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #F3F4F6;\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid #E5E7EB;\n padding: 0 16px;\n background: white;\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: #6B7280;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: #1e40af;\n background: #F9FAFB;\n}\n\n.tab-btn.active {\n color: #1e40af;\n border-bottom-color: #1e40af;\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\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}\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: #F9FAFB;\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: #111827;\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: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: #111827;\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n color: #9CA3AF;\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: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item:hover {\n border-color: #1e40af;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: #1e40af;\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: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n gap: 8px;\n}\n\n.link-action-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n color: #1e40af;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.link-action-btn:hover:not(:disabled) {\n background: #EFF6FF;\n border-color: #1e40af;\n}\n\n.link-action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n color: #9CA3AF;\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: #9CA3AF;\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"] }]
1089
- }], null, { artifactId: [{
1254
+ args: [{ selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\">\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas fa-cube\"></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\" [class.clickable]=\"allVersions.length > 1\" (click)=\"toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1) {\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 (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n (click)=\"onSaveToLibrary()\"\n title=\"Save to Collection\">\n <i class=\"far fa-bookmark\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\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\">\n <!-- Tab Navigation (Dynamic) -->\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 <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Display Tab - Special case for plugin rendering -->\n @if (activeTab === 'display') {\n <div class=\"display-content\">\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <!-- Use plugin viewer if available -->\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\">\n </mj-artifact-type-plugin-viewer>\n } @else 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 <markdown [data]=\"displayMarkdown\"></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 -->\n @if (activeTab === 'details') {\n <div class=\"details-content\">\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\n <!-- Links Tab - Conversations and Collections -->\n @if (activeTab === 'links') {\n <div class=\"links-container\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\">\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 <button\n class=\"link-action-btn\"\n [disabled]=\"!link.hasAccess\"\n [title]=\"link.hasAccess ? 'Open' : 'No access'\"\n (click)=\"onNavigateToLink(link)\">\n <i class=\"fas fa-arrow-right\"></i>\n </button>\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\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\" [innerHTML]=\"RenderMarkdown(tabData.content)\"></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 <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 }\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 </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\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 #E5E7EB;\n background: white;\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: #6366F1;\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: #6B7280;\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: #F3F4F6;\n border-radius: 12px;\n font-size: 12px;\n color: #6B7280;\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: #E5E7EB;\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: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\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: #F9FAFB;\n}\n\n.version-option.selected {\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: #10B981;\n margin-left: auto;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #9CA3AF;\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: #F3F4F6;\n color: #6B7280;\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\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: #F3F4F6;\n color: #111827;\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: #6B7280;\n}\n\n.error-state {\n color: #DC2626;\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: #F9FAFB;\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: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: #111827;\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: #EFF6FF;\n border-left: 3px solid #3B82F6;\n border-radius: 4px;\n color: #1E40AF;\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 #E5E7EB;\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: #F9FAFB;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: #374151;\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n}\n\n.btn-icon.btn-primary {\n background: #4F46E5;\n border-color: #4F46E5;\n color: white;\n}\n\n.btn-icon.btn-primary:hover {\n background: #4338CA;\n border-color: #4338CA;\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\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 #E5E7EB;\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: #F59E0B;\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 #E5E7EB;\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: #374151;\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 14px;\n color: #111827;\n background: white;\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: #4F46E5;\n box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: #9CA3AF;\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: #E5E7EB;\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: #4F46E5;\n color: white;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #4338CA;\n}\n\n.btn-secondary {\n background: white;\n border: 1px solid #D1D5DB;\n color: #374151;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #F3F4F6;\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid #E5E7EB;\n padding: 0 16px;\n background: white;\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: #6B7280;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: #1e40af;\n background: #F9FAFB;\n}\n\n.tab-btn.active {\n color: #1e40af;\n border-bottom-color: #1e40af;\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\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: #F9FAFB;\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: #111827;\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: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: #111827;\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n color: #9CA3AF;\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: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item:hover {\n border-color: #1e40af;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: #1e40af;\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: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: #6B7280;\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n gap: 8px;\n}\n\n.link-action-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n color: #1e40af;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.link-action-btn:hover:not(:disabled) {\n background: #EFF6FF;\n border-color: #1e40af;\n}\n\n.link-action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n color: #9CA3AF;\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: #9CA3AF;\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.markdown-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: white;\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: #f3f4f6;\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: #f3f4f6;\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, .plaintext-viewer {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: #f9fafb;\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: white;\n}\n"] }]
1255
+ }], () => [{ type: i1.MJNotificationService }, { type: i2.DomSanitizer }], { artifactId: [{
1090
1256
  type: Input
1091
1257
  }], currentUser: [{
1092
1258
  type: Input
@@ -1112,5 +1278,5 @@ export class ArtifactViewerPanelComponent {
1112
1278
  type: ViewChild,
1113
1279
  args: [ArtifactTypePluginViewerComponent]
1114
1280
  }] }); })();
1115
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactViewerPanelComponent, { className: "ArtifactViewerPanelComponent", filePath: "src/lib/components/artifact-viewer-panel.component.ts", lineNumber: 14 }); })();
1281
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactViewerPanelComponent, { className: "ArtifactViewerPanelComponent", filePath: "src/lib/components/artifact-viewer-panel.component.ts", lineNumber: 18 }); })();
1116
1282
  //# sourceMappingURL=artifact-viewer-panel.component.js.map