@memberjunction/ng-artifacts 2.107.0 → 2.108.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.
@@ -6,12 +6,13 @@ import { Subject } from 'rxjs';
6
6
  import { takeUntil } from 'rxjs/operators';
7
7
  import { ArtifactTypePluginViewerComponent } from './artifact-type-plugin-viewer.component';
8
8
  import * as i0 from "@angular/core";
9
- import * as i1 from "@angular/common";
10
- import * as i2 from "@angular/forms";
11
- import * as i3 from "ngx-markdown";
12
- import * as i4 from "@memberjunction/ng-code-editor";
13
- import * as i5 from "./artifact-type-plugin-viewer.component";
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";
14
14
  const _forTrack0 = ($index, $item) => $item.ID;
15
+ const _forTrack1 = ($index, $item) => $item.id;
15
16
  function ArtifactViewerPanelComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
16
17
  i0.ɵɵelementStart(0, "p", 4);
17
18
  i0.ɵɵtext(1);
@@ -22,26 +23,26 @@ function ArtifactViewerPanelComponent_Conditional_6_Template(rf, ctx) { if (rf &
22
23
  i0.ɵɵtextInterpolate(ctx_r0.displayDescription);
23
24
  } }
24
25
  function ArtifactViewerPanelComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
25
- i0.ɵɵelement(0, "i", 19);
26
+ i0.ɵɵelement(0, "i", 18);
26
27
  } if (rf & 2) {
27
28
  const ctx_r0 = i0.ɵɵnextContext();
28
29
  i0.ɵɵclassProp("open", ctx_r0.showVersionDropdown);
29
30
  } }
30
31
  function ArtifactViewerPanelComponent_Conditional_13_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
31
- i0.ɵɵelement(0, "i", 25);
32
+ i0.ɵɵelement(0, "i", 24);
32
33
  } }
33
34
  function ArtifactViewerPanelComponent_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
34
35
  const _r3 = i0.ɵɵgetCurrentView();
35
- i0.ɵɵelementStart(0, "div", 22);
36
+ i0.ɵɵelementStart(0, "div", 21);
36
37
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.selectVersion(version_r4); return i0.ɵɵresetView($event.stopPropagation()); });
37
- i0.ɵɵelementStart(1, "span", 23);
38
+ i0.ɵɵelementStart(1, "span", 22);
38
39
  i0.ɵɵtext(2);
39
40
  i0.ɵɵelementEnd();
40
- i0.ɵɵelementStart(3, "span", 24);
41
+ i0.ɵɵelementStart(3, "span", 23);
41
42
  i0.ɵɵtext(4);
42
43
  i0.ɵɵpipe(5, "date");
43
44
  i0.ɵɵelementEnd();
44
- i0.ɵɵtemplate(6, ArtifactViewerPanelComponent_Conditional_13_For_2_Conditional_6_Template, 1, 0, "i", 25);
45
+ i0.ɵɵtemplate(6, ArtifactViewerPanelComponent_Conditional_13_For_2_Conditional_6_Template, 1, 0, "i", 24);
45
46
  i0.ɵɵelementEnd();
46
47
  } if (rf & 2) {
47
48
  const version_r4 = ctx.$implicit;
@@ -56,9 +57,9 @@ function ArtifactViewerPanelComponent_Conditional_13_For_2_Template(rf, ctx) { i
56
57
  } }
57
58
  function ArtifactViewerPanelComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
58
59
  const _r2 = i0.ɵɵgetCurrentView();
59
- i0.ɵɵelementStart(0, "div", 20);
60
+ i0.ɵɵelementStart(0, "div", 19);
60
61
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_13_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r2); return i0.ɵɵresetView($event.stopPropagation()); });
61
- i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_13_For_2_Template, 7, 8, "div", 21, _forTrack0);
62
+ i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_13_For_2_Template, 7, 8, "div", 20, _forTrack0);
62
63
  i0.ɵɵelementEnd();
63
64
  } if (rf & 2) {
64
65
  const ctx_r0 = i0.ɵɵnextContext();
@@ -67,27 +68,21 @@ function ArtifactViewerPanelComponent_Conditional_13_Template(rf, ctx) { if (rf
67
68
  } }
68
69
  function ArtifactViewerPanelComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
69
70
  const _r5 = i0.ɵɵgetCurrentView();
70
- i0.ɵɵelementStart(0, "button", 26);
71
+ i0.ɵɵelementStart(0, "button", 25);
71
72
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSaveToLibrary()); });
72
- i0.ɵɵelement(1, "i", 27);
73
+ i0.ɵɵelement(1, "i", 26);
73
74
  i0.ɵɵelementEnd();
74
- } if (rf & 2) {
75
- const ctx_r0 = i0.ɵɵnextContext();
76
- i0.ɵɵclassProp("in-collection", ctx_r0.isInCollection);
77
- i0.ɵɵproperty("title", ctx_r0.isInCollection ? "View in Collection" : "Save to Collection");
78
- i0.ɵɵadvance();
79
- i0.ɵɵproperty("ngClass", ctx_r0.isInCollection ? "fas fa-bookmark" : "far fa-bookmark");
80
75
  } }
81
76
  function ArtifactViewerPanelComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
82
77
  i0.ɵɵelementStart(0, "div", 15);
83
- i0.ɵɵelement(1, "i", 28);
78
+ i0.ɵɵelement(1, "i", 27);
84
79
  i0.ɵɵelementStart(2, "span");
85
80
  i0.ɵɵtext(3, "Loading artifact...");
86
81
  i0.ɵɵelementEnd()();
87
82
  } }
88
83
  function ArtifactViewerPanelComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
89
84
  i0.ɵɵelementStart(0, "div", 16);
90
- i0.ɵɵelement(1, "i", 29);
85
+ i0.ɵɵelement(1, "i", 28);
91
86
  i0.ɵɵelementStart(2, "span");
92
87
  i0.ɵɵtext(3);
93
88
  i0.ɵɵelementEnd()();
@@ -98,7 +93,7 @@ function ArtifactViewerPanelComponent_Conditional_19_Template(rf, ctx) { if (rf
98
93
  } }
99
94
  function ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
100
95
  const _r7 = i0.ɵɵgetCurrentView();
101
- i0.ɵɵelementStart(0, "button", 32);
96
+ i0.ɵɵelementStart(0, "button", 31);
102
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")); });
103
98
  i0.ɵɵelement(1, "i", 38);
104
99
  i0.ɵɵtext(2, " Display ");
@@ -109,7 +104,7 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template(rf,
109
104
  } }
110
105
  function ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
111
106
  const _r8 = i0.ɵɵgetCurrentView();
112
- i0.ɵɵelementStart(0, "button", 32);
107
+ i0.ɵɵelementStart(0, "button", 31);
113
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")); });
114
109
  i0.ɵɵelement(1, "i", 39);
115
110
  i0.ɵɵtext(2, " JSON ");
@@ -118,58 +113,74 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template(rf,
118
113
  const ctx_r0 = i0.ɵɵnextContext(2);
119
114
  i0.ɵɵclassProp("active", ctx_r0.activeTab === "json");
120
115
  } }
