@memberjunction/ng-skip-chat 2.48.0 → 2.50.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.
Files changed (31) hide show
  1. package/dist/lib/artifacts/skip-artifact-viewer.component.js +254 -270
  2. package/dist/lib/artifacts/skip-artifact-viewer.component.js.map +1 -1
  3. package/dist/lib/artifacts/skip-artifacts-counter.component.js +82 -90
  4. package/dist/lib/artifacts/skip-artifacts-counter.component.js.map +1 -1
  5. package/dist/lib/drill-down-info.js +4 -3
  6. package/dist/lib/drill-down-info.js.map +1 -1
  7. package/dist/lib/dynamic-report/base-report.js +147 -164
  8. package/dist/lib/dynamic-report/base-report.js.map +1 -1
  9. package/dist/lib/dynamic-report/dynamic-chart.js +77 -86
  10. package/dist/lib/dynamic-report/dynamic-chart.js.map +1 -1
  11. package/dist/lib/dynamic-report/dynamic-grid.js +80 -93
  12. package/dist/lib/dynamic-report/dynamic-grid.js.map +1 -1
  13. package/dist/lib/dynamic-report/dynamic-ui-component.js +173 -188
  14. package/dist/lib/dynamic-report/dynamic-ui-component.js.map +1 -1
  15. package/dist/lib/dynamic-report/linear-report.js +16 -26
  16. package/dist/lib/dynamic-report/linear-report.js.map +1 -1
  17. package/dist/lib/dynamic-report/skip-dynamic-report-wrapper.js +28 -28
  18. package/dist/lib/dynamic-report/skip-dynamic-report-wrapper.js.map +1 -1
  19. package/dist/lib/dynamic-report/skip-react-component-host.js +203 -212
  20. package/dist/lib/dynamic-report/skip-react-component-host.js.map +1 -1
  21. package/dist/lib/module.js +22 -22
  22. package/dist/lib/module.js.map +1 -1
  23. package/dist/lib/report-cache.js +2 -5
  24. package/dist/lib/report-cache.js.map +1 -1
  25. package/dist/lib/skip-chat/skip-chat.component.js +1052 -1087
  26. package/dist/lib/skip-chat/skip-chat.component.js.map +1 -1
  27. package/dist/lib/skip-single-message/skip-single-message.component.js +251 -259
  28. package/dist/lib/skip-single-message/skip-single-message.component.js.map +1 -1
  29. package/dist/lib/split-panel/skip-split-panel.component.js +52 -51
  30. package/dist/lib/split-panel/skip-split-panel.component.js.map +1 -1
  31. package/package.json +13 -13
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { Component, Input, ViewChild, ViewContainerRef, Output, EventEmitter } from '@angular/core';
11
2
  import { RunView, LogError } from '@memberjunction/core';
12
3
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
@@ -75,43 +66,48 @@ function SkipArtifactViewerComponent_Conditional_5_Template(rf, ctx) { if (rf &
75
66
  i0.ɵɵconditional(ctx_r0.artifactVersion ? 2 : -1);
76
67
  } }
77
68
  export class SkipArtifactViewerComponent extends BaseAngularComponent {
69
+ notificationService;
70
+ componentFactoryResolver;
71
+ cdRef;
72
+ injector;
73
+ ArtifactID = '';
74
+ ArtifactVersionID = '';
75
+ DataContext = null;
76
+ reportContainer;
77
+ /**
78
+ * Event emitted when the user clicks on a matching report and the application needs to handle the navigation
79
+ */
80
+ NavigateToMatchingReport = new EventEmitter();
81
+ /**
82
+ * This event fires whenever a new report is created.
83
+ */
84
+ NewReportCreated = new EventEmitter();
85
+ /**
86
+ * This event fires whenever a drill down is requested within a given report.
87
+ */
88
+ DrillDownEvent = new EventEmitter();
89
+ /**
90
+ * Event that emits the artifact info for display in parent components
91
+ */
92
+ ArtifactInfoChanged = new EventEmitter();
93
+ isLoading = false;
94
+ artifact = null;
95
+ artifactVersion = null;
96
+ artifactType = null;
97
+ contentType = '';
98
+ displayContent = null;
99
+ error = null;
100
+ artifactVersions = [];
101
+ selectedVersionId = '';
102
+ showVersionDropdown = false;
103
+ reportComponentRef = null;
104
+ conversationDetailRecord = null;
78
105
  constructor(notificationService, componentFactoryResolver, cdRef, injector) {
79
106
  super();
80
107
  this.notificationService = notificationService;
81
108
  this.componentFactoryResolver = componentFactoryResolver;
82
109
  this.cdRef = cdRef;
83
110
  this.injector = injector;
84
- this.ArtifactID = '';
85
- this.ArtifactVersionID = '';
86
- this.DataContext = null;
87
- /**
88
- * Event emitted when the user clicks on a matching report and the application needs to handle the navigation
89
- */
90
- this.NavigateToMatchingReport = new EventEmitter();
91
- /**
92
- * This event fires whenever a new report is created.
93
- */
94
- this.NewReportCreated = new EventEmitter();
95
- /**
96
- * This event fires whenever a drill down is requested within a given report.
97
- */
98
- this.DrillDownEvent = new EventEmitter();
99
- /**
100
- * Event that emits the artifact info for display in parent components
101
- */
102
- this.ArtifactInfoChanged = new EventEmitter();
103
- this.isLoading = false;
104
- this.artifact = null;
105
- this.artifactVersion = null;
106
- this.artifactType = null;
107
- this.contentType = '';
108
- this.displayContent = null;
109
- this.error = null;
110
- this.artifactVersions = [];
111
- this.selectedVersionId = '';
112
- this.showVersionDropdown = false;
113
- this.reportComponentRef = null;
114
- this.conversationDetailRecord = null;
115
111
  }
116
112
  ngOnInit() {
117
113
  if (this.ArtifactID) {
@@ -130,105 +126,101 @@ export class SkipArtifactViewerComponent extends BaseAngularComponent {
130
126
  if (this.artifact && this.artifactVersion) {
131
127
  // Use setTimeout to avoid ExpressionChangedAfterItHasBeenCheckedError
132
128
  // and to ensure reportContainer is properly initialized
133
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
129
+ setTimeout(async () => {
134
130
  if (this.reportContainer) {
135
- yield this.createReportComponent();
131
+ await this.createReportComponent();
136
132
  }
137
133
  else {
138
134
  // If the container is still not available, try once more after a longer delay
139
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
135
+ setTimeout(async () => {
140
136
  if (this.reportContainer) {
141
- yield this.createReportComponent();
137
+ await this.createReportComponent();
142
138
  }
143
139
  else {
144
140
  LogError('Report container still not available after multiple attempts');
145
141
  }
146
- }), 100);
142
+ }, 100);
147
143
  }
148
- }), 0);
144
+ }, 0);
149
145
  }