121
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
122
- i0.ɵɵelement(0, "mj-artifact-type-plugin-viewer", 40);
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 ");
122
+ i0.ɵɵelementEnd();
123
+ } if (rf & 2) {
124
+ const ctx_r0 = i0.ɵɵnextContext(2);
125
+ i0.ɵɵclassProp("active", ctx_r0.activeTab === "links");
126
+ } }
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);
123
129
  } if (rf & 2) {
124
130
  const ctx_r0 = i0.ɵɵnextContext(3);
125
131
  i0.ɵɵproperty("artifactVersion", ctx_r0.artifactVersion)("artifactTypeName", ctx_r0.artifactTypeName)("contentType", ctx_r0.contentType)("readonly", true);
126
132
  } }
127
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵelementStart(0, "div", 44);
129
- i0.ɵɵelement(1, "markdown", 46);
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);
130
136
  i0.ɵɵelementEnd();
131
137
  } if (rf & 2) {
132
138
  const ctx_r0 = i0.ɵɵnextContext(4);
133
139
  i0.ɵɵadvance();
134
140
  i0.ɵɵproperty("data", ctx_r0.displayMarkdown);
135
141
  } }
136
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
137
- i0.ɵɵelement(0, "div", 45);
142
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
143
+ i0.ɵɵelement(0, "div", 48);
138
144
  } if (rf & 2) {
139
145
  const ctx_r0 = i0.ɵɵnextContext(4);
140
146
  i0.ɵɵproperty("innerHTML", ctx_r0.displayHtml, i0.ɵɵsanitizeHtml);
141
147
  } }
142
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
143
- const _r9 = i0.ɵɵgetCurrentView();
144
- i0.ɵɵelementStart(0, "div", 41)(1, "button", 42);
145
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onCopyDisplayContent()); });
146
- i0.ɵɵelement(2, "i", 43);
147
- i0.ɵɵtext(3, " Copy ");
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);
153
+ i0.ɵɵtext(3, " Print ");
154
+ 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);
158
+ i0.ɵɵtext(6, " Copy ");
148
159
  i0.ɵɵelementEnd()();
149
- i0.ɵɵtemplate(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Conditional_4_Template, 2, 1, "div", 44)(5, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Conditional_5_Template, 1, 1, "div", 45);
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);
150
161
  } if (rf & 2) {
151
162
  const ctx_r0 = i0.ɵɵnextContext(3);
152
- i0.ɵɵadvance(4);
153
- i0.ɵɵconditional(ctx_r0.displayMarkdown ? 4 : ctx_r0.displayHtml ? 5 : -1);
163
+ i0.ɵɵadvance(7);
164
+ i0.ɵɵconditional(ctx_r0.displayMarkdown ? 7 : ctx_r0.displayHtml ? 8 : -1);
154
165
  } }
155
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Template(rf, ctx) { if (rf & 1) {
156
- i0.ɵɵelementStart(0, "div", 35);
157
- i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_1_Template, 1, 4, "mj-artifact-type-plugin-viewer", 40)(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Conditional_2_Template, 6, 1);
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);
158
169
  i0.ɵɵelementEnd();
159
170
  } if (rf & 2) {
160
171
  const ctx_r0 = i0.ɵɵnextContext(2);
161
172
  i0.ɵɵadvance();
162
173
  i0.ɵɵconditional(ctx_r0.hasPlugin && ctx_r0.artifactVersion && ctx_r0.artifactTypeName ? 1 : ctx_r0.displayMarkdown || ctx_r0.displayHtml ? 2 : -1);
163
174
  } }
164
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template(rf, ctx) { if (rf & 1) {
165
- const _r10 = i0.ɵɵgetCurrentView();
166
- i0.ɵɵelementStart(0, "div", 36)(1, "div", 47)(2, "button", 48);
167
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onCopyToClipboard()); });
168
- i0.ɵɵelement(3, "i", 43);
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);
169
180
  i0.ɵɵtext(4, " Copy ");
170
181
  i0.ɵɵelementEnd()();
171
- i0.ɵɵelementStart(5, "div", 49)(6, "mj-code-editor", 50);
172
- i0.ɵɵtwoWayListener("ngModelChange", function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template_mj_code_editor_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.jsonContent, $event) || (ctx_r0.jsonContent = $event); return i0.ɵɵresetView($event); });
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); });
173
184
  i0.ɵɵelementEnd()()();
174
185
  } if (rf & 2) {
175
186
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -177,8 +188,8 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template(rf,
177
188
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.jsonContent);
178
189
  i0.ɵɵproperty("language", "json")("readonly", true);
179
190
  } }
180
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_24_Template(rf, ctx) { if (rf & 1) {
181
- i0.ɵɵelementStart(0, "div", 53)(1, "label");
191
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_24_Template(rf, ctx) { if (rf & 1) {
192
+ i0.ɵɵelementStart(0, "div", 56)(1, "label");
182
193
  i0.ɵɵtext(2, "Artifact Description");
183
194
  i0.ɵɵelementEnd();
184
195
  i0.ɵɵelementStart(3, "span");
@@ -189,8 +200,8 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_
189
200
  i0.ɵɵadvance(4);
190
201
  i0.ɵɵtextInterpolate(ctx_r0.artifact.Description);
191
202
  } }
192
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_25_Template(rf, ctx) { if (rf & 1) {
193
- i0.ɵɵelementStart(0, "div", 53)(1, "label");
203
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_25_Template(rf, ctx) { if (rf & 1) {
204
+ i0.ɵɵelementStart(0, "div", 56)(1, "label");
194
205
  i0.ɵɵtext(2, "Version Description");
195
206
  i0.ɵɵelementEnd();
196
207
  i0.ɵɵelementStart(3, "span");
@@ -201,75 +212,75 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_
201
212
  i0.ɵɵadvance(4);
202
213
  i0.ɵɵtextInterpolate(ctx_r0.artifactVersion == null ? null : ctx_r0.artifactVersion.Description);
203
214
  } }
204
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
215
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
205
216
  i0.ɵɵelementStart(0, "span");
206
217
  i0.ɵɵtext(1);
207
218
  i0.ɵɵelementEnd();
208
219
  } if (rf & 2) {
209
- const attr_r11 = i0.ɵɵnextContext().$implicit;
220
+ const attr_r12 = i0.ɵɵnextContext().$implicit;
210
221
  i0.ɵɵadvance();
211
- i0.ɵɵtextInterpolate(attr_r11.Value);
222
+ i0.ɵɵtextInterpolate(attr_r12.Value);
212
223
  } }
213
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
214
- i0.ɵɵelementStart(0, "span", 57);
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);
215
226
  i0.ɵɵtext(1, "Empty");
216
227
  i0.ɵɵelementEnd();
217
228
  } }
218
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Template(rf, ctx) { if (rf & 1) {
219
- i0.ɵɵelementStart(0, "div", 56)(1, "label");
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");
220
231
  i0.ɵɵtext(2);
221
232
  i0.ɵɵelementEnd();
222
- i0.ɵɵtemplate(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Conditional_4_Template, 2, 0, "span", 57);
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);
223
234
  i0.ɵɵelementEnd();
224
235
  } if (rf & 2) {
225
- const attr_r11 = ctx.$implicit;
236
+ const attr_r12 = ctx.$implicit;
226
237
  i0.ɵɵadvance(2);
227
- i0.ɵɵtextInterpolate(attr_r11.Name);
238
+ i0.ɵɵtextInterpolate(attr_r12.Name);
228
239
  i0.ɵɵadvance();
229
- i0.ɵɵconditional(attr_r11.Value ? 3 : 4);
240
+ i0.ɵɵconditional(attr_r12.Value ? 3 : 4);
230
241
  } }
231
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_Template(rf, ctx) { if (rf & 1) {
232
- i0.ɵɵelementStart(0, "div", 54)(1, "h4");
242
+ function ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_Template(rf, ctx) { if (rf & 1) {
243
+ i0.ɵɵelementStart(0, "div", 57)(1, "h4");
233
244
  i0.ɵɵtext(2, "Version Attributes");
234
245
  i0.ɵɵelementEnd();
235
- i0.ɵɵelementStart(3, "div", 55);
236
- i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_For_5_Template, 5, 2, "div", 56, _forTrack0);
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);
237
248
  i0.ɵɵelementEnd()();
238
249
  } if (rf & 2) {
239
250
  const ctx_r0 = i0.ɵɵnextContext(3);
240
251
  i0.ɵɵadvance(4);
241
252
  i0.ɵɵrepeater(ctx_r0.filteredAttributes);
242
253
  } }
243
- function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template(rf, ctx) { if (rf & 1) {
244
- i0.ɵɵelementStart(0, "div", 37)(1, "div", 51)(2, "div", 52)(3, "label");
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");
245
256
  i0.ɵɵtext(4, "Type");
246
257
  i0.ɵɵelementEnd();
247
258
  i0.ɵɵelementStart(5, "span");
248
259
  i0.ɵɵtext(6);
249
260
  i0.ɵɵelementEnd()();
250
- i0.ɵɵelementStart(7, "div", 52)(8, "label");
261
+ i0.ɵɵelementStart(7, "div", 55)(8, "label");
251
262
  i0.ɵɵtext(9, "Version");
252
263
  i0.ɵɵelementEnd();
253
264
  i0.ɵɵelementStart(10, "span");
254
265
  i0.ɵɵtext(11);
255
266
  i0.ɵɵelementEnd()();
256
- i0.ɵɵelementStart(12, "div", 52)(13, "label");
267
+ i0.ɵɵelementStart(12, "div", 55)(13, "label");
257
268
  i0.ɵɵtext(14, "Created");
258
269
  i0.ɵɵelementEnd();
259
270
  i0.ɵɵelementStart(15, "span");
260
271
  i0.ɵɵtext(16);
261
272
  i0.ɵɵpipe(17, "date");
262
273
  i0.ɵɵelementEnd()();
263
- i0.ɵɵelementStart(18, "div", 52)(19, "label");
274
+ i0.ɵɵelementStart(18, "div", 55)(19, "label");
264
275
  i0.ɵɵtext(20, "Updated");
265
276
  i0.ɵɵelementEnd();
266
277
  i0.ɵɵelementStart(21, "span");
267
278
  i0.ɵɵtext(22);
268
279
  i0.ɵɵpipe(23, "date");
269
280
  i0.ɵɵelementEnd()();
270
- i0.ɵɵtemplate(24, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_24_Template, 5, 1, "div", 53)(25, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_25_Template, 5, 1, "div", 53);
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);
271
282
  i0.ɵɵelementEnd();
272
- i0.ɵɵtemplate(26, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Conditional_26_Template, 6, 0, "div", 54);
283
+ i0.ɵɵtemplate(26, ArtifactViewerPanelComponent_Conditional_20_Conditional_11_Conditional_26_Template, 6, 0, "div", 57);
273
284
  i0.ɵɵelementEnd();
274
285
  } if (rf & 2) {
275
286
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -288,122 +299,95 @@ function ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template(rf,
288
299
  i0.ɵɵadvance();
289
300
  i0.ɵɵconditional(ctx_r0.filteredAttributes.length > 0 ? 26 : -1);
290
301
  } }
291
- function ArtifactViewerPanelComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
292
- const _r6 = i0.ɵɵgetCurrentView();
293
- i0.ɵɵelementStart(0, "div", 17)(1, "div", 30);
294
- i0.ɵɵtemplate(2, ArtifactViewerPanelComponent_Conditional_20_Conditional_2_Template, 3, 2, "button", 31)(3, ArtifactViewerPanelComponent_Conditional_20_Conditional_3_Template, 3, 2, "button", 31);
295
- i0.ɵɵelementStart(4, "button", 32);
296
- 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")); });
297
- i0.ɵɵelement(5, "i", 33);
298
- i0.ɵɵtext(6, " Details ");
299
- i0.ɵɵelementEnd()();
300
- i0.ɵɵelementStart(7, "div", 34);
301
- i0.ɵɵtemplate(8, ArtifactViewerPanelComponent_Conditional_20_Conditional_8_Template, 3, 1, "div", 35)(9, ArtifactViewerPanelComponent_Conditional_20_Conditional_9_Template, 7, 3, "div", 36)(10, ArtifactViewerPanelComponent_Conditional_20_Conditional_10_Template, 27, 13, "div", 37);
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);
304
+ } }
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);
307
+ } }
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);
312
+ i0.ɵɵelementEnd();
313
+ i0.ɵɵelementStart(4, "div", 67)(5, "div", 68);
314
+ i0.ɵɵtext(6);
315
+ i0.ɵɵelementEnd();
316
+ i0.ɵɵelementStart(7, "div", 69);
317
+ i0.ɵɵtext(8);
302
318
  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);
322
+ i0.ɵɵelementEnd()()();
303
323
  } if (rf & 2) {
304
- const ctx_r0 = i0.ɵɵnextContext();
324
+ const link_r14 = ctx.$implicit;
305
325
  i0.ɵɵadvance(2);
306
- i0.ɵɵconditional(ctx_r0.hasDisplayTab ? 2 : -1);
307
- i0.ɵɵadvance();
308
- i0.ɵɵconditional(ctx_r0.hasJsonTab ? 3 : -1);
309
- i0.ɵɵadvance();
310
- i0.ɵɵclassProp("active", ctx_r0.activeTab === "details");
326
+ i0.ɵɵconditional(link_r14.type === "conversation" ? 2 : 3);
311
327
  i0.ɵɵadvance(4);
312
- i0.ɵɵconditional(ctx_r0.activeTab === "display" && ctx_r0.hasDisplayTab ? 8 : -1);
313
- i0.ɵɵadvance();
314
- i0.ɵɵconditional(ctx_r0.activeTab === "json" && ctx_r0.hasJsonTab ? 9 : -1);
315
- i0.ɵɵadvance();
316
- i0.ɵɵconditional(ctx_r0.activeTab === "details" ? 10 : -1);
328
+ i0.ɵɵtextInterpolate(link_r14.name);
329
+ i0.ɵɵadvance(2);
330
+ i0.ɵɵtextInterpolate(link_r14.type === "conversation" ? "Conversation" : "Collection");
331
+ i0.ɵɵadvance(2);
332
+ i0.ɵɵproperty("disabled", !link_r14.hasAccess)("title", link_r14.hasAccess ? "Open" : "No access");
317
333
  } }