150
146
  }
151
- loadArtifact() {
152
- return __awaiter(this, void 0, void 0, function* () {
153
- if (!this.ArtifactID) {
154
- return;
147
+ async loadArtifact() {
148
+ if (!this.ArtifactID) {
149
+ return;
150
+ }
151
+ this.isLoading = true;
152
+ this.error = null;
153
+ try {
154
+ const provider = this.ProviderToUse;
155
+ // Load the artifact
156
+ const artifactEntity = await provider.GetEntityObject('MJ: Conversation Artifacts', provider.CurrentUser);
157
+ if (!await artifactEntity.Load(this.ArtifactID)) {
158
+ throw new Error(`Failed to load artifact: ${artifactEntity.LatestResult.Message}`);
155
159
  }
156
- this.isLoading = true;
157
- this.error = null;
158
- try {
159
- const provider = this.ProviderToUse;
160
- // Load the artifact
161
- const artifactEntity = yield provider.GetEntityObject('MJ: Conversation Artifacts', provider.CurrentUser);
162
- if (!(yield artifactEntity.Load(this.ArtifactID))) {
163
- throw new Error(`Failed to load artifact: ${artifactEntity.LatestResult.Message}`);
164
- }
165
- this.artifact = artifactEntity;
166
- // Load the artifact type
167
- const artifactTypeEntity = yield provider.GetEntityObject('MJ: Artifact Types', provider.CurrentUser);
168
- if (!(yield artifactTypeEntity.Load(this.artifact.ArtifactTypeID))) {
169
- throw new Error(`Failed to load artifact type: ${artifactTypeEntity.LatestResult.Message}`);
170
- }
171
- this.artifactType = artifactTypeEntity;
172
- this.contentType = this.artifactType.ContentType;
173
- // Load all versions of this artifact for the dropdown
174
- yield this.loadArtifactVersions();
175
- // Load the specific artifact version if provided, otherwise use the latest version
176
- if (this.ArtifactVersionID) {
177
- this.loadSpecificArtifactVersion(this.ArtifactVersionID);
178
- }
179
- else if (this.artifactVersions.length > 0) {
180
- // Use the latest version (first in the list since we sort by Version DESC)
181
- this.artifactVersion = this.artifactVersions[0];
182
- this.selectedVersionId = this.artifactVersion.ID;
183
- }
184
- else {
185
- throw new Error('No artifact versions found');
186
- }
187
- // Emit artifact info for parent components
188
- this.emitArtifactInfo();
189
- // Create the report component after a short delay to ensure Angular has time to initialize the view
190
- this.isLoading = false;
191
- this.cdRef.detectChanges(); // Trigger change detection to update the view
192
- setTimeout(() => {
193
- // Check again if view is initialized
194
- if (this.reportContainer) {
195
- this.createReportComponent();
196
- }
197
- else {
198
- // If still not initialized, we'll try again in ngAfterViewInit
199
- LogError('Report container not yet initialized, will try in ngAfterViewInit');
200
- }
201
- }, 0);
160
+ this.artifact = artifactEntity;
161
+ // Load the artifact type
162
+ const artifactTypeEntity = await provider.GetEntityObject('MJ: Artifact Types', provider.CurrentUser);
163
+ if (!await artifactTypeEntity.Load(this.artifact.ArtifactTypeID)) {
164
+ throw new Error(`Failed to load artifact type: ${artifactTypeEntity.LatestResult.Message}`);
202
165
  }
203
- catch (err) {
204
- LogError('Error loading artifact', err instanceof Error ? err.message : String(err));
205
- this.error = err instanceof Error ? err.message : 'Unknown error loading artifact';
206
- this.notificationService.CreateSimpleNotification('Error loading artifact', 'error', 3000);
166
+ this.artifactType = artifactTypeEntity;
167
+ this.contentType = this.artifactType.ContentType;
168
+ // Load all versions of this artifact for the dropdown
169
+ await this.loadArtifactVersions();
170
+ // Load the specific artifact version if provided, otherwise use the latest version
171
+ if (this.ArtifactVersionID) {
172
+ this.loadSpecificArtifactVersion(this.ArtifactVersionID);
207
173
  }
208
- finally {
209
- this.isLoading = false;
174
+ else if (this.artifactVersions.length > 0) {
175
+ // Use the latest version (first in the list since we sort by Version DESC)
176
+ this.artifactVersion = this.artifactVersions[0];
177
+ this.selectedVersionId = this.artifactVersion.ID;
210
178
  }
211
- });
179
+ else {
180
+ throw new Error('No artifact versions found');
181
+ }
182
+ // Emit artifact info for parent components
183
+ this.emitArtifactInfo();
184
+ // Create the report component after a short delay to ensure Angular has time to initialize the view
185
+ this.isLoading = false;
186
+ this.cdRef.detectChanges(); // Trigger change detection to update the view
187
+ setTimeout(() => {
188
+ // Check again if view is initialized
189
+ if (this.reportContainer) {
190
+ this.createReportComponent();
191
+ }
192
+ else {
193
+ // If still not initialized, we'll try again in ngAfterViewInit
194
+ LogError('Report container not yet initialized, will try in ngAfterViewInit');
195
+ }
196
+ }, 0);
197
+ }
198
+ catch (err) {
199
+ LogError('Error loading artifact', err instanceof Error ? err.message : String(err));
200
+ this.error = err instanceof Error ? err.message : 'Unknown error loading artifact';
201
+ this.notificationService.CreateSimpleNotification('Error loading artifact', 'error', 3000);
202
+ }
203
+ finally {
204
+ this.isLoading = false;
205
+ }
212
206
  }
213
207
  /**
214
208
  * Loads all versions of the current artifact for the dropdown
215
209
  */
216
- loadArtifactVersions() {
217
- return __awaiter(this, void 0, void 0, function* () {
218
- const runView = new RunView(this.RunViewToUse);
219
- const versionResult = yield runView.RunView({
220
- EntityName: 'MJ: Conversation Artifact Versions',
221
- ResultType: 'entity_object',
222
- OrderBy: 'Version DESC',
223
- ExtraFilter: `ConversationArtifactID = '${this.ArtifactID}'`
224
- });
225
- if (versionResult && versionResult.Success && versionResult.Results.length > 0) {
226
- this.artifactVersions = versionResult.Results;
227
- }
228
- else {
229
- this.artifactVersions = [];
230
- }
210
+ async loadArtifactVersions() {
211
+ const runView = new RunView(this.RunViewToUse);
212
+ const versionResult = await runView.RunView({
213
+ EntityName: 'MJ: Conversation Artifact Versions',
214
+ ResultType: 'entity_object',
215
+ OrderBy: 'Version DESC',
216
+ ExtraFilter: `ConversationArtifactID = '${this.ArtifactID}'`
231
217
  });
218
+ if (versionResult && versionResult.Success && versionResult.Results.length > 0) {
219
+ this.artifactVersions = versionResult.Results;
220
+ }
221
+ else {
222
+ this.artifactVersions = [];
223
+ }
232
224
  }
233
225
  /**
234
226
  * Loads a specific artifact version by ID
@@ -245,159 +237,152 @@ export class SkipArtifactViewerComponent extends BaseAngularComponent {
245
237
  /**
246
238
  * Called when the user selects a different version from the dropdown
247
239
  */
248
- onVersionChange() {
249
- return __awaiter(this, void 0, void 0, function* () {
250
- if (this.selectedVersionId) {
251
- this.isLoading = true;
252
- try {
253
- // Destroy existing component if any
254
- this.destroyReportComponent();
255
- // Load the selected version
256
- this.loadSpecificArtifactVersion(this.selectedVersionId);
257
- // Emit updated artifact info
258
- this.emitArtifactInfo();
259
- this.isLoading = false;
260
- this.cdRef.detectChanges(); // Trigger change detection to update the view
261
- // Wait for the next Angular cycle and ensure reportContainer is available
262
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
263
- if (this.reportContainer) {
264
- yield this.createReportComponent();
265
- }
266
- else {
267
- // If the container is still not available, try once more after a longer delay
268
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
269
- if (this.reportContainer) {
270
- yield this.createReportComponent();
271
- }
272
- else {
273
- LogError('Report container not available when changing versions');
274
- }
275
- }), 100);
276
- }
277
- }), 0);
278
- }
279
- catch (err) {
280
- LogError('Error changing artifact version', err instanceof Error ? err.message : String(err));
281
- this.error = err instanceof Error ? err.message : 'Unknown error loading artifact version';
282
- this.notificationService.CreateSimpleNotification('Error loading artifact version', 'error', 3000);
283
- this.isLoading = false;
284
- }
240
+ async onVersionChange() {
241
+ if (this.selectedVersionId) {
242
+ this.isLoading = true;
243
+ try {
244
+ // Destroy existing component if any
245
+ this.destroyReportComponent();
246
+ // Load the selected version
247
+ this.loadSpecificArtifactVersion(this.selectedVersionId);
248
+ // Emit updated artifact info
249
+ this.emitArtifactInfo();
250
+ this.isLoading = false;
251
+ this.cdRef.detectChanges(); // Trigger change detection to update the view
252
+ // Wait for the next Angular cycle and ensure reportContainer is available
253
+ setTimeout(async () => {
254
+ if (this.reportContainer) {
255
+ await this.createReportComponent();
256
+ }
257
+ else {
258
+ // If the container is still not available, try once more after a longer delay
259
+ setTimeout(async () => {
260
+ if (this.reportContainer) {
261
+ await this.createReportComponent();
262
+ }
263
+ else {
264
+ LogError('Report container not available when changing versions');
265
+ }
266
+ }, 100);
267
+ }
268
+ }, 0);
285
269
  }
286
- });
270
+ catch (err) {
271
+ LogError('Error changing artifact version', err instanceof Error ? err.message : String(err));
272
+ this.error = err instanceof Error ? err.message : 'Unknown error loading artifact version';
273
+ this.notificationService.CreateSimpleNotification('Error loading artifact version', 'error', 3000);
274
+ this.isLoading = false;
275
+ }
276
+ }
287
277
  }
288
278
  /**
289
279
  * Creates the report component using the current artifact version Configuration
290
280
  */
291
- createReportComponent() {
292
- return __awaiter(this, void 0, void 0, function* () {
293
- var _a;
294
- if (!this.reportContainer || !this.artifactVersion) {
295
- return;
296
- }
297
- // Clear any existing component
298
- this.destroyReportComponent();
299
- this.reportContainer.clear();
300
- try {
301
- // Load conversation detail record to get AI message
302
- yield this.loadConversationDetail();
303
- // Create the report component based on Configuration
304
- const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SkipDynamicReportWrapperComponent);
305
- this.reportComponentRef = this.reportContainer.createComponent(componentFactory);
306
- if (this.reportComponentRef) {
307
- const instance = this.reportComponentRef.instance;
308
- // Initialize from AI message or Configuration
309
- let configData = null;
310
- if (this.conversationDetailRecord &&
311
- this.conversationDetailRecord.Role.trim().toLowerCase() === 'ai' &&
312
- ((_a = this.conversationDetailRecord.ID) === null || _a === void 0 ? void 0 : _a.length) > 0) {
313
- try {
314
- const resultObject = JSON.parse(this.conversationDetailRecord.Message);
315
- if (resultObject.success && resultObject.responsePhase === SkipResponsePhase.analysis_complete) {
316
- // Use the Skip API response data directly
317
- configData = resultObject;
318
- }
319
- }
320
- catch (parseErr) {
321
- LogError('Error parsing AI message', parseErr instanceof Error ? parseErr.message : String(parseErr));
281
+ async createReportComponent() {
282
+ if (!this.reportContainer || !this.artifactVersion) {
283
+ return;
284
+ }
285
+ // Clear any existing component
286
+ this.destroyReportComponent();
287
+ this.reportContainer.clear();
288
+ try {
289
+ // Load conversation detail record to get AI message
290
+ await this.loadConversationDetail();
291
+ // Create the report component based on Configuration
292
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SkipDynamicReportWrapperComponent);
293
+ this.reportComponentRef = this.reportContainer.createComponent(componentFactory);
294
+ if (this.reportComponentRef) {
295
+ const instance = this.reportComponentRef.instance;
296
+ // Initialize from AI message or Configuration
297
+ let configData = null;
298
+ if (this.conversationDetailRecord &&
299
+ this.conversationDetailRecord.Role.trim().toLowerCase() === 'ai' &&
300
+ this.conversationDetailRecord.ID?.length > 0) {
301
+ try {
302
+ const resultObject = JSON.parse(this.conversationDetailRecord.Message);
303
+ if (resultObject.success && resultObject.responsePhase === SkipResponsePhase.analysis_complete) {
304
+ // Use the Skip API response data directly
305
+ configData = resultObject;
322
306
  }
323
307
  }
324
- // If we couldn't get data from AI message, try using the artifact version Configuration
325
- if (!configData) {
326
- try {
327
- if (typeof this.artifactVersion.Configuration === 'string') {
328
- configData = JSON.parse(this.artifactVersion.Configuration);
329
- }
330
- else {
331
- // If it's already an object, use it directly
332
- configData = this.artifactVersion.Configuration;
333
- }
308
+ catch (parseErr) {
309
+ LogError('Error parsing AI message', parseErr instanceof Error ? parseErr.message : String(parseErr));
310
+ }
311
+ }
312
+ // If we couldn't get data from AI message, try using the artifact version Configuration
313
+ if (!configData) {
314
+ try {
315
+ if (typeof this.artifactVersion.Configuration === 'string') {
316
+ configData = JSON.parse(this.artifactVersion.Configuration);
334
317
  }
335
- catch (parseErr) {
336
- LogError('Error parsing artifact configuration', parseErr instanceof Error ? parseErr.message : String(parseErr));
337
- configData = null;
318
+ else {
319
+ // If it's already an object, use it directly
320
+ configData = this.artifactVersion.Configuration;
338
321
  }
339
322
  }
340
- if (!configData) {
341
- throw new Error('No valid configuration data found');
342
- }
343
- // Set properties on the report component
344
- instance.SkipData = configData;
345
- instance.Provider = this.ProviderToUse;
346
- // Set up event handlers
347
- instance.NavigateToMatchingReport.subscribe((reportID) => {
348
- this.NavigateToMatchingReport.emit(reportID); // bubble up
349
- });
350
- instance.NewReportCreated.subscribe((reportID) => {
351
- this.NewReportCreated.emit(reportID); // bubble up
352
- });
353
- instance.DrillDownEvent.subscribe((drillDownInfo) => {
354
- this.DrillDownEvent.emit(drillDownInfo); // bubble up
355
- });
356
- // Set additional properties
357
- if (this.DataContext) {
358
- instance.DataContext = this.DataContext;
359
- }
360
- instance.AllowDrillDown = false; // Disable drill-down in artifact viewer for simplicity
361
- // Set conversation info if available
362
- if (this.conversationDetailRecord) {
363
- instance.ConversationID = this.conversationDetailRecord.ConversationID;
364
- instance.ConversationDetailID = this.conversationDetailRecord.ID;
365
- instance.ConversationName = this.conversationDetailRecord.Conversation;
323
+ catch (parseErr) {
324
+ LogError('Error parsing artifact configuration', parseErr instanceof Error ? parseErr.message : String(parseErr));
325
+ configData = null;
366
326
  }
367
327
  }
328
+ if (!configData) {
329
+ throw new Error('No valid configuration data found');
330
+ }
331
+ // Set properties on the report component
332
+ instance.SkipData = configData;
333
+ instance.Provider = this.ProviderToUse;
334
+ // Set up event handlers
335
+ instance.NavigateToMatchingReport.subscribe((reportID) => {
336
+ this.NavigateToMatchingReport.emit(reportID); // bubble up
337
+ });
338
+ instance.NewReportCreated.subscribe((reportID) => {
339
+ this.NewReportCreated.emit(reportID); // bubble up
340
+ });
341
+ instance.DrillDownEvent.subscribe((drillDownInfo) => {
342
+ this.DrillDownEvent.emit(drillDownInfo); // bubble up
343
+ });
344
+ // Set additional properties
345
+ if (this.DataContext) {
346
+ instance.DataContext = this.DataContext;
347
+ }
348
+ instance.AllowDrillDown = false; // Disable drill-down in artifact viewer for simplicity
349
+ // Set conversation info if available
350
+ if (this.conversationDetailRecord) {
351
+ instance.ConversationID = this.conversationDetailRecord.ConversationID;
352
+ instance.ConversationDetailID = this.conversationDetailRecord.ID;
353
+ instance.ConversationName = this.conversationDetailRecord.Conversation;
354
+ }
368
355
  }
369
- catch (err) {
370
- LogError('Error creating report component', err instanceof Error ? err.message : String(err));
371
- this.error = 'Failed to create artifact viewer component: ' + (err instanceof Error ? err.message : String(err));
372
- }
373
- });
356
+ }
357
+ catch (err) {
358
+ LogError('Error creating report component', err instanceof Error ? err.message : String(err));
359
+ this.error = 'Failed to create artifact viewer component: ' + (err instanceof Error ? err.message : String(err));
360
+ }
374
361
  }
375
362
  /**
376
363
  * Loads the conversation detail record associated with this artifact
377
364
  */
378
- loadConversationDetail() {
379
- return __awaiter(this, void 0, void 0, function* () {
380
- if (!this.artifact || !this.artifact.ID) {
381
- return;
382
- }
383
- try {
384
- // Get the conversation detail record
385
- const runView = new RunView(this.RunViewToUse);
386
- const detailsResult = yield runView.RunView({
387
- EntityName: 'Conversation Details',
388
- ResultType: 'entity_object',
389
- ExtraFilter: `ArtifactID = '${this.artifact.ID}' ${this.artifactVersion ? `AND ArtifactVersionID = '${this.artifactVersion.ID}'` : ''}`,
390
- OrderBy: '__mj_CreatedAt DESC' // Get most recent first
391
- });
392
- if (detailsResult && detailsResult.Success && detailsResult.Results.length > 0) {
393
- this.conversationDetailRecord = detailsResult.Results[0];
394
- }
395
- }
396
- catch (err) {
397
- LogError('Error loading conversation detail for artifact', err instanceof Error ? err.message : String(err));
398
- // Don't set an error here, as this is non-critical - we can still try to use Configuration
365
+ async loadConversationDetail() {
366
+ if (!this.artifact || !this.artifact.ID) {
367
+ return;
368
+ }
369
+ try {
370
+ // Get the conversation detail record
371
+ const runView = new RunView(this.RunViewToUse);
372
+ const detailsResult = await runView.RunView({
373
+ EntityName: 'Conversation Details',
374
+ ResultType: 'entity_object',
375
+ ExtraFilter: `ArtifactID = '${this.artifact.ID}' ${this.artifactVersion ? `AND ArtifactVersionID = '${this.artifactVersion.ID}'` : ''}`,
376
+ OrderBy: '__mj_CreatedAt DESC' // Get most recent first
377
+ });
378
+ if (detailsResult && detailsResult.Success && detailsResult.Results.length > 0) {
379
+ this.conversationDetailRecord = detailsResult.Results[0];
399
380
  }
400
- });
381
+ }
382
+ catch (err) {
383
+ LogError('Error loading conversation detail for artifact', err instanceof Error ? err.message : String(err));
384
+ // Don't set an error here, as this is non-critical - we can still try to use Configuration
385
+ }
401
386
  }
402
387
  /**
403
388
  * Destroys the current report component if it exists
@@ -457,40 +442,39 @@ export class SkipArtifactViewerComponent extends BaseAngularComponent {
457
442
  * Emits the current artifact info to parent components
458
443
  */
459
444
  emitArtifactInfo() {
460
- var _a, _b;
461
445
  if (this.artifact) {
462
446
  this.ArtifactInfoChanged.emit({
463
447
  title: this.artifactTitle,
464
448
  type: this.artifactTypeName,
465
- date: ((_a = this.artifactVersion) === null || _a === void 0 ? void 0 : _a.__mj_CreatedAt) || null,
449
+ date: this.artifactVersion?.__mj_CreatedAt || null,
466
450
  version: this.getCurrentVersionNumber(),
467
451
  versionList: this.artifactVersions.map(v => ({
468
452
  ID: v.ID,
469
453
  Version: v.Version,
470
454
  __mj_CreatedAt: v.__mj_CreatedAt
471
455
  })),
472
- selectedVersionId: ((_b = this.artifactVersion) === null || _b === void 0 ? void 0 : _b.ID) || ''
456
+ selectedVersionId: this.artifactVersion?.ID || ''
473
457
  });
474
458
  }
475
459
  }
476
460
  get isPlainText() {
477
461
  return this.contentType.includes('text/plain');
478
462
  }
463
+ static ɵfac = function SkipArtifactViewerComponent_Factory(t) { return new (t || SkipArtifactViewerComponent)(i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i0.ComponentFactoryResolver), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.Injector)); };
464
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SkipArtifactViewerComponent, selectors: [["skip-artifact-viewer"]], viewQuery: function SkipArtifactViewerComponent_Query(rf, ctx) { if (rf & 1) {
465
+ i0.ɵɵviewQuery(_c0, 5, ViewContainerRef);
466
+ } if (rf & 2) {
467
+ let _t;
468
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reportContainer = _t.first);
469
+ } }, inputs: { ArtifactID: "ArtifactID", ArtifactVersionID: "ArtifactVersionID", DataContext: "DataContext" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactInfoChanged: "ArtifactInfoChanged" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 1, consts: [["reportContainer", ""], [1, "skip-artifact-viewer-container"], [1, "skip-artifact-viewer-content"], [1, "loading-container"], [1, "error-container"], [1, "empty-state"], ["size", "large"], [1, "loading-text"], [1, "error-icon"], [1, "fa-solid", "fa-exclamation-circle"], [1, "error-message"], [1, "empty-icon"], [1, "fa-solid", "fa-file-alt"], [1, "empty-message"], [1, "report-container"], [1, "artifact-metadata"], [1, "metadata-item"], [1, "metadata-label"], [1, "metadata-value"]], template: function SkipArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
470
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2);
471
+ i0.ɵɵtemplate(2, SkipArtifactViewerComponent_Conditional_2_Template, 4, 0, "div", 3)(3, SkipArtifactViewerComponent_Conditional_3_Template, 5, 1, "div", 4)(4, SkipArtifactViewerComponent_Conditional_4_Template, 5, 0, "div", 5)(5, SkipArtifactViewerComponent_Conditional_5_Template, 3, 1);
472
+ i0.ɵɵelementEnd()();
473
+ } if (rf & 2) {
474
+ i0.ɵɵadvance(2);
475
+ i0.ɵɵconditional(ctx.isLoading ? 2 : ctx.error ? 3 : !ctx.artifact ? 4 : 5);
476
+ } }, dependencies: [i2.LoaderComponent, i3.DatePipe], styles: [".skip-artifact-viewer-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.skip-artifact-viewer-header[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background-color: #ffffff;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n z-index: 10;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.version-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #555;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid #e0e0e0;\n background-color: white;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:hover {\n border-color: #1976d2;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);\n}\n\n.report-container[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.artifact-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.artifact-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.version-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-info[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: #666;\n white-space: nowrap;\n}\n\n.version-info[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n}\n\n.artifact-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1a1a1a;\n display: flex;\n align-items: center;\n gap: 8px;\n line-height: 1.2;\n flex: 1;\n min-width: 0;\n}\n\n.artifact-type-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background-color: #e8f0fe;\n color: #1976d2;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n\n\n.version-dropdown-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background-color: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 16px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #1976d2;\n color: #1976d2;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n opacity: 0.7;\n}\n\n.version-dropdown-button.open[_ngcontent-%COMP%] {\n border-color: #1976d2;\n color: #1976d2;\n background-color: #f8f9fa;\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.dropdown-icon[_ngcontent-%COMP%] {\n font-size: 9px;\n transition: transform 0.2s ease;\n color: inherit;\n}\n\n.version-dropdown-button.open[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n min-width: 220px;\n background-color: white;\n border: 1px solid #e0e0e0;\n border-radius: 12px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n overflow: hidden;\n animation: _ngcontent-%COMP%_dropdownFadeIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_dropdownFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 10px 14px;\n background: none;\n border: none;\n cursor: pointer;\n text-align: left;\n transition: background-color 0.15s ease;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.version-option[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background-color: #e8f0fe;\n color: #1976d2;\n}\n\n.version-option.selected[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n color: #1976d2;\n opacity: 0.8;\n}\n\n.version-number[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n}\n\n.version-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n font-weight: 400;\n}\n\n.skip-artifact-viewer-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 0;\n background-color: #ffffff;\n}\n\n.content-container[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n background-color: #fff;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n overflow: auto;\n transition: box-shadow 0.2s ease;\n}\n\n.content-container[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);\n}\n\n.markdown-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.code-content[_ngcontent-%COMP%], .json-content[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.code-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%], .json-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n font-family: 'Monaco', 'Menlo', 'Consolas', monospace;\n font-size: 14px;\n line-height: 1.4;\n background-color: #f5f7f9;\n border-radius: 4px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n.text-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.html-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 16px;\n background-color: #f9f9f9;\n border-radius: 6px;\n}\n\n.artifact-description[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n color: #555;\n}\n\n.artifact-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n color: #333;\n}\n\n\n\n\n.artifact-metadata[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 12px 16px;\n background-color: #f5f5f5;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.metadata-item[_ngcontent-%COMP%] {\n display: flex;\n margin-bottom: 4px;\n}\n\n.metadata-label[_ngcontent-%COMP%] {\n width: 80px;\n font-weight: 500;\n color: #555;\n}\n\n.metadata-value[_ngcontent-%COMP%] {\n color: #333;\n}\n\n.loading-container[_ngcontent-%COMP%], .error-container[_ngcontent-%COMP%], .empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 200px;\n text-align: center;\n}\n\n.loading-text[_ngcontent-%COMP%] {\n margin-top: 16px;\n font-size: 14px;\n color: #666;\n}\n\n.error-icon[_ngcontent-%COMP%], .empty-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 16px;\n}\n\n.error-icon[_ngcontent-%COMP%] {\n color: #e33d3d;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n color: #aaa;\n}\n\n.error-message[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #e33d3d;\n max-width: 300px;\n}\n\n.empty-message[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #888;\n}"] });
479
477
  }
480
- SkipArtifactViewerComponent.ɵfac = function SkipArtifactViewerComponent_Factory(t) { return new (t || SkipArtifactViewerComponent)(i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i0.ComponentFactoryResolver), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.Injector)); };
481
- SkipArtifactViewerComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SkipArtifactViewerComponent, selectors: [["skip-artifact-viewer"]], viewQuery: function SkipArtifactViewerComponent_Query(rf, ctx) { if (rf & 1) {
482
- i0.ɵɵviewQuery(_c0, 5, ViewContainerRef);
483
- } if (rf & 2) {
484
- let _t;
485
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reportContainer = _t.first);
486
- } }, inputs: { ArtifactID: "ArtifactID", ArtifactVersionID: "ArtifactVersionID", DataContext: "DataContext" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactInfoChanged: "ArtifactInfoChanged" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 1, consts: [["reportContainer", ""], [1, "skip-artifact-viewer-container"], [1, "skip-artifact-viewer-content"], [1, "loading-container"], [1, "error-container"], [1, "empty-state"], ["size", "large"], [1, "loading-text"], [1, "error-icon"], [1, "fa-solid", "fa-exclamation-circle"], [1, "error-message"], [1, "empty-icon"], [1, "fa-solid", "fa-file-alt"], [1, "empty-message"], [1, "report-container"], [1, "artifact-metadata"], [1, "metadata-item"], [1, "metadata-label"], [1, "metadata-value"]], template: function SkipArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
487
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 2);
488
- i0.ɵɵtemplate(2, SkipArtifactViewerComponent_Conditional_2_Template, 4, 0, "div", 3)(3, SkipArtifactViewerComponent_Conditional_3_Template, 5, 1, "div", 4)(4, SkipArtifactViewerComponent_Conditional_4_Template, 5, 0, "div", 5)(5, SkipArtifactViewerComponent_Conditional_5_Template, 3, 1);
489
- i0.ɵɵelementEnd()();
490
- } if (rf & 2) {
491
- i0.ɵɵadvance(2);
492
- i0.ɵɵconditional(ctx.isLoading ? 2 : ctx.error ? 3 : !ctx.artifact ? 4 : 5);
493
- } }, dependencies: [i2.LoaderComponent, i3.DatePipe], styles: [".skip-artifact-viewer-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.skip-artifact-viewer-header[_ngcontent-%COMP%] {\n padding: 8px 16px;\n background-color: #ffffff;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n z-index: 10;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.version-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #555;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid #e0e0e0;\n background-color: white;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:hover {\n border-color: #1976d2;\n}\n\n.version-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);\n}\n\n.report-container[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.artifact-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.artifact-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.version-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-info[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: #666;\n white-space: nowrap;\n}\n\n.version-info[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #888;\n}\n\n.artifact-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1a1a1a;\n display: flex;\n align-items: center;\n gap: 8px;\n line-height: 1.2;\n flex: 1;\n min-width: 0;\n}\n\n.artifact-type-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background-color: #e8f0fe;\n color: #1976d2;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n\n\n.version-dropdown-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background-color: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 16px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #1976d2;\n color: #1976d2;\n}\n\n.version-dropdown-button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n opacity: 0.7;\n}\n\n.version-dropdown-button.open[_ngcontent-%COMP%] {\n border-color: #1976d2;\n color: #1976d2;\n background-color: #f8f9fa;\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.dropdown-icon[_ngcontent-%COMP%] {\n font-size: 9px;\n transition: transform 0.2s ease;\n color: inherit;\n}\n\n.version-dropdown-button.open[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n min-width: 220px;\n background-color: white;\n border: 1px solid #e0e0e0;\n border-radius: 12px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n overflow: hidden;\n animation: _ngcontent-%COMP%_dropdownFadeIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_dropdownFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 10px 14px;\n background: none;\n border: none;\n cursor: pointer;\n text-align: left;\n transition: background-color 0.15s ease;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.version-option[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background-color: #e8f0fe;\n color: #1976d2;\n}\n\n.version-option.selected[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n color: #1976d2;\n opacity: 0.8;\n}\n\n.version-number[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n}\n\n.version-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #888;\n font-weight: 400;\n}\n\n.skip-artifact-viewer-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 0;\n background-color: #ffffff;\n}\n\n.content-container[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n background-color: #fff;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n overflow: auto;\n transition: box-shadow 0.2s ease;\n}\n\n.content-container[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);\n}\n\n.markdown-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.code-content[_ngcontent-%COMP%], .json-content[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.code-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%], .json-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n font-family: 'Monaco', 'Menlo', 'Consolas', monospace;\n font-size: 14px;\n line-height: 1.4;\n background-color: #f5f7f9;\n border-radius: 4px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n.text-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.html-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 16px;\n background-color: #f9f9f9;\n border-radius: 6px;\n}\n\n.artifact-description[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n color: #555;\n}\n\n.artifact-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n color: #333;\n}\n\n\n\n\n.artifact-metadata[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 12px 16px;\n background-color: #f5f5f5;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.metadata-item[_ngcontent-%COMP%] {\n display: flex;\n margin-bottom: 4px;\n}\n\n.metadata-label[_ngcontent-%COMP%] {\n width: 80px;\n font-weight: 500;\n color: #555;\n}\n\n.metadata-value[_ngcontent-%COMP%] {\n color: #333;\n}\n\n.loading-container[_ngcontent-%COMP%], .error-container[_ngcontent-%COMP%], .empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 200px;\n text-align: center;\n}\n\n.loading-text[_ngcontent-%COMP%] {\n margin-top: 16px;\n font-size: 14px;\n color: #666;\n}\n\n.error-icon[_ngcontent-%COMP%], .empty-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 16px;\n}\n\n.error-icon[_ngcontent-%COMP%] {\n color: #e33d3d;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n color: #aaa;\n}\n\n.error-message[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #e33d3d;\n max-width: 300px;\n}\n\n.empty-message[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #888;\n}"] });
494
478
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SkipArtifactViewerComponent, [{
495
479
  type: Component,
496
480
  args: [{ selector: 'skip-artifact-viewer', template: "<div class=\"skip-artifact-viewer-container\">\n <div class=\"skip-artifact-viewer-content\">\n @if (isLoading) {\n <div class=\"loading-container\">\n <kendo-loader size=\"large\"></kendo-loader>\n <div class=\"loading-text\">Loading artifact...</div>\n </div>\n } @else if (error) {\n <div class=\"error-container\">\n <div class=\"error-icon\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n </div>\n <div class=\"error-message\">{{ error }}</div>\n </div>\n } @else if (!artifact) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-file-alt\"></i>\n </div>\n <div class=\"empty-message\">No artifact selected</div>\n </div>\n } @else {\n <div class=\"report-container\" #reportContainer>\n <!-- The dynamic report component will be inserted here -->\n </div>\n\n @if (artifactVersion) {\n <div class=\"artifact-metadata\">\n @if (artifactVersion.__mj_CreatedAt) {\n <div class=\"metadata-item\">\n <span class=\"metadata-label\">Created:</span>\n <span class=\"metadata-value\">{{ artifactVersion.__mj_CreatedAt | date:'medium' }}</span>\n </div>\n }\n </div>\n }\n }\n </div>\n</div>", styles: [".skip-artifact-viewer-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.skip-artifact-viewer-header {\n padding: 8px 16px;\n background-color: #ffffff;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n z-index: 10;\n}\n\n.version-selector {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.version-selector label {\n font-size: 13px;\n color: #555;\n}\n\n.version-selector select {\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid #e0e0e0;\n background-color: white;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.version-selector select:hover {\n border-color: #1976d2;\n}\n\n.version-selector select:focus {\n outline: none;\n border-color: #1976d2;\n box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);\n}\n\n.report-container {\n width: 100%;\n}\n\n.artifact-header-content {\n display: flex;\n flex-direction: column;\n}\n\n.artifact-title-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.version-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-info .version-date {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: #666;\n white-space: nowrap;\n}\n\n.version-info .version-date i {\n font-size: 12px;\n color: #888;\n}\n\n.artifact-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1a1a1a;\n display: flex;\n align-items: center;\n gap: 8px;\n line-height: 1.2;\n flex: 1;\n min-width: 0;\n}\n\n.artifact-type-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background-color: #e8f0fe;\n color: #1976d2;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Version Dropdown */\n.version-dropdown-wrapper {\n position: relative;\n}\n\n.version-dropdown-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background-color: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 16px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.version-dropdown-button:hover:not(:disabled) {\n border-color: #1976d2;\n color: #1976d2;\n}\n\n.version-dropdown-button:disabled {\n cursor: default;\n opacity: 0.7;\n}\n\n.version-dropdown-button.open {\n border-color: #1976d2;\n color: #1976d2;\n background-color: #f8f9fa;\n}\n\n.version-label {\n font-weight: 500;\n}\n\n.dropdown-icon {\n font-size: 9px;\n transition: transform 0.2s ease;\n color: inherit;\n}\n\n.version-dropdown-button.open .dropdown-icon {\n transform: rotate(180deg);\n}\n\n.version-dropdown-menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n min-width: 220px;\n background-color: white;\n border: 1px solid #e0e0e0;\n border-radius: 12px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n overflow: hidden;\n animation: dropdownFadeIn 0.2s ease-out;\n}\n\n@keyframes dropdownFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.version-option {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 10px 14px;\n background: none;\n border: none;\n cursor: pointer;\n text-align: left;\n transition: background-color 0.15s ease;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.version-option:last-child {\n border-bottom: none;\n}\n\n.version-option:hover {\n background-color: #f8f9fa;\n}\n\n.version-option.selected {\n background-color: #e8f0fe;\n color: #1976d2;\n}\n\n.version-option.selected .version-date {\n color: #1976d2;\n opacity: 0.8;\n}\n\n.version-number {\n font-size: 13px;\n font-weight: 500;\n}\n\n.version-date {\n font-size: 11px;\n color: #888;\n font-weight: 400;\n}\n\n.skip-artifact-viewer-content {\n flex: 1;\n overflow: auto;\n padding: 0;\n background-color: #ffffff;\n}\n\n.content-container {\n margin-bottom: 16px;\n background-color: #fff;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n overflow: auto;\n transition: box-shadow 0.2s ease;\n}\n\n.content-container:hover {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);\n}\n\n.markdown-content {\n padding: 16px;\n}\n\n.code-content, .json-content {\n padding: 0;\n}\n\n.code-content pre, .json-content pre {\n margin: 0;\n padding: 16px;\n font-family: 'Monaco', 'Menlo', 'Consolas', monospace;\n font-size: 14px;\n line-height: 1.4;\n background-color: #f5f7f9;\n border-radius: 4px;\n overflow: auto;\n white-space: pre-wrap;\n}\n\n.text-content pre {\n margin: 0;\n padding: 16px;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.html-content {\n padding: 16px;\n}\n\n.artifact-description {\n margin-top: 16px;\n padding: 16px;\n background-color: #f9f9f9;\n border-radius: 6px;\n}\n\n.artifact-description h4 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n color: #555;\n}\n\n.artifact-description p {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n color: #333;\n}\n\n/* Metadata Pills - Removed in favor of inline date display */\n\n.artifact-metadata {\n margin-top: 16px;\n padding: 12px 16px;\n background-color: #f5f5f5;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.metadata-item {\n display: flex;\n margin-bottom: 4px;\n}\n\n.metadata-label {\n width: 80px;\n font-weight: 500;\n color: #555;\n}\n\n.metadata-value {\n color: #333;\n}\n\n.loading-container, .error-container, .empty-state {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 200px;\n text-align: center;\n}\n\n.loading-text {\n margin-top: 16px;\n font-size: 14px;\n color: #666;\n}\n\n.error-icon, .empty-icon {\n font-size: 32px;\n margin-bottom: 16px;\n}\n\n.error-icon {\n color: #e33d3d;\n}\n\n.empty-icon {\n color: #aaa;\n}\n\n.error-message {\n font-size: 14px;\n color: #e33d3d;\n max-width: 300px;\n}\n\n.empty-message {\n font-size: 14px;\n color: #888;\n}"] }]