318
- function ArtifactViewerPanelComponent_Conditional_21_For_16_Template(rf, ctx) { if (rf & 1) {
319
- i0.ɵɵelementStart(0, "option", 66);
320
- i0.ɵɵtext(1);
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);
321
337
  i0.ɵɵelementEnd();
322
338
  } if (rf & 2) {
323
- const collection_r13 = ctx.$implicit;
324
- i0.ɵɵproperty("ngValue", collection_r13.ID);
339
+ const ctx_r0 = i0.ɵɵnextContext(3);
325
340
  i0.ɵɵadvance();
326
- i0.ɵɵtextInterpolate(collection_r13.Name);
327
- } }
328
- function ArtifactViewerPanelComponent_Conditional_21_Conditional_26_Template(rf, ctx) { if (rf & 1) {
329
- i0.ɵɵelement(0, "i", 28);
341
+ i0.ɵɵrepeater(ctx_r0.linksToShow);
330
342
  } }
331
- function ArtifactViewerPanelComponent_Conditional_21_Conditional_27_Template(rf, ctx) { if (rf & 1) {
332
- i0.ɵɵelement(0, "i", 71);
333
- } }
334
- function ArtifactViewerPanelComponent_Conditional_21_Conditional_33_Template(rf, ctx) { if (rf & 1) {
335
- i0.ɵɵelement(0, "i", 28);
336
- i0.ɵɵtext(1, " Saving... ");
337
- } }
338
- function ArtifactViewerPanelComponent_Conditional_21_Conditional_34_Template(rf, ctx) { if (rf & 1) {
339
- i0.ɵɵelement(0, "i", 75);
340
- i0.ɵɵtext(1, " Save to Collection ");
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);
346
+ i0.ɵɵelementStart(2, "p");
347
+ i0.ɵɵtext(3, "No links available");
348
+ i0.ɵɵelementEnd()();
341
349
  } }
342
- function ArtifactViewerPanelComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
343
- const _r12 = i0.ɵɵgetCurrentView();
344
- i0.ɵɵelementStart(0, "div", 58);
345
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.cancelLibraryDialog()); });
346
- i0.ɵɵelementStart(1, "div", 59);
347
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
348
- i0.ɵɵelementStart(2, "div", 60)(3, "h3");
349
- i0.ɵɵelement(4, "i", 61);
350
- i0.ɵɵtext(5, " Save to Collection ");
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);
351
353
  i0.ɵɵelementEnd();
352
- i0.ɵɵelementStart(6, "button", 62);
353
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.cancelLibraryDialog()); });
354
- i0.ɵɵelement(7, "i", 13);
355
- i0.ɵɵelementEnd()();
356
- i0.ɵɵelementStart(8, "div", 63)(9, "div", 64)(10, "label");
357
- i0.ɵɵtext(11, "Select Collection");
354
+ } if (rf & 2) {
355
+ const ctx_r0 = i0.ɵɵnextContext(2);
356
+ i0.ɵɵadvance();
357
+ i0.ɵɵconditional(ctx_r0.linksToShow.length > 0 ? 1 : 2);
358
+ } }
359
+ function ArtifactViewerPanelComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
360
+ const _r6 = i0.ɵɵgetCurrentView();
361
+ 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 ");
358
367
  i0.ɵɵelementEnd();
359
- i0.ɵɵelementStart(12, "select", 65);
360
- i0.ɵɵtwoWayListener("ngModelChange", function ArtifactViewerPanelComponent_Conditional_21_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.selectedCollectionId, $event) || (ctx_r0.selectedCollectionId = $event); return i0.ɵɵresetView($event); });
361
- i0.ɵɵelementStart(13, "option", 66);
362
- i0.ɵɵtext(14, "-- Choose a collection --");
368
+ i0.ɵɵtemplate(7, ArtifactViewerPanelComponent_Conditional_20_Conditional_7_Template, 3, 2, "button", 30);
363
369
  i0.ɵɵelementEnd();
364
- i0.ɵɵrepeaterCreate(15, ArtifactViewerPanelComponent_Conditional_21_For_16_Template, 2, 2, "option", 66, _forTrack0);
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);
365
372
  i0.ɵɵelementEnd()();
366
- i0.ɵɵelementStart(17, "div", 67)(18, "span");
367
- i0.ɵɵtext(19, "OR");
368
- i0.ɵɵelementEnd()();
369
- i0.ɵɵelementStart(20, "div", 64)(21, "label");
370
- i0.ɵɵtext(22, "Create New Collection");
371
- i0.ɵɵelementEnd();
372
- i0.ɵɵelementStart(23, "div", 68)(24, "input", 69);
373
- i0.ɵɵtwoWayListener("ngModelChange", function ArtifactViewerPanelComponent_Conditional_21_Template_input_ngModelChange_24_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.newCollectionName, $event) || (ctx_r0.newCollectionName = $event); return i0.ɵɵresetView($event); });
374
- i0.ɵɵlistener("keyup.enter", function ArtifactViewerPanelComponent_Conditional_21_Template_input_keyup_enter_24_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.createNewCollection()); });
375
- i0.ɵɵelementEnd();
376
- i0.ɵɵelementStart(25, "button", 70);
377
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.createNewCollection()); });
378
- i0.ɵɵtemplate(26, ArtifactViewerPanelComponent_Conditional_21_Conditional_26_Template, 1, 0, "i", 28)(27, ArtifactViewerPanelComponent_Conditional_21_Conditional_27_Template, 1, 0, "i", 71);
379
- i0.ɵɵtext(28, " Create ");
380
- i0.ɵɵelementEnd()()()();
381
- i0.ɵɵelementStart(29, "div", 72)(30, "button", 73);
382
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.cancelLibraryDialog()); });
383
- i0.ɵɵtext(31, " Cancel ");
384
- i0.ɵɵelementEnd();
385
- i0.ɵɵelementStart(32, "button", 74);
386
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_21_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.saveToSelectedCollection()); });
387
- i0.ɵɵtemplate(33, ArtifactViewerPanelComponent_Conditional_21_Conditional_33_Template, 2, 0)(34, ArtifactViewerPanelComponent_Conditional_21_Conditional_34_Template, 2, 0);
388
- i0.ɵɵelementEnd()()()();
389
373
  } if (rf & 2) {
390
374
  const ctx_r0 = i0.ɵɵnextContext();
391
- i0.ɵɵadvance(12);
392
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.selectedCollectionId);
375
+ i0.ɵɵadvance(2);
376
+ i0.ɵɵconditional(ctx_r0.hasDisplayTab ? 2 : -1);
393
377
  i0.ɵɵadvance();
394
- i0.ɵɵproperty("ngValue", null);
378
+ i0.ɵɵconditional(ctx_r0.hasJsonTab ? 3 : -1);
379
+ i0.ɵɵadvance();
380
+ i0.ɵɵclassProp("active", ctx_r0.activeTab === "details");
381
+ i0.ɵɵadvance(3);
382
+ i0.ɵɵconditional(ctx_r0.hasLinksTab ? 7 : -1);
395
383
  i0.ɵɵadvance(2);
396
- i0.ɵɵrepeater(ctx_r0.collections);
397
- i0.ɵɵadvance(9);
398
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.newCollectionName);
384
+ i0.ɵɵconditional(ctx_r0.activeTab === "display" && ctx_r0.hasDisplayTab ? 9 : -1);
399
385
  i0.ɵɵadvance();
400
- i0.ɵɵproperty("disabled", ctx_r0.isCreatingCollection || !ctx_r0.newCollectionName.trim());
386
+ i0.ɵɵconditional(ctx_r0.activeTab === "json" && ctx_r0.hasJsonTab ? 10 : -1);
401
387
  i0.ɵɵadvance();
402
- i0.ɵɵconditional(ctx_r0.isCreatingCollection ? 26 : 27);
403
- i0.ɵɵadvance(6);
404
- i0.ɵɵproperty("disabled", !ctx_r0.selectedCollectionId || ctx_r0.isSavingToLibrary);
388
+ i0.ɵɵconditional(ctx_r0.activeTab === "details" ? 11 : -1);
405
389
  i0.ɵɵadvance();
406
- i0.ɵɵconditional(ctx_r0.isSavingToLibrary ? 33 : 34);
390
+ i0.ɵɵconditional(ctx_r0.activeTab === "links" ? 12 : -1);
407
391
  } }
408
392
  export class ArtifactViewerPanelComponent {
409
393
  artifactId;
@@ -412,7 +396,11 @@ export class ArtifactViewerPanelComponent {
412
396
  versionNumber; // Version to display
413
397
  showSaveToCollection = true; // Control whether Save to Collection button is shown
414
398
  refreshTrigger;
399
+ viewContext = null; // Where artifact is being viewed
400
+ contextCollectionId; // If viewing in collection, which collection
415
401
  closed = new EventEmitter();
402
+ saveToCollectionRequested = new EventEmitter();
403
+ navigateToLink = new EventEmitter();
416
404
  pluginViewer;
417
405
  destroy$ = new Subject();
418
406
  artifact = null;
@@ -423,12 +411,6 @@ export class ArtifactViewerPanelComponent {
423
411
  error = null;
424
412
  jsonContent = '';
425
413
  showVersionDropdown = false;
426
- showLibraryDialog = false;
427
- collections = [];
428
- selectedCollectionId = null;
429
- newCollectionName = '';
430
- isCreatingCollection = false;
431
- isSavingToLibrary = false;
432
414
  artifactCollections = [];
433
415
  primaryCollection = null;
434
416
  // Tabbed interface
@@ -437,6 +419,10 @@ export class ArtifactViewerPanelComponent {
437
419
  displayHtml = null;
438
420
  versionAttributes = [];
439
421
  artifactTypeDriverClass = null;
422
+ // Links tab data
423
+ originConversation = null;
424
+ allCollections = [];
425
+ hasAccessToOriginConversation = false;
440
426
  // Cache plugin state to avoid losing it when switching tabs
441
427
  cachedPluginShouldShowRaw = false;
442
428
  cachedPluginIsElevated = false;
@@ -540,6 +526,8 @@ export class ArtifactViewerPanelComponent {
540
526
  await this.loadVersionAttributes();
541
527
  // Load collection associations
542
528
  await this.loadCollectionAssociations();
529
+ // Load links data
530
+ await this.loadLinksData();
543
531
  console.log(`📦 Loaded ${this.allVersions.length} versions for artifact ${this.artifactId}, showing v${this.selectedVersionNumber}`);
544
532
  }
545
533
  else {
@@ -590,6 +578,10 @@ export class ArtifactViewerPanelComponent {
590
578
  // Parse values - they might be JSON-encoded strings
591
579
  this.displayMarkdown = this.parseAttributeValue(displayMarkdownAttr?.Value);
592
580
  this.displayHtml = this.parseAttributeValue(displayHtmlAttr?.Value);
581
+ // Clean up double-escaped characters in HTML (from LLM generation)
582
+ if (this.displayHtml) {
583
+ this.displayHtml = this.cleanEscapedCharacters(this.displayHtml);
584
+ }
593
585
  // Default to display tab if we have a plugin or extracted display content
594
586
  // Otherwise default to JSON tab for JSON types, or Details tab as last resort
595
587
  if (this.hasDisplayTab) {
@@ -676,6 +668,22 @@ export class ArtifactViewerPanelComponent {
676
668
  }
677
669
  return value;
678
670
  }
671
+ /**
672
+ * Clean up double-escaped characters that appear in LLM-generated HTML
673
+ * Removes literal "\\n" and "\\t" which cause rendering issues
674
+ */
675
+ cleanEscapedCharacters(html) {
676
+ // Remove escaped newlines (\\n becomes nothing)
677
+ // HTML doesn't need whitespace for formatting, and these cause display issues
678
+ let cleaned = html.replace(/\\n/g, '');
679
+ // Remove escaped tabs
680
+ cleaned = cleaned.replace(/\\t/g, '');
681
+ // Remove double-escaped tabs
682
+ cleaned = cleaned.replace(/\\\\t/g, '');
683
+ // Remove double-escaped newlines
684
+ cleaned = cleaned.replace(/\\\\n/g, '');
685
+ return cleaned;
686
+ }
679
687
  async loadCollectionAssociations() {
680
688
  if (!this.artifactId)
681
689
  return;
@@ -714,7 +722,7 @@ export class ArtifactViewerPanelComponent {
714
722
  }
715
723
  }
716
724
  onCopyDisplayContent() {
717
- const content = this.displayMarkdown || this.displayHtml;
725
+ const content = this.displayHtml || this.displayMarkdown;
718
726
  if (content) {
719
727
  navigator.clipboard.writeText(content).then(() => {
720
728
  console.log('✅ Copied display content to clipboard');
@@ -723,6 +731,50 @@ export class ArtifactViewerPanelComponent {
723
731
  });
724
732
  }
725
733
  }
734
+ onPrintDisplayContent() {
735
+ // Try to delegate to the plugin viewer's print method
736
+ if (this.pluginViewer?.pluginInstance) {
737
+ const plugin = this.pluginViewer.pluginInstance;
738
+ if (typeof plugin.printHtml === 'function') {
739
+ plugin.printHtml();
740
+ return;
741
+ }
742
+ }
743
+ // Fallback: create a temporary print window with displayHtml or displayMarkdown
744
+ const content = this.displayHtml || this.displayMarkdown;
745
+ if (content) {
746
+ const printWindow = window.open('', '_blank');
747
+ if (printWindow) {
748
+ if (this.displayHtml) {
749
+ printWindow.document.write(content);
750
+ }
751
+ else if (this.displayMarkdown) {
752
+ // Wrap markdown in basic HTML for printing
753
+ printWindow.document.write(`
754
+ <!DOCTYPE html>
755
+ <html>
756
+ <head>
757
+ <title>Print</title>
758
+ <style>
759
+ body { font-family: sans-serif; padding: 20px; }
760
+ pre { background: #f5f5f5; padding: 10px; border-radius: 4px; }
761
+ </style>
762
+ </head>
763
+ <body>
764
+ <pre>${content}</pre>
765
+ </body>
766
+ </html>
767
+ `);
768
+ }
769
+ printWindow.document.close();
770
+ printWindow.focus();
771
+ setTimeout(() => {
772
+ printWindow.print();
773
+ printWindow.close();
774
+ }, 250);
775
+ }
776
+ }
777
+ }
726
778
  toggleVersionDropdown() {
727
779
  if (this.allVersions.length > 1) {
728
780
  this.showVersionDropdown = !this.showVersionDropdown;
@@ -738,127 +790,199 @@ export class ArtifactViewerPanelComponent {
738
790
  console.log(`📦 Switched to version ${this.selectedVersionNumber}`);
739
791
  }
740
792
  async onSaveToLibrary() {
741
- // If already in a collection, navigate to that collection
742
- if (this.isInCollection && this.primaryCollection) {
743
- // TODO: Implement navigation to collection view
744
- // For now, just log - will need ConversationStateService or similar to navigate
745
- console.log('Navigate to collection:', this.primaryCollection.Name, this.primaryCollection.ID);
746
- MJNotificationService.Instance.CreateSimpleNotification(`This artifact is saved in collection: ${this.primaryCollection.Name}`, 'info', 3000);
747
- return;
748
- }
749
- // If not in a collection, show the save dialog
750
- try {
751
- // Load user's collections
752
- const rv = new RunView();
753
- const result = await rv.RunView({
754
- EntityName: 'MJ: Collections',
755
- ExtraFilter: `EnvironmentID='${this.environmentId}'`,
756
- OrderBy: 'Name',
757
- ResultType: 'entity_object'
758
- }, this.currentUser);
759
- if (result.Success) {
760
- this.collections = result.Results || [];
761
- this.showLibraryDialog = true;
762
- }
763
- else {
764
- console.error('Failed to load collections:', result.ErrorMessage);
765
- MJNotificationService.Instance.CreateSimpleNotification('Failed to load collections. Please try again.', 'error');
766
- }
767
- }
768
- catch (err) {
769
- console.error('Error loading collections:', err);
770
- MJNotificationService.Instance.CreateSimpleNotification('Error loading collections. Please try again.', 'error');
771
- }
793
+ // Always show the collection picker modal
794
+ // Artifacts can be saved to multiple collections
795
+ this.saveToCollectionRequested.emit({
796
+ artifactId: this.artifactId,
797
+ excludedCollectionIds: this.excludedCollectionIds
798
+ });
772
799
  }
773
- async createNewCollection() {
774
- if (!this.newCollectionName.trim()) {
775
- MJNotificationService.Instance.CreateSimpleNotification('Please enter a collection name', 'warning', 2000);
776
- return;
800
+ get excludedCollectionIds() {
801
+ // Return IDs of collections that already contain this artifact
802
+ return this.artifactCollections.map(ca => ca.CollectionID);
803
+ }
804
+ /**
805
+ * Called by parent component after user selects collections in the picker.
806
+ * Saves the artifact to the selected collections.
807
+ */
808
+ async saveToCollections(collectionIds) {
809
+ if (!this.artifactId || collectionIds.length === 0) {
810
+ return false;
777
811
  }
778
812
  try {
779
- this.isCreatingCollection = true;
780
813
  const md = new Metadata();
781
- const collection = await md.GetEntityObject('MJ: Collections', this.currentUser);
782
- collection.EnvironmentID = this.environmentId;
783
- collection.Name = this.newCollectionName.trim();
784
- collection.Description = 'Created from conversation';
785
- const saved = await collection.Save();
786
- if (saved) {
787
- this.collections.push(collection);
788
- this.selectedCollectionId = collection.ID;
789
- this.newCollectionName = '';
790
- console.log('✅ Created new collection:', collection.Name);
791
- MJNotificationService.Instance.CreateSimpleNotification(`Collection "${collection.Name}" created successfully!`, 'success', 3000);
814
+ let successCount = 0;
815
+ // Save artifact to each selected collection
816
+ for (const collectionId of collectionIds) {
817
+ // Double check it doesn't already exist
818
+ const rv = new RunView();
819
+ const existingResult = await rv.RunView({
820
+ EntityName: 'MJ: Collection Artifacts',
821
+ ExtraFilter: `CollectionID='${collectionId}' AND ArtifactID='${this.artifactId}'`,
822
+ ResultType: 'entity_object'
823
+ }, this.currentUser);
824
+ if (existingResult.Success && existingResult.Results && existingResult.Results.length > 0) {
825
+ console.log(`Artifact already in collection ${collectionId}, skipping`);
826
+ continue;
827
+ }
828
+ // Create junction record
829
+ const collectionArtifact = await md.GetEntityObject('MJ: Collection Artifacts', this.currentUser);
830
+ collectionArtifact.CollectionID = collectionId;
831
+ collectionArtifact.ArtifactID = this.artifactId;
832
+ collectionArtifact.Sequence = 0;
833
+ const saved = await collectionArtifact.Save();
834
+ if (saved) {
835
+ successCount++;
836
+ }
837
+ else {
838
+ console.error(`Failed to save artifact to collection ${collectionId}`);
839
+ }
840
+ }
841
+ if (successCount > 0) {
842
+ console.log(`✅ Saved artifact to ${successCount} collection(s)`);
843
+ MJNotificationService.Instance.CreateSimpleNotification(`Artifact saved to ${successCount} collection(s) successfully!`, 'success', 3000);
844
+ // Reload collection associations to update the bookmark icon state
845
+ await this.loadCollectionAssociations();
846
+ return true;
792
847
  }
793
848
  else {
794
- MJNotificationService.Instance.CreateSimpleNotification('Failed to create collection. Please try again.', 'error');
849
+ MJNotificationService.Instance.CreateSimpleNotification('Failed to save artifact to any collections', 'error');
850
+ return false;
795
851
  }
796
852
  }
797
853
  catch (err) {
798
- console.error('Error creating collection:', err);
854
+ console.error('Error saving to collections:', err);
799
855
  LogError(err);
800
- MJNotificationService.Instance.CreateSimpleNotification('Error creating collection. Please try again.', 'error');
801
- }
802
- finally {
803
- this.isCreatingCollection = false;
856
+ MJNotificationService.Instance.CreateSimpleNotification('Error saving artifact to collections. Please try again.', 'error');
857
+ return false;
804
858
  }
805
859
  }
806
- async saveToSelectedCollection() {
807
- if (!this.selectedCollectionId) {
808
- MJNotificationService.Instance.CreateSimpleNotification('Please select a collection', 'warning', 2000);
809
- return;
810
- }
811
- if (!this.artifactId) {
812
- MJNotificationService.Instance.CreateSimpleNotification('No artifact to save', 'error');
860
+ /**
861
+ * Load links data: origin conversation and all collections containing this artifact
862
+ */
863
+ async loadLinksData() {
864
+ if (!this.artifactId)
813
865
  return;
814
- }
815
866
  try {
816
- this.isSavingToLibrary = true;
817
- // Check if artifact already exists in this collection
867
+ const md = new Metadata();
818
868
  const rv = new RunView();
819
- const existingResult = await rv.RunView({
869
+ // Load all collections containing this artifact
870
+ const collArtifactsResult = await rv.RunView({
820
871
  EntityName: 'MJ: Collection Artifacts',
821
- ExtraFilter: `CollectionID='${this.selectedCollectionId}' AND ArtifactID='${this.artifactId}'`,
872
+ ExtraFilter: `ArtifactID='${this.artifactId}'`,
822
873
  ResultType: 'entity_object'
823
874
  }, this.currentUser);
824
- if (existingResult.Success && existingResult.Results && existingResult.Results.length > 0) {
825
- MJNotificationService.Instance.CreateSimpleNotification('This artifact is already in the selected collection', 'info', 3000);
826
- this.showLibraryDialog = false;
827
- return;
828
- }
829
- // Create junction record
830
- const md = new Metadata();
831
- const collectionArtifact = await md.GetEntityObject('MJ: Collection Artifacts', this.currentUser);
832
- collectionArtifact.CollectionID = this.selectedCollectionId;
833
- collectionArtifact.ArtifactID = this.artifactId;
834
- collectionArtifact.Sequence = 0; // Could calculate max sequence + 1 if needed
835
- const saved = await collectionArtifact.Save();
836
- if (saved) {
837
- const collectionName = this.collections.find(c => c.ID === this.selectedCollectionId)?.Name || 'collection';
838
- console.log(`✅ Saved artifact to ${collectionName}`);
839
- MJNotificationService.Instance.CreateSimpleNotification(`Artifact saved to ${collectionName} successfully!`, 'success', 3000);
840
- this.showLibraryDialog = false;
841
- this.selectedCollectionId = null;
842
- // Reload collection associations to update the bookmark icon state
843
- await this.loadCollectionAssociations();
875
+ if (collArtifactsResult.Success && collArtifactsResult.Results) {
876
+ // Get unique collection IDs
877
+ const collectionIds = [...new Set(collArtifactsResult.Results.map(ca => ca.CollectionID))];
878
+ if (collectionIds.length > 0) {
879
+ const collectionsFilter = collectionIds.map(id => `ID='${id}'`).join(' OR ');
880
+ const collectionsResult = await rv.RunView({
881
+ EntityName: 'MJ: Collections',
882
+ ExtraFilter: collectionsFilter,
883
+ ResultType: 'entity_object'
884
+ }, this.currentUser);
885
+ if (collectionsResult.Success && collectionsResult.Results) {
886
+ this.allCollections = collectionsResult.Results;
887
+ }
888
+ }
844
889
  }
845
- else {
846
- MJNotificationService.Instance.CreateSimpleNotification('Failed to save artifact to collection. Please try again.', 'error');
890
+ // Load origin conversation (if artifact came from conversation)
891
+ // Artifacts are linked to conversations via ConversationDetailArtifact -> ConversationDetail -> Conversation
892
+ // Get all version IDs for this artifact
893
+ const versionIds = this.allVersions.map(v => v.ID);
894
+ if (versionIds.length > 0) {
895
+ const versionFilter = versionIds.map(id => `ArtifactVersionID='${id}'`).join(' OR ');
896
+ const convDetailArtifactsResult = await rv.RunView({
897
+ EntityName: 'MJ: Conversation Detail Artifacts',
898
+ ExtraFilter: versionFilter,
899
+ MaxRows: 1,
900
+ ResultType: 'entity_object'
901
+ }, this.currentUser);
902
+ if (convDetailArtifactsResult.Success && convDetailArtifactsResult.Results && convDetailArtifactsResult.Results.length > 0) {
903
+ const conversationDetailId = convDetailArtifactsResult.Results[0].ConversationDetailID;
904
+ // Load the conversation detail to get the conversation ID
905
+ const conversationDetail = await md.GetEntityObject('Conversation Details', this.currentUser);
906
+ const detailLoaded = await conversationDetail.Load(conversationDetailId);
907
+ if (detailLoaded && conversationDetail.ConversationID) {
908
+ const conversation = await md.GetEntityObject('Conversations', this.currentUser);
909
+ const loaded = await conversation.Load(conversationDetail.ConversationID);
910
+ if (loaded) {
911
+ this.originConversation = conversation;
912
+ // Check if user has access (is owner or participant)
913
+ const userIsOwner = conversation.UserID === this.currentUser.ID;
914
+ // Check if user is a participant
915
+ const participantResult = await rv.RunView({
916
+ EntityName: 'Conversation Details',
917
+ ExtraFilter: `ConversationID='${conversation.ID}' AND UserID='${this.currentUser.ID}'`,
918
+ MaxRows: 1,
919
+ ResultType: 'simple'
920
+ }, this.currentUser);
921
+ const userIsParticipant = participantResult.Success &&
922
+ participantResult.Results &&
923
+ participantResult.Results.length > 0;
924
+ this.hasAccessToOriginConversation = userIsOwner || userIsParticipant;
925
+ }
926
+ }
927
+ }
847
928
  }
929
+ console.log(`🔗 Loaded links: ${this.allCollections.length} collections, origin conversation: ${this.originConversation?.Name || 'none'}`);
848
930
  }
849
- catch (err) {
850
- console.error('Error saving to collection:', err);
851
- LogError(err);
852
- MJNotificationService.Instance.CreateSimpleNotification('Error saving artifact to collection. Please try again.', 'error');
931
+ catch (error) {
932
+ console.error('Error loading links data:', error);
853
933
  }
854
- finally {
855
- this.isSavingToLibrary = false;
934
+ }
935
+ get hasLinksTab() {
936
+ // Show links tab if:
937
+ // 1. Viewing in collection and there's an origin conversation OR other collections
938
+ // 2. Viewing in conversation and there are any collections
939
+ if (this.viewContext === 'collection') {
940
+ // Show if there's an origin conversation, or more than 1 collection (current + others)
941
+ return !!this.originConversation || this.allCollections.length > 1;
942
+ }
943
+ else if (this.viewContext === 'conversation') {
944
+ // Show if there are any collections
945
+ return this.allCollections.length > 0;
856
946
  }
947
+ return false;
857
948
  }
858
- cancelLibraryDialog() {
859
- this.showLibraryDialog = false;
860
- this.selectedCollectionId = null;
861
- this.newCollectionName = '';
949
+ get linksToShow() {
950
+ const links = [];
951
+ // Add origin conversation if viewing in collection
952
+ if (this.viewContext === 'collection' && this.originConversation) {
953
+ links.push({
954
+ type: 'conversation',
955
+ id: this.originConversation.ID,
956
+ name: this.originConversation.Name || 'Untitled Conversation',
957
+ hasAccess: this.hasAccessToOriginConversation
958
+ });
959
+ }
960
+ // Add all collections (excluding current context if applicable)
961
+ for (const collection of this.allCollections) {
962
+ if (this.viewContext === 'collection' && collection.ID === this.contextCollectionId) {
963
+ // Skip current collection
964
+ continue;
965
+ }
966
+ links.push({
967
+ type: 'collection',
968
+ id: collection.ID,
969
+ name: collection.Name,
970
+ hasAccess: true // User can see it, so they have access
971
+ });
972
+ }
973
+ return links;
974
+ }
975
+ /**
976
+ * Navigate to a linked conversation or collection
977
+ */
978
+ onNavigateToLink(link) {
979
+ if (!link.hasAccess) {
980
+ return;
981
+ }
982
+ this.navigateToLink.emit({
983
+ type: link.type,
984
+ id: link.id
985
+ });
862
986
  }
863
987
  onClose() {
864
988
  this.closed.emit();
@@ -913,7 +1037,7 @@ export class ArtifactViewerPanelComponent {
913
1037
  } if (rf & 2) {
914
1038
  let _t;
915
1039
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pluginViewer = _t.first);
916
- } }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", refreshTrigger: "refreshTrigger" }, outputs: { closed: "closed" }, features: [i0.ɵɵNgOnChangesFeature], decls: 22, vars: 12, 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"], [1, "save-to-collection-btn", 3, "in-collection", "title"], ["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, "modal-overlay"], [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"], [1, "save-to-collection-btn", 3, "click", "title"], [3, "ngClass"], [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, "fas", "fa-eye"], [1, "fas", "fa-code"], [3, "artifactVersion", "artifactTypeName", "contentType", "readonly"], [1, "display-toolbar"], ["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, "modal-overlay", 3, "click"], [1, "modal-content", "library-modal", 3, "click"], [1, "modal-header"], [1, "fas", "fa-bookmark"], [1, "close-btn", 3, "click"], [1, "modal-body"], [1, "form-section"], [1, "form-select", 3, "ngModelChange", "ngModel"], [3, "ngValue"], [1, "divider"], [1, "create-collection-row"], ["type", "text", "placeholder", "Enter collection name", 1, "form-input", 3, "ngModelChange", "keyup.enter", "ngModel"], [1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "modal-footer"], [1, "btn", "btn-secondary", 3, "click"], [1, "btn", "btn-primary", 3, "click", "disabled"], [1, "fas", "fa-save"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
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) {
917
1041
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h3");
918
1042
  i0.ɵɵelement(4, "i", 3);
919
1043
  i0.ɵɵtext(5);
@@ -928,15 +1052,14 @@ export class ArtifactViewerPanelComponent {
928
1052
  i0.ɵɵelementEnd();
929
1053
  i0.ɵɵtemplate(12, ArtifactViewerPanelComponent_Conditional_12_Template, 1, 2, "i", 9)(13, ArtifactViewerPanelComponent_Conditional_13_Template, 3, 0, "div", 10);
930
1054
  i0.ɵɵelementEnd();
931
- i0.ɵɵtemplate(14, ArtifactViewerPanelComponent_Conditional_14_Template, 2, 4, "button", 11);
1055
+ i0.ɵɵtemplate(14, ArtifactViewerPanelComponent_Conditional_14_Template, 2, 0, "button", 11);
932
1056
  i0.ɵɵelementStart(15, "button", 12);
933
1057
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Template_button_click_15_listener() { return ctx.onClose(); });
934
1058
  i0.ɵɵelement(16, "i", 13);
935
1059
  i0.ɵɵelementEnd()()();
936
1060
  i0.ɵɵelementStart(17, "div", 14);
937
- 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, 11, 7, "div", 17);
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);
938
1062
  i0.ɵɵelementEnd()();
939
- i0.ɵɵtemplate(21, ArtifactViewerPanelComponent_Conditional_21_Template, 35, 7, "div", 18);
940
1063
  } if (rf & 2) {
941
1064
  i0.ɵɵadvance(5);
942
1065
  i0.ɵɵtextInterpolate1(" ", ctx.displayName, " ");
@@ -958,13 +1081,11 @@ export class ArtifactViewerPanelComponent {
958
1081
  i0.ɵɵconditional(ctx.error ? 19 : -1);
959
1082
  i0.ɵɵadvance();
960
1083
  i0.ɵɵconditional(!ctx.isLoading && !ctx.error && ctx.artifact ? 20 : -1);
961
- i0.ɵɵadvance();
962
- i0.ɵɵconditional(ctx.showLibraryDialog ? 21 : -1);
963
- } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MarkdownComponent, i4.CodeEditorComponent, i5.ArtifactTypePluginViewerComponent, i1.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid #E5E7EB;\n background: white;\n flex-shrink: 0;\n}\n\n.panel-header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\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: center;\n gap: 8px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366F1;\n flex-shrink: 0;\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}\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.in-collection[_ngcontent-%COMP%] {\n color: #F59E0B;\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%]:hover {\n background: #FEF3C7;\n color: #D97706;\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}\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}\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}\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}\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;\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}"] });
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}"] });
964
1085
  }
965
1086
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArtifactViewerPanelComponent, [{
966
1087
  type: Component,
967
- 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 [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'View in Collection' : 'Save to Collection'\">\n <i [ngClass]=\"isInCollection ? 'fas fa-bookmark' : '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 </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=\"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 </div>\n </div>\n }\n </div>\n</div>\n\n<!-- Save to Collection Dialog -->\n@if (showLibraryDialog) {\n <div class=\"modal-overlay\" (click)=\"cancelLibraryDialog()\">\n <div class=\"modal-content library-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>\n <i class=\"fas fa-bookmark\"></i>\n Save to Collection\n </h3>\n <button class=\"close-btn\" (click)=\"cancelLibraryDialog()\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-section\">\n <label>Select Collection</label>\n <select [(ngModel)]=\"selectedCollectionId\" class=\"form-select\">\n <option [ngValue]=\"null\">-- Choose a collection --</option>\n @for (collection of collections; track collection.ID) {\n <option [ngValue]=\"collection.ID\">{{ collection.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"divider\">\n <span>OR</span>\n </div>\n\n <div class=\"form-section\">\n <label>Create New Collection</label>\n <div class=\"create-collection-row\">\n <input\n type=\"text\"\n [(ngModel)]=\"newCollectionName\"\n placeholder=\"Enter collection name\"\n class=\"form-input\"\n (keyup.enter)=\"createNewCollection()\">\n <button\n class=\"btn btn-secondary\"\n (click)=\"createNewCollection()\"\n [disabled]=\"isCreatingCollection || !newCollectionName.trim()\">\n @if (isCreatingCollection) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fas fa-plus\"></i>\n }\n Create\n </button>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"cancelLibraryDialog()\">\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"saveToSelectedCollection()\"\n [disabled]=\"!selectedCollectionId || isSavingToLibrary\">\n @if (isSavingToLibrary) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fas fa-save\"></i> Save to Collection\n }\n </button>\n </div>\n </div>\n </div>\n}\n", styles: [".artifact-viewer-panel {\n height: 100%;\n background: white;\n border-left: 1px solid #E5E7EB;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid #E5E7EB;\n background: white;\n flex-shrink: 0;\n}\n\n.panel-header-left {\n flex: 1;\n min-width: 0;\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-header h3 i {\n color: #6366F1;\n flex-shrink: 0;\n}\n\n.header-description {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: #6B7280;\n font-weight: normal;\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.in-collection {\n color: #F59E0B;\n}\n\n.save-to-collection-btn.in-collection:hover {\n background: #FEF3C7;\n color: #D97706;\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}\n\n.artifact-content-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\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}\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}\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;\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"] }]
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"] }]
968
1089
  }], null, { artifactId: [{
969
1090
  type: Input
970
1091
  }], currentUser: [{
@@ -977,8 +1098,16 @@ export class ArtifactViewerPanelComponent {
977
1098
  type: Input
978
1099
  }], refreshTrigger: [{
979
1100
  type: Input
1101
+ }], viewContext: [{
1102
+ type: Input
1103
+ }], contextCollectionId: [{
1104
+ type: Input
980
1105
  }], closed: [{
981
1106
  type: Output
1107
+ }], saveToCollectionRequested: [{
1108
+ type: Output
1109
+ }], navigateToLink: [{
1110
+ type: Output
982
1111
  }], pluginViewer: [{
983
1112
  type: ViewChild,
984
1113
  args: [ArtifactTypePluginViewerComponent]