@memberjunction/ng-skip-chat 2.93.0 → 2.95.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.
@@ -227,59 +227,57 @@ function SkipChatComponent_span_16_Template(rf, ctx) { if (rf & 1) {
227
227
  const ctx_r2 = i0.ɵɵnextContext();
228
228
  i0.ɵɵstyleProp("left", ctx_r2.getScrollToBottomIconPosition(), "px");
229
229
  } }
230
- function SkipChatComponent_Conditional_17_Conditional_5_Template(rf, ctx) { if (rf & 1) {
230
+ function SkipChatComponent_Conditional_17_Conditional_6_Template(rf, ctx) { if (rf & 1) {
231
231
  const _r16 = i0.ɵɵgetCurrentView();
232
- i0.ɵɵelementStart(0, "button", 64)(1, "span", 68);
233
- i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_5_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showDataContextDialog()); });
232
+ i0.ɵɵelementStart(0, "button", 65)(1, "span", 69);
233
+ i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_6_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showDataContextDialog()); });
234
234
  i0.ɵɵelementEnd()();
235
235
  } }
236
- function SkipChatComponent_Conditional_17_Conditional_6_Template(rf, ctx) { if (rf & 1) {
236
+ function SkipChatComponent_Conditional_17_Conditional_7_Template(rf, ctx) { if (rf & 1) {
237
237
  const _r17 = i0.ɵɵgetCurrentView();
238
- i0.ɵɵelementStart(0, "button", 69);
239
- i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.stopProcessing()); });
240
- i0.ɵɵelement(1, "span", 70);
238
+ i0.ɵɵelementStart(0, "button", 70);
239
+ i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.stopProcessing()); });
240
+ i0.ɵɵelement(1, "span", 71);
241
241
  i0.ɵɵelementEnd();
242
242
  } }
243
- function SkipChatComponent_Conditional_17_Conditional_7_Template(rf, ctx) { if (rf & 1) {
243
+ function SkipChatComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
244
244
  const _r18 = i0.ɵɵgetCurrentView();
245
- i0.ɵɵelementStart(0, "button", 71);
246
- i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.sendSkipMessage()); });
247
- i0.ɵɵelement(1, "span", 72);
245
+ i0.ɵɵelementStart(0, "button", 72);
246
+ i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.sendSkipMessage()); });
247
+ i0.ɵɵelement(1, "span", 73);
248
248
  i0.ɵɵelementEnd();
249
249
  } if (rf & 2) {
250
250
  const ctx_r2 = i0.ɵɵnextContext(2);
251
251
  i0.ɵɵproperty("disabled", ctx_r2.IsTextAreaEmpty());
252
252
  } }
253
- function SkipChatComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
253
+ function SkipChatComponent_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
254
254
  const _r19 = i0.ɵɵgetCurrentView();
255
- i0.ɵɵelementStart(0, "button", 67)(1, "span", 73);
256
- i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_8_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showSharingDialog()); });
255
+ i0.ɵɵelementStart(0, "button", 68)(1, "span", 74);
256
+ i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_9_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showSharingDialog()); });
257
257
  i0.ɵɵelementEnd()();
258
258
  } }
259
259
  function SkipChatComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
260
260
  const _r15 = i0.ɵɵgetCurrentView();
261
- i0.ɵɵelementStart(0, "div", 20)(1, "div", 61)(2, "textarea", 62, 5);
262
- i0.ɵɵlistener("keyup.enter", function SkipChatComponent_Conditional_17_Template_textarea_keyup_enter_2_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEnter($event)); })("input", function SkipChatComponent_Conditional_17_Template_textarea_input_2_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onInputChange($event)); });
263
- i0.ɵɵelementEnd()();
264
- i0.ɵɵelementStart(4, "div", 63);
265
- i0.ɵɵtemplate(5, SkipChatComponent_Conditional_17_Conditional_5_Template, 2, 0, "button", 64)(6, SkipChatComponent_Conditional_17_Conditional_6_Template, 2, 0, "button", 65)(7, SkipChatComponent_Conditional_17_Conditional_7_Template, 2, 1, "button", 66)(8, SkipChatComponent_Conditional_17_Conditional_8_Template, 2, 0, "button", 67);
266
- i0.ɵɵelementEnd()();
261
+ i0.ɵɵelementStart(0, "div", 20)(1, "div", 61)(2, "div", 62)(3, "textarea", 63, 5);
262
+ i0.ɵɵlistener("keyup.enter", function SkipChatComponent_Conditional_17_Template_textarea_keyup_enter_3_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEnter($event)); })("input", function SkipChatComponent_Conditional_17_Template_textarea_input_3_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onInputChange($event)); });
263
+ i0.ɵɵelementEnd();
264
+ i0.ɵɵelementStart(5, "div", 64);
265
+ i0.ɵɵtemplate(6, SkipChatComponent_Conditional_17_Conditional_6_Template, 2, 0, "button", 65)(7, SkipChatComponent_Conditional_17_Conditional_7_Template, 2, 0, "button", 66)(8, SkipChatComponent_Conditional_17_Conditional_8_Template, 2, 1, "button", 67)(9, SkipChatComponent_Conditional_17_Conditional_9_Template, 2, 0, "button", 68);
266
+ i0.ɵɵelementEnd()()()();
267
267
  } if (rf & 2) {
268
268
  const ctx_r2 = i0.ɵɵnextContext();
269
- i0.ɵɵadvance(2);
269
+ i0.ɵɵadvance(3);
270
270
  i0.ɵɵproperty("disabled", ctx_r2.SelectedConversation && ctx_r2.IsSkipProcessing(ctx_r2.SelectedConversation))("placeholder", ctx_r2._AskSkipTextboxPlaceholder);
271
- i0.ɵɵadvance(2);
272
- i0.ɵɵstyleProp("margin-left", -35 * ctx_r2.NumVisibleButtons, "px");
273
- i0.ɵɵadvance();
274
- i0.ɵɵconditional(ctx_r2.ShowDataContextButton ? 5 : -1);
271
+ i0.ɵɵadvance(3);
272
+ i0.ɵɵconditional(ctx_r2.ShowDataContextButton ? 6 : -1);
275
273
  i0.ɵɵadvance();
276
- i0.ɵɵconditional(ctx_r2.SelectedConversation && ctx_r2.IsSkipProcessing(ctx_r2.SelectedConversation) ? 6 : 7);
274
+ i0.ɵɵconditional(ctx_r2.SelectedConversation && ctx_r2.IsSkipProcessing(ctx_r2.SelectedConversation) ? 7 : 8);
277
275
  i0.ɵɵadvance(2);
278
- i0.ɵɵconditional(ctx_r2.ShowSharingButton && ctx_r2.SelectedConversationCurrentUserPermissionLevel === "Owner" ? 8 : -1);
276
+ i0.ɵɵconditional(ctx_r2.ShowSharingButton && ctx_r2.SelectedConversationCurrentUserPermissionLevel === "Owner" ? 9 : -1);
279
277
  } }
280
278
  function SkipChatComponent_skip_artifact_viewer_19_Template(rf, ctx) { if (rf & 1) {
281
279
  const _r20 = i0.ɵɵgetCurrentView();
282
- i0.ɵɵelementStart(0, "skip-artifact-viewer", 74);
280
+ i0.ɵɵelementStart(0, "skip-artifact-viewer", 75);
283
281
  i0.ɵɵlistener("NavigateToMatchingReport", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_NavigateToMatchingReport_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.NavigateToMatchingReport.emit($event)); })("NewReportCreated", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_NewReportCreated_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.NewReportCreated.emit($event)); })("DrillDownEvent", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_DrillDownEvent_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.DrillDownEvent.emit($event)); })("ArtifactInfoChanged", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_ArtifactInfoChanged_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactInfoChanged($event)); });
284
282
  i0.ɵɵelementEnd();
285
283
  } if (rf & 2) {
@@ -288,7 +286,7 @@ function SkipChatComponent_skip_artifact_viewer_19_Template(rf, ctx) { if (rf &
288
286
  } }
289
287
  function SkipChatComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
290
288
  const _r21 = i0.ɵɵgetCurrentView();
291
- i0.ɵɵelementStart(0, "mj-data-context-dialog", 75);
289
+ i0.ɵɵelementStart(0, "mj-data-context-dialog", 76);
292
290
  i0.ɵɵlistener("dialogClosed", function SkipChatComponent_Conditional_20_Template_mj_data_context_dialog_dialogClosed_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDataContextDialog()); });
293
291
  i0.ɵɵelementEnd();
294
292
  } if (rf & 2) {
@@ -297,14 +295,14 @@ function SkipChatComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
297
295
  } }
298
296
  function SkipChatComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
299
297
  const _r22 = i0.ɵɵgetCurrentView();
300
- i0.ɵɵelementStart(0, "kendo-dialog", 76);
298
+ i0.ɵɵelementStart(0, "kendo-dialog", 77);
301
299
  i0.ɵɵlistener("close", function SkipChatComponent_Conditional_21_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("no")); });
302
- i0.ɵɵelement(1, "mj-resource-permissions", 77, 6);
303
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
300
+ i0.ɵɵelement(1, "mj-resource-permissions", 78, 6);
301
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 79);
304
302
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_21_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("yes")); });
305
303
  i0.ɵɵtext(5, " Save ");
306
304
  i0.ɵɵelementEnd();
307
- i0.ɵɵelementStart(6, "button", 79);
305
+ i0.ɵɵelementStart(6, "button", 80);
308
306
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_21_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("no")); });
309
307
  i0.ɵɵtext(7, " Cancel ");
310
308
  i0.ɵɵelementEnd()()();
@@ -316,16 +314,16 @@ function SkipChatComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
316
314
  } }
317
315
  function SkipChatComponent_kendo_dialog_22_Template(rf, ctx) { if (rf & 1) {
318
316
  const _r23 = i0.ɵɵgetCurrentView();
319
- i0.ɵɵelementStart(0, "kendo-dialog", 80);
317
+ i0.ɵɵelementStart(0, "kendo-dialog", 81);
320
318
  i0.ɵɵlistener("close", function SkipChatComponent_kendo_dialog_22_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("no")); });
321
- i0.ɵɵelementStart(1, "p", 81);
319
+ i0.ɵɵelementStart(1, "p", 82);
322
320
  i0.ɵɵtext(2);
323
321
  i0.ɵɵelementEnd();
324
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
322
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 79);
325
323
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_22_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("yes")); });
326
324
  i0.ɵɵtext(5, " Yes ");
327
325
  i0.ɵɵelementEnd();
328
- i0.ɵɵelementStart(6, "button", 79);
326
+ i0.ɵɵelementStart(6, "button", 80);
329
327
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_22_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("no")); });
330
328
  i0.ɵɵtext(7, " No ");
331
329
  i0.ɵɵelementEnd()()();
@@ -337,16 +335,16 @@ function SkipChatComponent_kendo_dialog_22_Template(rf, ctx) { if (rf & 1) {
337
335
  } }
338
336
  function SkipChatComponent_kendo_dialog_23_Template(rf, ctx) { if (rf & 1) {
339
337
  const _r24 = i0.ɵɵgetCurrentView();
340
- i0.ɵɵelementStart(0, "kendo-dialog", 80);
338
+ i0.ɵɵelementStart(0, "kendo-dialog", 81);
341
339
  i0.ɵɵlistener("close", function SkipChatComponent_kendo_dialog_23_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("no")); });
342
- i0.ɵɵelementStart(1, "p", 81);
340
+ i0.ɵɵelementStart(1, "p", 82);
343
341
  i0.ɵɵtext(2);
344
342
  i0.ɵɵelementEnd();
345
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
343
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 79);
346
344
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_23_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("yes")); });
347
345
  i0.ɵɵtext(5, " Yes ");
348
346
  i0.ɵɵelementEnd();
349
- i0.ɵɵelementStart(6, "button", 79);
347
+ i0.ɵɵelementStart(6, "button", 80);
350
348
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_23_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("no")); });
351
349
  i0.ɵɵtext(7, " No ");
352
350
  i0.ɵɵelementEnd()()();
@@ -482,6 +480,9 @@ export class SkipChatComponent extends BaseManagedComponent {
482
480
  _intersectionObserver;
483
481
  static __skipChatWindowsCurrentlyVisible = 0;
484
482
  sub;
483
+ // Per-conversation status message tracking
484
+ _statusMessagesByConversation = {};
485
+ _temporaryMessagesByConversation = {};
485
486
  /**
486
487
  * Currently selected artifact for viewing in the split panel
487
488
  */
@@ -568,6 +569,24 @@ export class SkipChatComponent extends BaseManagedComponent {
568
569
  this.HandlePushStatusUpdate(event.args);
569
570
  }
570
571
  });
572
+ // Set up the push status subscription
573
+ this.setupPushStatusSubscription();
574
+ }
575
+ catch (e) {
576
+ LogError(e);
577
+ }
578
+ }
579
+ LogVerbose(message) {
580
+ if (this.VerboseLogging) {
581
+ LogStatus(message);
582
+ }
583
+ }
584
+ /**
585
+ * Sets up or re-establishes the push status subscription
586
+ * This is extracted as a separate method so it can be called after page reloads
587
+ */
588
+ setupPushStatusSubscription() {
589
+ try {
571
590
  // Directly subscribe to the push status updates from the GraphQLDataProvider. If SkipChat is running in an environment where someone else is NOT
572
591
  // picking them up and broadcasting via MJ Events, we need this. If we get both, that's okay too as the update will not look any different and be
573
592
  // near instant from the user's perspective.
@@ -587,38 +606,78 @@ export class SkipChatComponent extends BaseManagedComponent {
587
606
  this.LogVerbose('Push status update received in Skip Chat: ' + JSON.stringify(status));
588
607
  if (status && status.message) {
589
608
  const statusObj = SafeJSONParse(status.message);
590
- if (statusObj && statusObj.type === 'AskSkip') {
591
- this.HandlePushStatusUpdate(statusObj);
609
+ if (statusObj) {
610
+ if (statusObj.type === 'AskSkip' || statusObj.type === 'ConversationStatusUpdate') {
611
+ this.HandlePushStatusUpdate(statusObj);
612
+ }
592
613
  }
593
614
  }
594
615
  });
595
616
  }
596
617
  catch (e) {
597
- LogError(e);
598
- }
599
- }
600
- LogVerbose(message) {
601
- if (this.VerboseLogging) {
602
- LogStatus(message);
618
+ LogError(`Error setting up push status subscription: ${e}`);
603
619
  }
604
620
  }
605
621
  HandlePushStatusUpdate(statusObj) {
606
622
  try {
607
623
  const obj = statusObj;
608
- if (obj.type?.trim().toLowerCase() === 'askskip' && obj.status?.trim().toLowerCase() === 'ok') {
624
+ // Handle conversation status updates from the backend
625
+ if (obj.type === 'ConversationStatusUpdate' && obj.conversationID) {
626
+ // Find and update the conversation in our cached list
627
+ const conversation = this.Conversations.find(c => c.ID === obj.conversationID);
628
+ if (conversation && (obj.status === 'Processing' || obj.status === 'Available')) {
629
+ conversation.Status = obj.status;
630
+ // Handle status changes
631
+ if (obj.status === 'Processing') {
632
+ // Conversation started processing
633
+ if (obj.conversationID === this.SelectedConversation?.ID) {
634
+ // If this is the currently selected conversation, ensure we show status message
635
+ const cachedStatus = this._statusMessagesByConversation[obj.conversationID];
636
+ if (cachedStatus) {
637
+ this.SetSkipStatusMessage(cachedStatus.message, 0, cachedStatus.startTime);
638
+ }
639
+ }
640
+ }
641
+ else if (obj.status === 'Available') {
642
+ // Conversation finished processing - clear its tracking data
643
+ delete this._conversationsInProgress[obj.conversationID];
644
+ this._processingStatus[obj.conversationID] = false; // Set to false instead of deleting
645
+ delete this._statusMessagesByConversation[obj.conversationID];
646
+ delete this._temporaryMessagesByConversation[obj.conversationID];
647
+ // Only clear the UI status message if this is the currently selected conversation
648
+ if (obj.conversationID === this.SelectedConversation?.ID) {
649
+ this.SetSkipStatusMessage('', 0);
650
+ }
651
+ }
652
+ }
653
+ }
654
+ else if (obj.type?.trim().toLowerCase() === 'askskip' && obj.status?.trim().toLowerCase() === 'ok') {
609
655
  if (obj.conversationID && this._conversationsInProgress[obj.conversationID]) {
656
+ // Cache the status message for this conversation regardless of whether it's selected
657
+ if (obj.message && obj.message.length > 0) {
658
+ // Keep the original start time if it exists, otherwise use now
659
+ const existingStatus = this._statusMessagesByConversation[obj.conversationID];
660
+ this._statusMessagesByConversation[obj.conversationID] = {
661
+ message: obj.message,
662
+ startTime: existingStatus?.startTime || new Date()
663
+ };
664
+ this.LogVerbose(`Skip Chat: Cached status message for conversation ${obj.conversationID}: ${obj.message}`);
665
+ }
666
+ // If this is the currently selected conversation, update the display
610
667
  if (obj.conversationID === this.SelectedConversation?.ID) {
611
668
  if (obj.message && obj.message.length > 0) {
612
669
  // we are in the midst of a possibly long running process for Skip, and we got a message here, so go ahead and display it in the temporary message
613
- this.LogVerbose(`Skip Chat: Received Push Status for conversation ${obj.conversationID} with message: ${obj.message}`);
614
- this.SetSkipStatusMessage(obj.message, 0);
670
+ this.LogVerbose(`Skip Chat: Displaying Push Status for conversation ${obj.conversationID} with message: ${obj.message}`);
671
+ // Use the cached start time to preserve the timer
672
+ const cachedStatus = this._statusMessagesByConversation[obj.conversationID];
673
+ this.SetSkipStatusMessage(obj.message, 0, cachedStatus?.startTime);
615
674
  }
616
675
  else {
617
676
  this.LogVerbose(`Skip Chat: Received Push Status but no message for conversation ${obj.conversationID}`);
618
677
  }
619
678
  }
620
679
  else {
621
- this.LogVerbose(`Skip Chat: Received Push Status for conversation ${obj.conversationID} but it's not the current conversation`);
680
+ this.LogVerbose(`Skip Chat: Received Push Status for conversation ${obj.conversationID} but it's not the current conversation - cached for later`);
622
681
  }
623
682
  }
624
683
  else {
@@ -666,10 +725,25 @@ export class SkipChatComponent extends BaseManagedComponent {
666
725
  this.InnerSetSkipStatusMessage(message, startTime);
667
726
  }
668
727
  InnerSetSkipStatusMessage(message, startTime) {
728
+ const conversationId = this.SelectedConversation?.ID;
669
729
  if (message && message.length > 0) {
730
+ // Store the status message for the current conversation
731
+ if (conversationId) {
732
+ // Preserve existing start time if we have one
733
+ const existingStatus = this._statusMessagesByConversation[conversationId];
734
+ this._statusMessagesByConversation[conversationId] = {
735
+ message,
736
+ startTime: startTime || existingStatus?.startTime || new Date()
737
+ };
738
+ }
670
739
  if (!this._temporaryMessage) {
671
- this._temporaryMessage = { ID: -1, Message: message, Role: 'ai', __mj_CreatedAt: startTime }; // create a new object
740
+ const actualStartTime = startTime || (conversationId ? this._statusMessagesByConversation[conversationId]?.startTime : undefined) || new Date();
741
+ this._temporaryMessage = { ID: -1, Message: message, Role: 'ai', __mj_CreatedAt: actualStartTime }; // create a new object
672
742
  this.AddMessageToCurrentConversation(this._temporaryMessage, true, false);
743
+ // Store the temporary message for this conversation
744
+ if (conversationId) {
745
+ this._temporaryMessagesByConversation[conversationId] = this._temporaryMessage;
746
+ }
673
747
  }
674
748
  else {
675
749
  this._temporaryMessage.Message = message;
@@ -688,6 +762,14 @@ export class SkipChatComponent extends BaseManagedComponent {
688
762
  // get rid of the temporary message
689
763
  this.RemoveMessageFromCurrentConversation(this._temporaryMessage);
690
764
  this._temporaryMessage = undefined;
765
+ // Clear the cached temporary message for this conversation
766
+ if (conversationId && this._temporaryMessagesByConversation[conversationId]) {
767
+ delete this._temporaryMessagesByConversation[conversationId];
768
+ }
769
+ }
770
+ // Clear the status message cache when clearing the message
771
+ if (conversationId && this._statusMessagesByConversation[conversationId]) {
772
+ delete this._statusMessagesByConversation[conversationId];
691
773
  }
692
774
  this._AskSkipTextboxPlaceholder = this.DefaultTextboxPlaceholder;
693
775
  }
@@ -721,21 +803,37 @@ export class SkipChatComponent extends BaseManagedComponent {
721
803
  checkForProcessingConversations() {
722
804
  try {
723
805
  if (this.Conversations && this.Conversations.length > 0) {
806
+ let hasProcessingConversations = false;
724
807
  // Check each conversation's status
725
808
  for (const convo of this.Conversations) {
726
809
  if (convo.Status === 'Processing') {
727
- // This conversation is currently being processed
810
+ hasProcessingConversations = true;
811
+ // Mark as in progress
812
+ this._conversationsInProgress[convo.ID] = true;
813
+ this._processingStatus[convo.ID] = true; // Also update processing status for UI
814
+ this._messageInProgress = true;
815
+ this.AllowSend = false;
728
816
  // If this is the currently selected conversation, update the UI
729
817
  if (this.SelectedConversation && this.SelectedConversation.ID === convo.ID) {
730
818
  this.setProcessingStatus(convo.ID, true);
731
819
  this.startRequestStatusPolling(convo.ID);
732
- this.SetSkipStatusMessage("Processing...", 0, convo.__mj_UpdatedAt);
820
+ // Don't overwrite if we're already handling this conversation
821
+ if (!this._temporaryMessage) {
822
+ // Restore the cached status message if available
823
+ const cachedStatus = this._statusMessagesByConversation[convo.ID];
824
+ const statusMessage = cachedStatus?.message || "Processing...";
825
+ const statusStartTime = cachedStatus?.startTime || convo.__mj_UpdatedAt;
826
+ this.SetSkipStatusMessage(statusMessage, 0, statusStartTime);
827
+ // Note: We don't request status here as SelectConversation will handle it
828
+ // This avoids duplicate requests to the backend
829
+ }
733
830
  }
734
- this._conversationsInProgress[convo.ID] = true;
735
- this._messageInProgress = true;
736
- this.AllowSend = false;
737
831
  }
738
832
  }
833
+ // If we have processing conversations and no push subscription, set it up
834
+ if (hasProcessingConversations && !this._providerPushStatusSub) {
835
+ this.setupPushStatusSubscription();
836
+ }
739
837
  }
740
838
  }
741
839
  catch (error) {
@@ -766,6 +864,55 @@ export class SkipChatComponent extends BaseManagedComponent {
766
864
  delete this._requestStatusPollingIntervals[conversationId];
767
865
  }
768
866
  }
867
+ /**
868
+ * Requests the current status message from the backend for a processing conversation
869
+ * This is needed after page reloads when we lose the cached status messages
870
+ */
871
+ async requestCurrentConversationStatus(conversationId) {
872
+ try {
873
+ // Make sure we're subscribed to push updates if we aren't already
874
+ // This ensures we'll receive any ongoing status updates
875
+ if (!this._providerPushStatusSub) {
876
+ this.setupPushStatusSubscription();
877
+ }
878
+ // Mark this conversation as in progress so we handle future updates properly
879
+ this._conversationsInProgress[conversationId] = true;
880
+ // Call the backend to re-attach this session to the processing conversation
881
+ const gql = `query ReattachToProcessingConversation($conversationId: String!) {
882
+ ReattachToProcessingConversation(ConversationId: $conversationId) {
883
+ lastStatusMessage
884
+ startTime
885
+ }
886
+ }`;
887
+ const gqlProvider = this.ProviderToUse;
888
+ const result = await gqlProvider.ExecuteGQL(gql, {
889
+ conversationId: conversationId
890
+ });
891
+ if (result && result.ReattachToProcessingConversation) {
892
+ const response = result.ReattachToProcessingConversation;
893
+ const lastStatusMessage = response.lastStatusMessage;
894
+ const startTime = response.startTime ? new Date(response.startTime) : null;
895
+ // Update the cached status message with what we got from the backend
896
+ if (lastStatusMessage && lastStatusMessage !== 'Processing your request...') {
897
+ this._statusMessagesByConversation[conversationId] = {
898
+ message: lastStatusMessage,
899
+ startTime: startTime || this._statusMessagesByConversation[conversationId]?.startTime || new Date()
900
+ };
901
+ // Update the display if this is the current conversation
902
+ if (conversationId === this.SelectedConversation?.ID) {
903
+ const cachedStatus = this._statusMessagesByConversation[conversationId];
904
+ this.SetSkipStatusMessage(lastStatusMessage, 0, cachedStatus?.startTime);
905
+ }
906
+ }
907
+ }
908
+ else {
909
+ // Could not re-attach - conversation may no longer be processing
910
+ }
911
+ }
912
+ catch (error) {
913
+ LogError(`Error requesting conversation status: ${error}`);
914
+ }
915
+ }
769
916
  /**
770
917
  * Loads conversation details for a specific conversation and role
771
918
  * @param conversationId The ID of the conversation
@@ -816,13 +963,13 @@ export class SkipChatComponent extends BaseManagedComponent {
816
963
  this.cdRef.detach();
817
964
  if (convoID !== this.SelectedConversation?.ID) {
818
965
  // this scenario arises when we have a selected convo change after we submitted our request to skip
819
- // so we do nothing here other than update the status.
820
- this.setProcessingStatus(convoID, false);
966
+ // so we just mark it for reload, don't update processing status
821
967
  //the next time the user selects this convo, we will fetch messages
822
968
  //from the server rather than using the ones in cache
823
969
  this._conversationsToReload[convoID] = true;
824
970
  }
825
971
  else {
972
+ // Only update processing status for the selected conversation
826
973
  this.setProcessingStatus(convoID, false);
827
974
  if (this.SelectedConversation.Name === 'New Chat' || this.SelectedConversation.Name?.trim().length === 0 || this.SelectedConversation.Name !== conversation.Name) {
828
975
  // we are on the first message so skip renamed the convo, use that
@@ -853,15 +1000,20 @@ export class SkipChatComponent extends BaseManagedComponent {
853
1000
  }
854
1001
  this.AllowSend = true;
855
1002
  this._conversationsInProgress[convoID] = false;
1003
+ // Set processing status to false for this conversation
1004
+ this._processingStatus[convoID] = false;
856
1005
  this._messageInProgress = false;
857
1006
  // now tell Angular to resume its change detection
858
1007
  this.cdRef.reattach();
859
1008
  this.cdRef.detectChanges();
860
1009
  // invoke manual resize with a delay to ensure that the scroll to bottom has taken place
861
1010
  //InvokeManualResize();
862
- this.SetSkipStatusMessage('', 500); // slight delay to ensure that the message is removed after the UI has updated with the new response message
863
- // now set focus on the input box
864
- this.askSkipInput.nativeElement.focus();
1011
+ // Only clear the status message if this is the currently selected conversation
1012
+ if (convoID === this.SelectedConversation?.ID) {
1013
+ this.SetSkipStatusMessage('', 500); // slight delay to ensure that the message is removed after the UI has updated with the new response message
1014
+ // now set focus on the input box
1015
+ this.askSkipInput.nativeElement.focus();
1016
+ }
865
1017
  }
866
1018
  }
867
1019
  catch (error) {
@@ -869,6 +1021,8 @@ export class SkipChatComponent extends BaseManagedComponent {
869
1021
  }
870
1022
  }
871
1023
  ngOnDestroy() {
1024
+ // Clean up all message subscriptions
1025
+ this.ClearMessages();
872
1026
  // Unsubscribe to prevent memory leaks
873
1027
  if (this.paramsSubscription) {
874
1028
  this.paramsSubscription.unsubscribe();
@@ -1385,19 +1539,42 @@ export class SkipChatComponent extends BaseManagedComponent {
1385
1539
  }, 300, { purpose: 'scroll-after-messages-render' }); // Give DOM time to render all messages
1386
1540
  }
1387
1541
  this.setProcessingStatus(conversation.ID, oldStatus); // set back to old status as it might have been processing
1388
- // Check if this conversation is in 'Processing' status and restore the streaming state
1389
- if (conversation.Status === 'Processing') {
1542
+ // Check if this conversation is actually processing (regardless of DB status)
1543
+ if (conversation.Status === 'Processing' || this._conversationsInProgress[conversation.ID]) {
1390
1544
  // This conversation is currently being processed
1391
1545
  this.setProcessingStatus(conversation.ID, true);
1392
1546
  this._conversationsInProgress[conversation.ID] = true;
1393
1547
  this._messageInProgress = true;
1394
1548
  this.AllowSend = false;
1395
- // Create the temporary status message after a brief delay to ensure DOM is ready
1396
- this.setTimeout(() => {
1549
+ // Check if we have a cached status message (from before reload)
1550
+ const cachedStatus = this._statusMessagesByConversation[conversation.ID];
1551
+ if (!cachedStatus && conversation.Status === 'Processing') {
1552
+ // Show a default message immediately while we fetch the real status
1397
1553
  this.SetSkipStatusMessage("Processing...", 0, conversation.__mj_UpdatedAt);
1398
- // Start polling after the temporary message is created
1554
+ // After a page reload or when switching to a conversation without cached status,
1555
+ // request the current status from the backend and update when ready
1556
+ this.requestCurrentConversationStatus(conversation.ID).then(() => {
1557
+ // After getting the status from backend, update the message with the correct start time
1558
+ const updatedStatus = this._statusMessagesByConversation[conversation.ID];
1559
+ if (updatedStatus) {
1560
+ this.SetSkipStatusMessage(updatedStatus.message, 0, updatedStatus.startTime);
1561
+ }
1562
+ // Start polling after getting the real status
1563
+ this.startRequestStatusPolling(conversation.ID);
1564
+ });
1565
+ }
1566
+ else {
1567
+ // We have cached status, use it directly and immediately
1568
+ const statusMessage = cachedStatus?.message || "Processing...";
1569
+ const statusStartTime = cachedStatus?.startTime || conversation.__mj_UpdatedAt;
1570
+ // Set the status message immediately since we have cached data
1571
+ this.SetSkipStatusMessage(statusMessage, 0, statusStartTime);
1572
+ // Start polling immediately
1399
1573
  this.startRequestStatusPolling(conversation.ID);
1400
- }, 100);
1574
+ }
1575
+ }
1576
+ else {
1577
+ // Conversation is not processing
1401
1578
  }
1402
1579
  InvokeManualResize(500);
1403
1580
  // ensure the list box has the conversation in view
@@ -1494,7 +1671,16 @@ export class SkipChatComponent extends BaseManagedComponent {
1494
1671
  this.AddMessageToCurrentConversation(convoDetail, true, true);
1495
1672
  this.askSkipInput.nativeElement.value = '';
1496
1673
  this.resizeTextInput();
1497
- this.SetSkipStatusMessage(this.pickSkipStartMessage(), 850);
1674
+ // Store the start time when first creating the status message
1675
+ const startTime = new Date();
1676
+ const statusMessage = this.pickSkipStartMessage();
1677
+ if (convoID) {
1678
+ this._statusMessagesByConversation[convoID] = {
1679
+ message: statusMessage,
1680
+ startTime: startTime
1681
+ };
1682
+ }
1683
+ this.SetSkipStatusMessage(statusMessage, 850, startTime);
1498
1684
  // Ensure scroll to bottom after adding user message AND progress message
1499
1685
  this.setTimeout(() => {
1500
1686
  this.scrollToBottom();
@@ -1506,13 +1692,13 @@ export class SkipChatComponent extends BaseManagedComponent {
1506
1692
  if (skipResult?.Success) {
1507
1693
  if (convoID !== this.SelectedConversation?.ID) {
1508
1694
  // this scenario arises when we have a selected convo change after we submitted our request to skip
1509
- // so we do nothing here other than update the status.
1510
- this.setProcessingStatus(convoID, false);
1695
+ // so we just mark it for reload, don't update processing status
1511
1696
  //the next time the user selects this convo, we will fetch messages
1512
1697
  //from the server rather than using the ones in cache
1513
1698
  this._conversationsToReload[convoID] = true;
1514
1699
  }
1515
1700
  else {
1701
+ // Only update processing status for the selected conversation
1516
1702
  this.setProcessingStatus(convoID, false);
1517
1703
  const innerResult = JSON.parse(skipResult.Result);
1518
1704
  if (!this.SelectedConversation) {
@@ -1552,20 +1738,26 @@ export class SkipChatComponent extends BaseManagedComponent {
1552
1738
  // NOTE: we don't create a user notification at this point, that is done on the server and via GraphQL subscriptions it tells us and we update the UI automatically...
1553
1739
  }
1554
1740
  }
1555
- if (this.SelectedConversation) {
1741
+ // Only update processing status if this is the currently selected conversation
1742
+ if (this.SelectedConversation && this.SelectedConversation.ID === convoID) {
1556
1743
  this.setProcessingStatus(this.SelectedConversation.ID, false);
1557
1744
  }
1558
1745
  this.AllowSend = true;
1559
1746
  this._conversationsInProgress[convoID] = false;
1747
+ // Set processing status to false for this conversation
1748
+ this._processingStatus[convoID] = false;
1560
1749
  this._messageInProgress = false;
1561
1750
  // now tell Angular to resume its change detection
1562
1751
  this.cdRef.reattach();
1563
1752
  this.cdRef.detectChanges();
1564
1753
  // invoke manual resize with a delay to ensure that the scroll to bottom has taken place
1565
1754
  //InvokeManualResize();
1566
- this.SetSkipStatusMessage('', 500); // slight delay to ensure that the message is removed after the UI has updated with the new response message
1567
- // now set focus on the input box
1568
- this.askSkipInput.nativeElement.focus();
1755
+ // Only clear the status message if this is the currently selected conversation
1756
+ if (convoID === this.SelectedConversation?.ID) {
1757
+ this.SetSkipStatusMessage('', 500); // slight delay to ensure that the message is removed after the UI has updated with the new response message
1758
+ // now set focus on the input box
1759
+ this.askSkipInput.nativeElement.focus();
1760
+ }
1569
1761
  }
1570
1762
  }
1571
1763
  async sendSkipMessage() {
@@ -1576,8 +1768,22 @@ export class SkipChatComponent extends BaseManagedComponent {
1576
1768
  await this.sendPrompt(input);
1577
1769
  }
1578
1770
  ClearMessages() {
1771
+ // Clean up all message subscriptions before clearing
1772
+ if (this.Messages && this.Messages.length > 0) {
1773
+ this.Messages.forEach((message) => {
1774
+ const subscriptions = message._subscriptions;
1775
+ if (subscriptions && Array.isArray(subscriptions)) {
1776
+ subscriptions.forEach((sub) => {
1777
+ if (sub && sub.unsubscribe) {
1778
+ sub.unsubscribe();
1779
+ }
1780
+ });
1781
+ message._subscriptions = [];
1782
+ }
1783
+ });
1784
+ }
1579
1785
  this.Messages = []; // clear out the messages
1580
- // Clear the temporary message reference
1786
+ // Clear the temporary message reference (but keep the cached ones)
1581
1787
  this._temporaryMessage = undefined;
1582
1788
  // Get the first mjContainer in the DOM which is the one we're injecting into
1583
1789
  const containerElements = document.querySelectorAll('div[mjContainer]');
@@ -1634,6 +1840,16 @@ export class SkipChatComponent extends BaseManagedComponent {
1634
1840
  if (ref) {
1635
1841
  // Temporarily stop change detection for performance
1636
1842
  this.cdRef.detach();
1843
+ // Clean up subscriptions before destroying the component
1844
+ const subscriptions = messageDetail._subscriptions;
1845
+ if (subscriptions && Array.isArray(subscriptions)) {
1846
+ subscriptions.forEach((sub) => {
1847
+ if (sub && sub.unsubscribe) {
1848
+ sub.unsubscribe();
1849
+ }
1850
+ });
1851
+ messageDetail._subscriptions = [];
1852
+ }
1637
1853
  const index = this.askSkip.viewContainerRef.indexOf(ref.hostView);
1638
1854
  if (index !== -1) {
1639
1855
  this.askSkip.viewContainerRef.remove(index);
@@ -1669,25 +1885,27 @@ export class SkipChatComponent extends BaseManagedComponent {
1669
1885
  const componentRef = this.askSkip.viewContainerRef.createComponent(SkipSingleMessageComponent);
1670
1886
  // Pass the message details to the component instance
1671
1887
  const obj = componentRef.instance;
1888
+ // Store subscriptions so we can clean them up later
1889
+ const subscriptions = [];
1672
1890
  // bubble up events from the single message component to the parent component
1673
- obj.NavigateToMatchingReport.subscribe((reportId) => {
1891
+ subscriptions.push(obj.NavigateToMatchingReport.subscribe((reportId) => {
1674
1892
  this.NavigateToMatchingReport.emit(reportId);
1675
- });
1676
- obj.NewReportCreated.subscribe((reportId) => {
1893
+ }));
1894
+ subscriptions.push(obj.NewReportCreated.subscribe((reportId) => {
1677
1895
  this.NewReportCreated.emit(reportId);
1678
- });
1679
- obj.DeleteMessageRequested.subscribe((message) => {
1896
+ }));
1897
+ subscriptions.push(obj.DeleteMessageRequested.subscribe((message) => {
1680
1898
  this.HandleMessageDeleteRequest(message);
1681
- });
1682
- obj.EditMessageRequested.subscribe((message) => {
1899
+ }));
1900
+ subscriptions.push(obj.EditMessageRequested.subscribe((message) => {
1683
1901
  this.HandleMessageEditRequest(message);
1684
- });
1685
- obj.DrillDownEvent.subscribe((drillDownInfo) => {
1902
+ }));
1903
+ subscriptions.push(obj.DrillDownEvent.subscribe((drillDownInfo) => {
1686
1904
  this.DrillDownEvent.emit(drillDownInfo);
1687
- });
1688
- obj.ArtifactSelected.subscribe((artifact) => {
1905
+ }));
1906
+ subscriptions.push(obj.ArtifactSelected.subscribe((artifact) => {
1689
1907
  this.onArtifactSelected(artifact);
1690
- });
1908
+ }));
1691
1909
  obj.Provider = this.ProviderToUse;
1692
1910
  obj.SkipMarkOnlyLogoURL = this.SkipMarkOnlyLogoURL;
1693
1911
  obj.UserImage = this.UserImage;
@@ -1702,15 +1920,17 @@ export class SkipChatComponent extends BaseManagedComponent {
1702
1920
  // bind the processing status to the component
1703
1921
  obj.ConversationProcessing = this.IsSkipProcessing(this.SelectedConversation);
1704
1922
  // Whenever the suggested question is clicked on by the user in the single message component, we want to bubble that up here and send the prompt
1705
- obj.SuggestedQuestionSelected.subscribe((question) => {
1923
+ subscriptions.push(obj.SuggestedQuestionSelected.subscribe((question) => {
1706
1924
  this.sendPrompt(question);
1707
- });
1925
+ }));
1708
1926
  // Whenever the suggested answer is clicked on by the user in the single message component, we want to bubble that up here and send the prompt
1709
- obj.SuggestedAnswerSelected.subscribe((answer) => {
1927
+ subscriptions.push(obj.SuggestedAnswerSelected.subscribe((answer) => {
1710
1928
  this.sendPrompt(answer);
1711
- });
1929
+ }));
1712
1930
  // now, stash a link to our newly created componentRef inside the messageDetail so we know which componentRef to remove when we delete the message
1713
1931
  messageDetail._componentRef = componentRef;
1932
+ // Store subscriptions so we can clean them up when the message is removed
1933
+ messageDetail._subscriptions = subscriptions;
1714
1934
  // Resume change detection
1715
1935
  if (stopChangeDetection)
1716
1936
  this.cdRef.reattach();
@@ -1889,6 +2109,10 @@ export class SkipChatComponent extends BaseManagedComponent {
1889
2109
  else if (this._processingStatus[Conversation.ID]) {
1890
2110
  return this._processingStatus[Conversation.ID];
1891
2111
  }
2112
+ else if (Conversation.Status === 'Processing') {
2113
+ // Check the database status field as well (important for page refreshes)
2114
+ return true;
2115
+ }
1892
2116
  else {
1893
2117
  return false;
1894
2118
  }
@@ -2290,6 +2514,7 @@ export class SkipChatComponent extends BaseManagedComponent {
2290
2514
  // Clear processing state
2291
2515
  this.setProcessingStatus(this.SelectedConversation.ID, false);
2292
2516
  this._conversationsInProgress[this.SelectedConversation.ID] = false;
2517
+ this._processingStatus[this.SelectedConversation.ID] = false;
2293
2518
  this._messageInProgress = false;
2294
2519
  this.AllowSend = true;
2295
2520
  // Stop polling
@@ -2422,7 +2647,7 @@ export class SkipChatComponent extends BaseManagedComponent {
2422
2647
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.topLevelDiv = _t.first);
2423
2648
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.resourcePermissionsRef = _t.first);
2424
2649
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.splitPanel = _t.first);
2425
- } }, inputs: { AllowSend: "AllowSend", Messages: "Messages", Conversations: "Conversations", SelectedConversation: "SelectedConversation", ConversationEditMode: "ConversationEditMode", ShowConversationList: "ShowConversationList", AllowNewConversations: "AllowNewConversations", Title: "Title", DataContextID: "DataContextID", LinkedEntity: "LinkedEntity", LinkedEntityCompositeKey: "LinkedEntityCompositeKey", ShowDataContextButton: "ShowDataContextButton", IncludeLinkedConversationsInList: "IncludeLinkedConversationsInList", SkipLogoURL: "SkipLogoURL", SkipMarkOnlyLogoURL: "SkipMarkOnlyLogoURL", UserImage: "UserImage", VerboseLogging: "VerboseLogging", UpdateAppRoute: "UpdateAppRoute", ShowSkipLogoInConversationList: "ShowSkipLogoInConversationList", ShowSharingButton: "ShowSharingButton", SharingExcludeRoleNames: "SharingExcludeRoleNames", SharingExcludeEmails: "SharingExcludeEmails", EnableArtifactSplitView: "EnableArtifactSplitView", DefaultSplitRatio: "DefaultSplitRatio", DefaultTextboxPlaceholder: "DefaultTextboxPlaceholder", ProcessingTextBoxPlaceholder: "ProcessingTextBoxPlaceholder", WelcomeQuestions: "WelcomeQuestions", AutoLoad: "AutoLoad" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", ConversationSelected: "ConversationSelected", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactSelected: "ArtifactSelected", ArtifactViewed: "ArtifactViewed" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 24, vars: 18, consts: [["topLevelDiv", ""], ["splitPanel", ""], ["AskSkipPanel", ""], ["scrollContainer", ""], ["conversationList", ""], ["AskSkipInput", ""], ["resourcePermissions", ""], ["kendoDialogContainer", "", 1, "chat-container"], [1, "layout"], [1, "left-panel"], [1, "fa-solid", "fa-table-columns", "toggle-icon"], [1, "right-panel"], ["mjFillContainer", "", 3, "SplitRatioChanged", "VersionSelected", "Mode", "SplitRatio", "RightPanelHeaderContent", "VersionList", "SelectedVersionId", "fillWidth", "fillHeight"], ["left-panel", "", 1, "conversation-wrapper"], [2, "width", "0", "height", "0", "overflow", "hidden", "position", "absolute"], [1, "messages", 3, "scroll"], ["class", "welcome-wrapper", 4, "ngIf"], [1, "loading-convo-messages-wrapper"], ["mjContainer", "", "mjSkipResize", "true", 1, "messages-container"], ["class", "scroll-to-bottom-icon", 3, "left", "click", 4, "ngIf"], [1, "input-area"], ["right-panel", ""], [3, "ArtifactID", "ArtifactVersionID", "DataContext", "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", 4, "ngIf"], [3, "dataContextId", "Provider"], ["title", "Share Conversation", 3, "width", "height"], ["title", "Please confirm", 3, "minWidth", "width", "close", 4, "ngIf"], [1, "conversation-history"], [1, "new-chat-area"], [1, "fa-solid", "fa-table-columns", "toggle-icon", 3, "click"], [1, "avatar", 3, "src"], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon"], [1, "conversation-list", 3, "data", "itemClass"], ["kendoListViewItemTemplate", ""], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon", 3, "click"], [1, "conversation-item", 3, "click", "ngClass", "title"], ["class", "fa-regular fa-clock", 4, "ngIf"], [1, "text-container"], [4, "ngIf"], ["maxlength", "100", 3, "ngModel", "ngModelChange", 4, "ngIf"], ["class", "edit-conversation-panel", 4, "ngIf"], [1, "fa-regular", "fa-clock"], ["maxlength", "100", 3, "ngModelChange", "ngModel"], [1, "edit-conversation-panel"], ["class", "fa-solid fa-pen-to-square", 3, "click", 4, "ngIf"], ["class", "fa-regular fa-trash-can", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-check", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-xmark", 3, "click", 4, "ngIf"], [1, "fa-solid", "fa-pen-to-square", 3, "click"], [1, "fa-regular", "fa-trash-can", 3, "click"], [1, "fa-solid", "fa-check", 3, "click"], [1, "fa-solid", "fa-xmark", 3, "click"], [1, "welcome-wrapper"], [1, "welcome-message"], [3, "src"], [1, "welcome-header-text"], [1, "welcome-suggested-questions"], [1, "welcome-suggested-questions-col"], [1, "welcome-question", 3, "click"], [1, "welcome-question-header"], [1, "scroll-to-bottom-icon", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "text-area-wrapper"], ["type", "text", 3, "keyup.enter", "input", "disabled", "placeholder"], [1, "button-area"], ["kendoButton", ""], ["kendoButton", "", 1, "stop-button"], ["kendoButton", "", 3, "disabled"], ["kendoButton", "", 1, "share-button"], [1, "fa-solid", "fa-gear", 3, "click"], ["kendoButton", "", 1, "stop-button", 3, "click"], [1, "fas", "fa-solid", "fa-stop"], ["kendoButton", "", 3, "click", "disabled"], [1, "fas", "fa-solid", "fa-arrow-up"], [1, "fa-solid", "fa-share", 3, "click"], [3, "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", "ArtifactID", "ArtifactVersionID", "DataContext"], [3, "dialogClosed", "dataContextId", "Provider"], ["title", "Share Conversation", 3, "close", "width", "height"], [3, "Provider", "ResourceTypeID", "ResourceRecordID", "ExcludedRoleNames", "ExcludedUserEmails"], ["kendoButton", "", "themeColor", "primary", 3, "click"], ["kendoButton", "", 3, "click"], ["title", "Please confirm", 3, "close", "minWidth", "width"], [2, "margin", "30px", "text-align", "center"]], template: function SkipChatComponent_Template(rf, ctx) { if (rf & 1) {
2650
+ } }, inputs: { AllowSend: "AllowSend", Messages: "Messages", Conversations: "Conversations", SelectedConversation: "SelectedConversation", ConversationEditMode: "ConversationEditMode", ShowConversationList: "ShowConversationList", AllowNewConversations: "AllowNewConversations", Title: "Title", DataContextID: "DataContextID", LinkedEntity: "LinkedEntity", LinkedEntityCompositeKey: "LinkedEntityCompositeKey", ShowDataContextButton: "ShowDataContextButton", IncludeLinkedConversationsInList: "IncludeLinkedConversationsInList", SkipLogoURL: "SkipLogoURL", SkipMarkOnlyLogoURL: "SkipMarkOnlyLogoURL", UserImage: "UserImage", VerboseLogging: "VerboseLogging", UpdateAppRoute: "UpdateAppRoute", ShowSkipLogoInConversationList: "ShowSkipLogoInConversationList", ShowSharingButton: "ShowSharingButton", SharingExcludeRoleNames: "SharingExcludeRoleNames", SharingExcludeEmails: "SharingExcludeEmails", EnableArtifactSplitView: "EnableArtifactSplitView", DefaultSplitRatio: "DefaultSplitRatio", DefaultTextboxPlaceholder: "DefaultTextboxPlaceholder", ProcessingTextBoxPlaceholder: "ProcessingTextBoxPlaceholder", WelcomeQuestions: "WelcomeQuestions", AutoLoad: "AutoLoad" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", ConversationSelected: "ConversationSelected", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactSelected: "ArtifactSelected", ArtifactViewed: "ArtifactViewed" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 24, vars: 18, consts: [["topLevelDiv", ""], ["splitPanel", ""], ["AskSkipPanel", ""], ["scrollContainer", ""], ["conversationList", ""], ["AskSkipInput", ""], ["resourcePermissions", ""], ["kendoDialogContainer", "", 1, "chat-container"], [1, "layout"], [1, "left-panel"], [1, "fa-solid", "fa-table-columns", "toggle-icon"], [1, "right-panel"], ["mjFillContainer", "", 3, "SplitRatioChanged", "VersionSelected", "Mode", "SplitRatio", "RightPanelHeaderContent", "VersionList", "SelectedVersionId", "fillWidth", "fillHeight"], ["left-panel", "", 1, "conversation-wrapper"], [2, "width", "0", "height", "0", "overflow", "hidden", "position", "absolute"], [1, "messages", 3, "scroll"], ["class", "welcome-wrapper", 4, "ngIf"], [1, "loading-convo-messages-wrapper"], ["mjContainer", "", "mjSkipResize", "true", 1, "messages-container"], ["class", "scroll-to-bottom-icon", 3, "left", "click", 4, "ngIf"], [1, "input-area"], ["right-panel", ""], [3, "ArtifactID", "ArtifactVersionID", "DataContext", "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", 4, "ngIf"], [3, "dataContextId", "Provider"], ["title", "Share Conversation", 3, "width", "height"], ["title", "Please confirm", 3, "minWidth", "width", "close", 4, "ngIf"], [1, "conversation-history"], [1, "new-chat-area"], [1, "fa-solid", "fa-table-columns", "toggle-icon", 3, "click"], [1, "avatar", 3, "src"], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon"], [1, "conversation-list", 3, "data", "itemClass"], ["kendoListViewItemTemplate", ""], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon", 3, "click"], [1, "conversation-item", 3, "click", "ngClass", "title"], ["class", "fa-regular fa-clock", 4, "ngIf"], [1, "text-container"], [4, "ngIf"], ["maxlength", "100", 3, "ngModel", "ngModelChange", 4, "ngIf"], ["class", "edit-conversation-panel", 4, "ngIf"], [1, "fa-regular", "fa-clock"], ["maxlength", "100", 3, "ngModelChange", "ngModel"], [1, "edit-conversation-panel"], ["class", "fa-solid fa-pen-to-square", 3, "click", 4, "ngIf"], ["class", "fa-regular fa-trash-can", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-check", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-xmark", 3, "click", 4, "ngIf"], [1, "fa-solid", "fa-pen-to-square", 3, "click"], [1, "fa-regular", "fa-trash-can", 3, "click"], [1, "fa-solid", "fa-check", 3, "click"], [1, "fa-solid", "fa-xmark", 3, "click"], [1, "welcome-wrapper"], [1, "welcome-message"], [3, "src"], [1, "welcome-header-text"], [1, "welcome-suggested-questions"], [1, "welcome-suggested-questions-col"], [1, "welcome-question", 3, "click"], [1, "welcome-question-header"], [1, "scroll-to-bottom-icon", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "input-container"], [1, "text-area-wrapper"], ["type", "text", 3, "keyup.enter", "input", "disabled", "placeholder"], [1, "button-area"], ["kendoButton", ""], ["kendoButton", "", 1, "stop-button"], ["kendoButton", "", 3, "disabled"], ["kendoButton", "", 1, "share-button"], [1, "fa-solid", "fa-gear", 3, "click"], ["kendoButton", "", 1, "stop-button", 3, "click"], [1, "fas", "fa-solid", "fa-stop"], ["kendoButton", "", 3, "click", "disabled"], [1, "fas", "fa-solid", "fa-arrow-up"], [1, "fa-solid", "fa-share", 3, "click"], [3, "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", "ArtifactID", "ArtifactVersionID", "DataContext"], [3, "dialogClosed", "dataContextId", "Provider"], ["title", "Share Conversation", 3, "close", "width", "height"], [3, "Provider", "ResourceTypeID", "ResourceRecordID", "ExcludedRoleNames", "ExcludedUserEmails"], ["kendoButton", "", "themeColor", "primary", 3, "click"], ["kendoButton", "", 3, "click"], ["title", "Please confirm", 3, "close", "minWidth", "width"], [2, "margin", "30px", "text-align", "center"]], template: function SkipChatComponent_Template(rf, ctx) { if (rf & 1) {
2426
2651
  const _r1 = i0.ɵɵgetCurrentView();
2427
2652
  i0.ɵɵelementStart(0, "div", 7, 0)(2, "div", 8);
2428
2653
  i0.ɵɵtemplate(3, SkipChatComponent_Conditional_3_Template, 9, 5, "div", 9)(4, SkipChatComponent_Conditional_4_Template, 1, 0, "span", 10);
@@ -2436,7 +2661,7 @@ export class SkipChatComponent extends BaseManagedComponent {
2436
2661
  i0.ɵɵelement(15, "div", 18);
2437
2662
  i0.ɵɵtemplate(16, SkipChatComponent_span_16_Template, 2, 2, "span", 19);
2438
2663
  i0.ɵɵelementEnd();
2439
- i0.ɵɵtemplate(17, SkipChatComponent_Conditional_17_Template, 9, 7, "div", 20);
2664
+ i0.ɵɵtemplate(17, SkipChatComponent_Conditional_17_Template, 10, 5, "div", 20);
2440
2665
  i0.ɵɵelementEnd();
2441
2666
  i0.ɵɵelementStart(18, "div", 21);
2442
2667
  i0.ɵɵtemplate(19, SkipChatComponent_skip_artifact_viewer_19_Template, 1, 3, "skip-artifact-viewer", 22);
@@ -2467,11 +2692,11 @@ export class SkipChatComponent extends BaseManagedComponent {
2467
2692
  i0.ɵɵproperty("ngIf", ctx.confirmDeleteConversationDialogOpen);
2468
2693
  i0.ɵɵadvance();
2469
2694
  i0.ɵɵproperty("ngIf", ctx.confirmMessageEditOrDeleteDialogOpen);
2470
- } }, dependencies: [i2.NgClass, i2.NgIf, i5.DefaultValueAccessor, i5.NgControlStatus, i5.MaxLengthValidator, i5.NgModel, i6.LoaderComponent, i4.DialogComponent, i4.DialogActionsComponent, i4.DialogContainerDirective, i7.FillContainer, i7.Container, i8.ItemTemplateDirective, i8.ListViewComponent, i9.ButtonComponent, i10.DataContextDialogComponent, i11.ResourcePermissionsComponent, i12.SkipSplitPanelComponent, i13.SkipArtifactViewerComponent], styles: [".layout[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row; \n\n height: 100%; \n\n width: 100%; \n\n position: relative;\n overflow: hidden; \n\n}\n\n.left-panel[_ngcontent-%COMP%] {\n width: 272px; \n\n background-color: #f8f9fa; \n\n border-right: 1px solid #ddd; \n\n overflow-y: auto; \n\n overflow-x: hidden; \n\n position: relative;\n\n scrollbar-width: thin; \n\n scrollbar-color: #d3d3d3 #f8f9fa; \n\n}\n\n\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px; \n\n background-color: #f8f9fa; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; \n\n border-radius: 4px; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: #f8f9fa; \n\n}\n\n.right-panel[_ngcontent-%COMP%] {\n flex: 1; \n\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; \n\n overflow: hidden; \n\n}\n\n.conversation-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon[_ngcontent-%COMP%] {\n color: #808080; \n\n font-size: 18px; \n\n cursor: pointer; \n\n z-index: 10; \n\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon[_ngcontent-%COMP%] {\n color: #808080; \n\n font-size: 18px; \n\n cursor: pointer; \n\n z-index: 10; \n\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel[_ngcontent-%COMP%] .toggle-icon[_ngcontent-%COMP%] {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; \n\n}\n\n\n.chat-container[_ngcontent-%COMP%] {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n \n\n width: 100%;\n overflow: hidden; \n\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative; \n\n background-color: #f9f9f9;\n height: 100%; \n\n max-height: 100%; \n\n flex: 1;\n overflow: auto; \n\n}\n\n.new-conversation[_ngcontent-%COMP%] {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history[_ngcontent-%COMP%] {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; \n\n overflow-x: hidden; \n\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip[_ngcontent-%COMP%] {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n height: 25px;\n}\n\n.skip-title[_ngcontent-%COMP%] {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list[_ngcontent-%COMP%] {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n\n\n.welcome-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; \n\n}\n\n.embedded-conversations[_ngcontent-%COMP%] {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations[_ngcontent-%COMP%] > span[_ngcontent-%COMP%] {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked[_ngcontent-%COMP%] {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; \n\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text[_ngcontent-%COMP%] {\n font-size: larger;\n font-weight: bold;\n}\n\n\n\n.welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; \n\n}\n.welcome-suggested-questions-col[_ngcontent-%COMP%] {\n display: flex;\n margin-bottom: 10px; \n\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column; \n\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; \n\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question[_ngcontent-%COMP%]:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header[_ngcontent-%COMP%] {\n font-size: 12pt;\n font-weight: bold;\n display: block; \n\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages[_ngcontent-%COMP%] {\n overflow-y: auto !important; \n\n overflow-x: hidden !important; \n\n \n\n margin-bottom: 5px;\n\n margin-top: 2px; \n\n\n background-color: #f9f9f9;\n flex: 1 1 auto; \n\n height: calc(100% - 50px); \n\n max-height: 100%; \n\n scrollbar-width: thin; \n\n scrollbar-color: #d3d3d3 #f8f9fa; \n\n position: relative; \n\n}\n\n\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px; \n\n background-color: #f8f9fa; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; \n\n border-radius: 4px; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: #f8f9fa; \n\n}\n\n\n\n.messages-container[_ngcontent-%COMP%] {\n min-height: 20px; \n\n}\n\n\n\n.new-chat-area[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between; \n\n align-items: center; \n\n}\n.avatar[_ngcontent-%COMP%] {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n \n\n margin-right: auto; \n\n}\n\n.conversation-item[_ngcontent-%COMP%] {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; \n\n\n flex-wrap: wrap; \n\n}\n\n.text-container[_ngcontent-%COMP%] {\n flex: 1; \n\n display: flex;\n flex-direction: column; \n\n}\n\n.text-container[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: none; \n\n \n\n}\n\n.conversation-item[_ngcontent-%COMP%] > .conversation-icon[_ngcontent-%COMP%] {\n margin-top: 3px;\n}\n\n.conversation-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-block;\n white-space: pre-wrap; \n\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; \n\n}\n\n.conversation-item[_ngcontent-%COMP%]:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected[_ngcontent-%COMP%] {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item[_ngcontent-%COMP%] > .conversation-icon[_ngcontent-%COMP%] {\n margin-right: 11px;\n}\n.edit-conversation-panel[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end; \n\n margin-top: 2px; \n\n margin-right: 2px; \n\n}\n.edit-conversation-panel[_ngcontent-%COMP%] > .k-icon[_ngcontent-%COMP%] {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel[_ngcontent-%COMP%] > .k-icon[_ngcontent-%COMP%]:hover {\n color: #ff0000;\n}\n\n\n\n.input-area[_ngcontent-%COMP%] {\n min-height: 35px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-area[_ngcontent-%COMP%] > .button-area[_ngcontent-%COMP%] {\n vertical-align: top;\n margin-top: 3px;\n margin-left: -65px;\n}\n\n\n.button-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n border-radius: 12px;\n margin-left: 3px;\n}\n\n\n\n.button-area[_ngcontent-%COMP%] > button.stop-button[_ngcontent-%COMP%] {\n background-color: #dc3545;\n color: white;\n}\n\n.button-area[_ngcontent-%COMP%] > button.stop-button[_ngcontent-%COMP%]:hover {\n background-color: #c82333;\n}\n\n\n\n\n\n\n\n\n\n\n\n.text-area-wrapper[_ngcontent-%COMP%] {\n padding: 3px;\n border: solid 1px rgba(0, 0, 0, 0.08) ;\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; \n\n\n overflow: hidden; \n align-items: center;\n\n \n\n width: 710px; \n padding-right: 90px\n} \n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; \n\n\n width: 100%;\n overflow-y: hidden; \n\n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n\n background-color: #f9f9f9;\n}\n\n\n\n\n\n\n.input-wrapper[_ngcontent-%COMP%] {\n flex-grow: 1; \n\n height: 100%;\n}\n\n.waiting-for-ai[_ngcontent-%COMP%] {\n position: absolute;\n display: flex; \n\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: fixed; \n\n bottom: 120px; \n\n \n\n transform: translateX(-50%); \n\n z-index: 1000; \n\n background-color: white; \n\n color: black; \n\n border-radius: 50%; \n\n width: 40px; \n\n height: 40px; \n\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); \n\n cursor: pointer;\n opacity: 0.9; \n\n}\n\n.loading-convo-messages-wrapper[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap; \n\n align-content: flex-end; \n\n }\n}"] });
2695
+ } }, dependencies: [i2.NgClass, i2.NgIf, i5.DefaultValueAccessor, i5.NgControlStatus, i5.MaxLengthValidator, i5.NgModel, i6.LoaderComponent, i4.DialogComponent, i4.DialogActionsComponent, i4.DialogContainerDirective, i7.FillContainer, i7.Container, i8.ItemTemplateDirective, i8.ListViewComponent, i9.ButtonComponent, i10.DataContextDialogComponent, i11.ResourcePermissionsComponent, i12.SkipSplitPanelComponent, i13.SkipArtifactViewerComponent], styles: [".layout[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row; \n\n height: 100%; \n\n width: 100%; \n\n position: relative;\n overflow: hidden; \n\n}\n\n.left-panel[_ngcontent-%COMP%] {\n width: 272px; \n\n background-color: #f8f9fa; \n\n border-right: 1px solid #ddd; \n\n overflow-y: auto; \n\n overflow-x: hidden; \n\n position: relative;\n\n scrollbar-width: thin; \n\n scrollbar-color: #d3d3d3 #f8f9fa; \n\n}\n\n\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px; \n\n background-color: #f8f9fa; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; \n\n border-radius: 4px; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; \n\n}\n\n.left-panel[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: #f8f9fa; \n\n}\n\n.right-panel[_ngcontent-%COMP%] {\n flex: 1; \n\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; \n\n overflow: hidden; \n\n}\n\n.conversation-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon[_ngcontent-%COMP%] {\n color: #808080; \n\n font-size: 18px; \n\n cursor: pointer; \n\n z-index: 10; \n\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon[_ngcontent-%COMP%] {\n color: #808080; \n\n font-size: 18px; \n\n cursor: pointer; \n\n z-index: 10; \n\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel[_ngcontent-%COMP%] .toggle-icon[_ngcontent-%COMP%] {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; \n\n}\n\n\n.chat-container[_ngcontent-%COMP%] {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n \n\n width: 100%;\n overflow: hidden; \n\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative; \n\n background-color: #f9f9f9;\n height: 100%; \n\n max-height: 100%; \n\n flex: 1;\n overflow: auto; \n\n}\n\n.new-conversation[_ngcontent-%COMP%] {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history[_ngcontent-%COMP%] {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; \n\n overflow-x: hidden; \n\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip[_ngcontent-%COMP%] {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n height: 25px;\n}\n\n.skip-title[_ngcontent-%COMP%] {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list[_ngcontent-%COMP%] {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n\n\n.welcome-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; \n\n}\n\n.embedded-conversations[_ngcontent-%COMP%] {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations[_ngcontent-%COMP%] > span[_ngcontent-%COMP%] {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked[_ngcontent-%COMP%] {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; \n\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text[_ngcontent-%COMP%] {\n font-size: larger;\n font-weight: bold;\n}\n\n\n\n.welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; \n\n}\n.welcome-suggested-questions-col[_ngcontent-%COMP%] {\n display: flex;\n margin-bottom: 10px; \n\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column; \n\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; \n\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question[_ngcontent-%COMP%]:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header[_ngcontent-%COMP%] {\n font-size: 12pt;\n font-weight: bold;\n display: block; \n\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages[_ngcontent-%COMP%] {\n overflow-y: auto !important; \n\n overflow-x: hidden !important; \n\n \n\n margin-bottom: 5px;\n\n margin-top: 2px; \n\n\n background-color: #f9f9f9;\n flex: 1 1 auto; \n\n height: calc(100% - 50px); \n\n max-height: 100%; \n\n scrollbar-width: thin; \n\n scrollbar-color: #d3d3d3 #f8f9fa; \n\n position: relative; \n\n}\n\n\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px; \n\n background-color: #f8f9fa; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; \n\n border-radius: 4px; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; \n\n}\n\n.messages[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: #f8f9fa; \n\n}\n\n\n\n.messages-container[_ngcontent-%COMP%] {\n min-height: 20px; \n\n}\n\n\n\n.new-chat-area[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between; \n\n align-items: center; \n\n}\n.avatar[_ngcontent-%COMP%] {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n \n\n margin-right: auto; \n\n}\n\n.conversation-item[_ngcontent-%COMP%] {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; \n\n\n flex-wrap: wrap; \n\n}\n\n.text-container[_ngcontent-%COMP%] {\n flex: 1; \n\n display: flex;\n flex-direction: column; \n\n}\n\n.text-container[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: none; \n\n \n\n}\n\n.conversation-item[_ngcontent-%COMP%] > .conversation-icon[_ngcontent-%COMP%] {\n margin-top: 3px;\n}\n\n.conversation-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-block;\n white-space: pre-wrap; \n\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; \n\n}\n\n.conversation-item[_ngcontent-%COMP%]:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected[_ngcontent-%COMP%] {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item[_ngcontent-%COMP%] > .conversation-icon[_ngcontent-%COMP%] {\n margin-right: 11px;\n}\n.edit-conversation-panel[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end; \n\n margin-top: 2px; \n\n margin-right: 2px; \n\n}\n.edit-conversation-panel[_ngcontent-%COMP%] > .k-icon[_ngcontent-%COMP%] {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel[_ngcontent-%COMP%] > .k-icon[_ngcontent-%COMP%]:hover {\n color: #ff0000;\n}\n\n\n\n.input-area[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n padding: 10px 20px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-container[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 800px;\n}\n\n.button-area[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 8px;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n\n.button-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n min-width: 28px;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n.button-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.button-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.button-area[_ngcontent-%COMP%] > button.stop-button[_ngcontent-%COMP%] {\n background-color: #dc3545;\n color: white;\n border-color: #dc3545;\n}\n\n.button-area[_ngcontent-%COMP%] > button.stop-button[_ngcontent-%COMP%]:hover {\n background-color: #c82333;\n border-color: #c82333;\n}\n\n.text-area-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n padding: 10px 12px;\n padding-right: 120px; \n\n border: solid 1px rgba(0, 0, 0, 0.08);\n border-radius: 15px;\n min-height: 44px;\n max-height: 200px;\n overflow-y: auto;\n background-color: white;\n align-items: flex-end;\n} \n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n resize: none;\n width: 100%;\n min-height: 24px;\n max-height: 180px;\n overflow-y: auto;\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n line-height: 1.5;\n background-color: transparent;\n padding: 0;\n margin: 0;\n}\n\n\n\n\n\n\n.input-wrapper[_ngcontent-%COMP%] {\n flex-grow: 1; \n\n height: 100%;\n}\n\n.waiting-for-ai[_ngcontent-%COMP%] {\n position: absolute;\n display: flex; \n\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: fixed; \n\n bottom: 120px; \n\n \n\n transform: translateX(-50%); \n\n z-index: 1000; \n\n background-color: white; \n\n color: black; \n\n border-radius: 50%; \n\n width: 40px; \n\n height: 40px; \n\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); \n\n cursor: pointer;\n opacity: 0.9; \n\n}\n\n.loading-convo-messages-wrapper[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap; \n\n align-content: flex-end; \n\n }\n}"] });
2471
2696
  }
2472
2697
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SkipChatComponent, [{
2473
2698
  type: Component,
2474
- args: [{ selector: 'skip-chat', template: "<div class=\"chat-container\" kendoDialogContainer #topLevelDiv>\n <div class=\"layout\">\n @if (IsConversationListVisible) {\n <div class=\"left-panel\">\n <div class=\"conversation-history\">\n <div class=\"new-chat-area\">\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(false)\"></span>\n @if (ShowSkipLogoInConversationList) {\n <img [src]=\"SkipLogoURL\" class=\"avatar\" />\n }\n @if (AllowNewConversations) {\n <span class=\"fa-solid fa-pen-to-square new-convo-icon\" (click)=\"CreateNewConversation()\"></span> \n }\n </div>\n <kendo-listview\n class=\"conversation-list\"\n [data]=\"Conversations\"\n [itemClass]=\"{ 'item-border': true }\" \n #conversationList\n >\n <ng-template kendoListViewItemTemplate let-dataItem=\"dataItem\">\n <div class=\"conversation-item\" \n [ngClass]=\"GetConversationItemClass(dataItem)\"\n [title]=\"dataItem.Name\" \n (click)=\"SelectConversation(dataItem)\"> \n <span *ngIf=\"SelectedConversation && IsSkipProcessing(dataItem)\" class=\"fa-regular fa-clock\"></span>\n <div class=\"text-container\">\n <span *ngIf=\"dataItem.ID !== SelectedConversation?.ID || !ConversationEditMode\">{{ dataItem.Name }}</span>\n <textarea *ngIf=\"dataItem.ID === SelectedConversation?.ID && ConversationEditMode\" [(ngModel)]=\"dataItem.Name\" maxlength=\"100\"></textarea>\n </div>\n <div *ngIf=\"SelectedConversation?.ID === dataItem.ID\" class=\"edit-conversation-panel\">\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-solid fa-pen-to-square\" (click)=\"editConvo(dataItem)\"></span>\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-regular fa-trash-can\" (click)=\"showDeleteConvoDialog(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-check\" (click)=\"saveConvoName(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-xmark\" (click)=\"cancelConvoEdit(dataItem)\"></span>\n </div>\n </div>\n </ng-template>\n </kendo-listview>\n <!-- COMMENTED OUT as we don't want to support embedded conversations in the UI for now\n <div class=\"embedded-conversations\"><input kendoCheckBox type=\"checkbox\" [(ngModel)]=\"IncludeLinkedConversationsInList\" (ngModelChange)=\"loadConversations()\"/> <span (click)=\"FlipEmbeddedConversationState()\">Show Linked Conversations</span></div> -->\n </div> \n </div>\n }\n @if (!IsConversationListVisible) {\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(true)\"></span>\n }\n\n <div class=\"right-panel\">\n <skip-split-panel \n #splitPanel\n [Mode]=\"EnableArtifactSplitView && selectedArtifact ? 'BothSides' : 'LeftOnly'\" \n [SplitRatio]=\"SplitRatio\" \n (SplitRatioChanged)=\"onSplitRatioChanged($event)\"\n [RightPanelHeaderContent]=\"artifactHeaderInfo\"\n [VersionList]=\"artifactVersionList\"\n [SelectedVersionId]=\"selectedArtifactVersionId\"\n (VersionSelected)=\"onArtifactVersionSelected($event)\"\n mjFillContainer [fillWidth]=\"false\" [fillHeight]=\"true\">\n \n <!-- Left Panel (Chat) -->\n <div left-panel class=\"conversation-wrapper\">\n <!-- Use this for reference only, but don't display - hidden via width:0, height:0 -->\n <div #AskSkipPanel style=\"width:0; height:0; overflow:hidden; position:absolute;\"></div>\n \n <div class=\"messages\" #scrollContainer (scroll)=\"checkScroll()\">\n <div class=\"welcome-wrapper\" *ngIf=\"(!Messages || Messages.length ===0) && _conversationLoadComplete\">\n <div class='welcome-message'>\n <img [src]=\"SkipLogoURL\" />\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n </div>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n </div>\n </div> \n </div>\n @if (!_conversationLoadComplete) {\n <div class=\"loading-convo-messages-wrapper\">\n <kendo-loader></kendo-loader>\n </div>\n } \n <div class=\"messages-container\" mjContainer mjSkipResize=\"true\"><!--mjSkipResize results in everything below this level NOT being resized, performance optimization-->\n <!-- Dynamic messages will be injected here -->\n </div>\n <span class=\"scroll-to-bottom-icon\" \n *ngIf=\"_showScrollToBottomIcon && Messages && Messages.length > 0\" \n [style.left.px]=\"getScrollToBottomIconPosition()\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n @if (SelectedConversationCurrentUserPermissionLevel === 'Owner' || \n SelectedConversationCurrentUserPermissionLevel === 'Edit') {\n <div class=\"input-area\">\n <div class=\"text-area-wrapper\">\n <textarea\n #AskSkipInput \n [disabled]=\"SelectedConversation && IsSkipProcessing(SelectedConversation)\" \n (keyup.enter)=\"onEnter($event)\" \n (input)=\"onInputChange($event)\"\n type=\"text\" \n [placeholder]=\"_AskSkipTextboxPlaceholder\"></textarea>\n </div>\n <div class=\"button-area\" [style.marginLeft.px]=\"-35 * NumVisibleButtons\">\n @if (ShowDataContextButton) {\n <button kendoButton >\n <span class=\"fa-solid fa-gear\" \n (click)=\"showDataContextDialog()\"></span>\n </button> \n }\n @if (SelectedConversation && IsSkipProcessing(SelectedConversation)) {\n <button kendoButton \n class=\"stop-button\"\n (click)=\"stopProcessing()\">\n <span class=\"fas fa-solid fa-stop\"></span>\n </button>\n }\n @else {\n <button kendoButton \n [disabled]=\"IsTextAreaEmpty()\" \n (click)=\"sendSkipMessage()\">\n <span class=\"fas fa-solid fa-arrow-up\"></span>\n </button>\n }\n @if (ShowSharingButton && SelectedConversationCurrentUserPermissionLevel === 'Owner') {\n <button kendoButton class=\"share-button\">\n <span class=\"fa-solid fa-share\"\n (click)=\"showSharingDialog()\"></span>\n </button> \n }\n </div>\n </div>\n }\n </div>\n \n <!-- Right Panel (Artifact Viewer) -->\n <div right-panel>\n <skip-artifact-viewer\n *ngIf=\"selectedArtifact\"\n [ArtifactID]=\"selectedArtifact.artifactId\"\n [ArtifactVersionID]=\"selectedArtifact.artifactVersionId\"\n [DataContext]=\"DataContext\"\n (NavigateToMatchingReport)=\"NavigateToMatchingReport.emit($event)\"\n (NewReportCreated)=\"NewReportCreated.emit($event)\"\n (DrillDownEvent)=\"DrillDownEvent.emit($event)\"\n (ArtifactInfoChanged)=\"onArtifactInfoChanged($event)\">\n </skip-artifact-viewer>\n </div>\n </skip-split-panel>\n </div> \n </div> \n</div> \n\n@if(isDataContextDialogVisible) {\n <mj-data-context-dialog [dataContextId]=\"DataContextID\" (dialogClosed)=\"closeDataContextDialog()\" [Provider]=\"ProviderToUse\"></mj-data-context-dialog>\n}\n@if(isSharingDialogVisible && SelectedConversation && conversationResourceTypeID) {\n <kendo-dialog\n title=\"Share Conversation\"\n (close)=\"closeSharingDialog('no')\"\n [width]=\"650\"\n [height]=\"400\"\n >\n <mj-resource-permissions \n [Provider]=\"Provider\"\n [ResourceTypeID]=\"conversationResourceTypeID\"\n [ResourceRecordID]=\"SelectedConversation.ID\"\n [ExcludedRoleNames]=\"SharingExcludeRoleNames\"\n [ExcludedUserEmails]=\"SharingExcludeEmails\"\n #resourcePermissions\n >\n </mj-resource-permissions>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeSharingDialog('yes')\" themeColor=\"primary\">\n Save\n </button>\n <button kendoButton (click)=\"closeSharingDialog('no')\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog> \n}\n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmDeleteConversationDialogOpen\"\n (close)=\"closeDeleteConversation('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to delete {{SelectedConversation?.Name}}?\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeDeleteConversation('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeDeleteConversation('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> \n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmMessageEditOrDeleteDialogOpen\"\n (close)=\"closeMessageEditOrDeleteDialog('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to {{messageEditOrDeleteType}} this message? Doing so will result in any subsequent messages in the conversation being deleted.\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> ", styles: [".layout {\n display: flex;\n flex-direction: row; /* Ensures left and right panels are side by side */\n height: 100%; /* Fill the available height */\n width: 100%; /* Fill the available width */\n position: relative;\n overflow: hidden; /* Prevent content from expanding beyond container */\n}\n\n.left-panel {\n width: 272px; /* Fixed width for the conversation list */\n background-color: #f8f9fa; /* Optional: Background color */\n border-right: 1px solid #ddd; /* Optional: Add a divider */\n overflow-y: auto; /* Enable scrolling if content overflows */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n position: relative;\n\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.left-panel::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.left-panel::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.left-panel::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.left-panel::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n.right-panel {\n flex: 1; /* Take up the remaining space */\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; /* Don't exceed parent container height */\n overflow: hidden; /* Hide overflow to prevent double scrollbars */\n}\n\n.conversation-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel .toggle-icon {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; /* For the right panel toggle */\n}\n\n\n.chat-container {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n /*initial sizes*/\n width: 100%;\n overflow: hidden; /* Prevent container from growing beyond viewport */\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper {\n display: flex;\n flex-direction: column;\n position: relative; /* This ensures child absolute elements position relative to this container */\n background-color: #f9f9f9;\n height: 100%; /* Ensure it takes full height */\n max-height: 100%; /* Don't exceed parent container height */\n flex: 1;\n overflow: auto; /* Allow content to scroll */\n}\n\n.new-conversation {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; /* Add scroll if the content exceeds the height */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history > button {\n height: 25px;\n}\n\n.skip-title {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n/* Center the welcome message vertically and horizontally */\n.welcome-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; /* Push the content up a bit */\n}\n\n.embedded-conversations {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations > span {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message img {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; /* Adds some space between the image and the text below */\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text {\n font-size: larger;\n font-weight: bold;\n}\n\n/* Position the welcome-suggested-questions at the bottom of its container */\n.welcome-suggested-questions {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; /* Push questions down for spacing */\n}\n.welcome-suggested-questions-col {\n display: flex;\n margin-bottom: 10px; /* Space between rows */\n}\n\n/* Flex layout for questions, two per row */\n.welcome-question {\n display: flex;\n flex-direction: column; /* Stack the header and text vertically */\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; /* Adds some space around each question */\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header {\n font-size: 12pt;\n font-weight: bold;\n display: block; /* Ensures the header is on its own line */\n}\n\n/* Non-bold text for the content below the header */\n.welcome-question span:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages {\n overflow-y: auto !important; /* enable scrolling if the content overflows */\n overflow-x: hidden !important; /* hide horizontal scrollbar */\n /* border: solid 1px rgba(0, 0, 0, 0.08); */\n margin-bottom: 5px;\n\n margin-top: 2px; /* align it with the top of converation history exactly*/\n\n background-color: #f9f9f9;\n flex: 1 1 auto; /* Take up available space but don't push parent beyond size */\n height: calc(100% - 50px); /* Ensure messages container has a height */\n max-height: 100%; /* Don't exceed parent height */\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n position: relative; /* For proper positioning of scroll icon */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.messages::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.messages::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.messages::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.messages::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n/* Class for the messages container */\n.messages-container {\n min-height: 20px; /* Ensure container takes space even when empty */\n}\n\n\n\n.new-chat-area {\n display: flex;\n justify-content: space-between; /* Aligns children (img and button) to each end */\n align-items: center; /* Centers children vertically */\n}\n.avatar {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n /* Ensure the image aligns to the left */\n margin-right: auto; /* Pushes everything else to the right */\n}\n\n.conversation-item {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; /* Align items to the top */\n\n flex-wrap: wrap; /* Allow items to wrap to the next line */\n}\n\n.text-container {\n flex: 1; /* Take up remaining space */\n display: flex;\n flex-direction: column; /* Stack children vertically */\n}\n\n.text-container textarea {\n resize: none; /* Disable resizing */\n /* Add more styles for the textarea if needed */\n}\n\n.conversation-item > .conversation-icon {\n margin-top: 3px;\n}\n\n.conversation-item span {\n display: inline-block;\n white-space: pre-wrap; /* Allow text to wrap */\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; /* Move the text to the right */\n}\n\n.conversation-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item > .conversation-icon {\n margin-right: 11px;\n}\n.edit-conversation-panel {\n display: flex;\n justify-content: flex-end; /* Align icons to the right */\n margin-top: 2px; /* litle buffer on top */\n margin-right: 2px; /* litle buffer to the right */\n}\n.edit-conversation-panel > .k-icon {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel > .k-icon:hover {\n color: #ff0000;\n}\n\n\n\n.input-area {\n min-height: 35px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-area > .button-area {\n vertical-align: top;\n margin-top: 3px;\n margin-left: -65px;\n}\n/*all buttons in the button area within the input area*/\n.button-area > button {\n width: 30px;\n height: 30px;\n border-radius: 12px;\n margin-left: 3px;\n}\n\n/* Stop button styling */\n.button-area > button.stop-button {\n background-color: #dc3545;\n color: white;\n}\n\n.button-area > button.stop-button:hover {\n background-color: #c82333;\n}\n/* .input-area > button:first-of-type {\n margin-left: -40px;\n}\n.input-area > button:last-child {\n margin-left: -65px;\n}\n.input-area > .share-button {\n margin-left: 10px;\n} */\n\n.text-area-wrapper {\n padding: 3px;\n border: solid 1px rgba(0, 0, 0, 0.08) ;\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; /* Prevent it from growing beyond the container */\n\n overflow: hidden; \n align-items: center;\n\n /*combined width and padding is 800*/\n width: 710px; \n padding-right: 90px\n} \n.text-area-wrapper > textarea {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; /* Initial height */\n\n width: 100%;\n overflow-y: hidden; /* Hide scrollbar */\n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n\n background-color: #f9f9f9;\n}\n\n/* .text-area-wrapper > textarea:disabled {\n background-color: white;\n} */\n\n.input-wrapper {\n flex-grow: 1; /* This will make the input-wrapper take the remaining space */\n height: 100%;\n}\n\n.waiting-for-ai {\n position: absolute;\n display: flex; /* Use flexbox layout */\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon {\n position: fixed; /* Fixed positioning to float over content */\n bottom: 120px; /* Position relative to the viewport */\n /* left position will be set dynamically via inline style */\n transform: translateX(-50%); /* Shift it back by half its width to center it */\n z-index: 1000; /* Ensure it stays on top */\n background-color: white; /* Circle background color */\n color: black; /* Icon color */\n border-radius: 50%; /* Makes the background a circle */\n width: 40px; /* Circle size */\n height: 40px; /* Circle size */\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); /* Subtle shadow for better visibility */\n cursor: pointer;\n opacity: 0.9; /* Slightly transparent */\n}\n\n.loading-convo-messages-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions {\n display: flex;\n flex-wrap: wrap; /* Allows questions to wrap to the next line */\n align-content: flex-end; /* Aligns the content to the bottom */\n }\n}\n \n"] }]
2699
+ args: [{ selector: 'skip-chat', template: "<div class=\"chat-container\" kendoDialogContainer #topLevelDiv>\n <div class=\"layout\">\n @if (IsConversationListVisible) {\n <div class=\"left-panel\">\n <div class=\"conversation-history\">\n <div class=\"new-chat-area\">\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(false)\"></span>\n @if (ShowSkipLogoInConversationList) {\n <img [src]=\"SkipLogoURL\" class=\"avatar\" />\n }\n @if (AllowNewConversations) {\n <span class=\"fa-solid fa-pen-to-square new-convo-icon\" (click)=\"CreateNewConversation()\"></span> \n }\n </div>\n <kendo-listview\n class=\"conversation-list\"\n [data]=\"Conversations\"\n [itemClass]=\"{ 'item-border': true }\" \n #conversationList\n >\n <ng-template kendoListViewItemTemplate let-dataItem=\"dataItem\">\n <div class=\"conversation-item\" \n [ngClass]=\"GetConversationItemClass(dataItem)\"\n [title]=\"dataItem.Name\" \n (click)=\"SelectConversation(dataItem)\"> \n <span *ngIf=\"SelectedConversation && IsSkipProcessing(dataItem)\" class=\"fa-regular fa-clock\"></span>\n <div class=\"text-container\">\n <span *ngIf=\"dataItem.ID !== SelectedConversation?.ID || !ConversationEditMode\">{{ dataItem.Name }}</span>\n <textarea *ngIf=\"dataItem.ID === SelectedConversation?.ID && ConversationEditMode\" [(ngModel)]=\"dataItem.Name\" maxlength=\"100\"></textarea>\n </div>\n <div *ngIf=\"SelectedConversation?.ID === dataItem.ID\" class=\"edit-conversation-panel\">\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-solid fa-pen-to-square\" (click)=\"editConvo(dataItem)\"></span>\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-regular fa-trash-can\" (click)=\"showDeleteConvoDialog(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-check\" (click)=\"saveConvoName(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-xmark\" (click)=\"cancelConvoEdit(dataItem)\"></span>\n </div>\n </div>\n </ng-template>\n </kendo-listview>\n <!-- COMMENTED OUT as we don't want to support embedded conversations in the UI for now\n <div class=\"embedded-conversations\"><input kendoCheckBox type=\"checkbox\" [(ngModel)]=\"IncludeLinkedConversationsInList\" (ngModelChange)=\"loadConversations()\"/> <span (click)=\"FlipEmbeddedConversationState()\">Show Linked Conversations</span></div> -->\n </div> \n </div>\n }\n @if (!IsConversationListVisible) {\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(true)\"></span>\n }\n\n <div class=\"right-panel\">\n <skip-split-panel \n #splitPanel\n [Mode]=\"EnableArtifactSplitView && selectedArtifact ? 'BothSides' : 'LeftOnly'\" \n [SplitRatio]=\"SplitRatio\" \n (SplitRatioChanged)=\"onSplitRatioChanged($event)\"\n [RightPanelHeaderContent]=\"artifactHeaderInfo\"\n [VersionList]=\"artifactVersionList\"\n [SelectedVersionId]=\"selectedArtifactVersionId\"\n (VersionSelected)=\"onArtifactVersionSelected($event)\"\n mjFillContainer [fillWidth]=\"false\" [fillHeight]=\"true\">\n \n <!-- Left Panel (Chat) -->\n <div left-panel class=\"conversation-wrapper\">\n <!-- Use this for reference only, but don't display - hidden via width:0, height:0 -->\n <div #AskSkipPanel style=\"width:0; height:0; overflow:hidden; position:absolute;\"></div>\n \n <div class=\"messages\" #scrollContainer (scroll)=\"checkScroll()\">\n <div class=\"welcome-wrapper\" *ngIf=\"(!Messages || Messages.length ===0) && _conversationLoadComplete\">\n <div class='welcome-message'>\n <img [src]=\"SkipLogoURL\" />\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n </div>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n </div>\n </div> \n </div>\n @if (!_conversationLoadComplete) {\n <div class=\"loading-convo-messages-wrapper\">\n <kendo-loader></kendo-loader>\n </div>\n } \n <div class=\"messages-container\" mjContainer mjSkipResize=\"true\"><!--mjSkipResize results in everything below this level NOT being resized, performance optimization-->\n <!-- Dynamic messages will be injected here -->\n </div>\n <span class=\"scroll-to-bottom-icon\" \n *ngIf=\"_showScrollToBottomIcon && Messages && Messages.length > 0\" \n [style.left.px]=\"getScrollToBottomIconPosition()\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n @if (SelectedConversationCurrentUserPermissionLevel === 'Owner' || \n SelectedConversationCurrentUserPermissionLevel === 'Edit') {\n <div class=\"input-area\">\n <div class=\"input-container\">\n <div class=\"text-area-wrapper\">\n <textarea\n #AskSkipInput \n [disabled]=\"SelectedConversation && IsSkipProcessing(SelectedConversation)\" \n (keyup.enter)=\"onEnter($event)\" \n (input)=\"onInputChange($event)\"\n type=\"text\" \n [placeholder]=\"_AskSkipTextboxPlaceholder\"></textarea>\n <div class=\"button-area\">\n @if (ShowDataContextButton) {\n <button kendoButton >\n <span class=\"fa-solid fa-gear\" \n (click)=\"showDataContextDialog()\"></span>\n </button> \n }\n @if (SelectedConversation && IsSkipProcessing(SelectedConversation)) {\n <button kendoButton \n class=\"stop-button\"\n (click)=\"stopProcessing()\">\n <span class=\"fas fa-solid fa-stop\"></span>\n </button>\n }\n @else {\n <button kendoButton \n [disabled]=\"IsTextAreaEmpty()\" \n (click)=\"sendSkipMessage()\">\n <span class=\"fas fa-solid fa-arrow-up\"></span>\n </button>\n }\n @if (ShowSharingButton && SelectedConversationCurrentUserPermissionLevel === 'Owner') {\n <button kendoButton class=\"share-button\">\n <span class=\"fa-solid fa-share\"\n (click)=\"showSharingDialog()\"></span>\n </button> \n }\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n \n <!-- Right Panel (Artifact Viewer) -->\n <div right-panel>\n <skip-artifact-viewer\n *ngIf=\"selectedArtifact\"\n [ArtifactID]=\"selectedArtifact.artifactId\"\n [ArtifactVersionID]=\"selectedArtifact.artifactVersionId\"\n [DataContext]=\"DataContext\"\n (NavigateToMatchingReport)=\"NavigateToMatchingReport.emit($event)\"\n (NewReportCreated)=\"NewReportCreated.emit($event)\"\n (DrillDownEvent)=\"DrillDownEvent.emit($event)\"\n (ArtifactInfoChanged)=\"onArtifactInfoChanged($event)\">\n </skip-artifact-viewer>\n </div>\n </skip-split-panel>\n </div> \n </div> \n</div> \n\n@if(isDataContextDialogVisible) {\n <mj-data-context-dialog [dataContextId]=\"DataContextID\" (dialogClosed)=\"closeDataContextDialog()\" [Provider]=\"ProviderToUse\"></mj-data-context-dialog>\n}\n@if(isSharingDialogVisible && SelectedConversation && conversationResourceTypeID) {\n <kendo-dialog\n title=\"Share Conversation\"\n (close)=\"closeSharingDialog('no')\"\n [width]=\"650\"\n [height]=\"400\"\n >\n <mj-resource-permissions \n [Provider]=\"Provider\"\n [ResourceTypeID]=\"conversationResourceTypeID\"\n [ResourceRecordID]=\"SelectedConversation.ID\"\n [ExcludedRoleNames]=\"SharingExcludeRoleNames\"\n [ExcludedUserEmails]=\"SharingExcludeEmails\"\n #resourcePermissions\n >\n </mj-resource-permissions>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeSharingDialog('yes')\" themeColor=\"primary\">\n Save\n </button>\n <button kendoButton (click)=\"closeSharingDialog('no')\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog> \n}\n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmDeleteConversationDialogOpen\"\n (close)=\"closeDeleteConversation('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to delete {{SelectedConversation?.Name}}?\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeDeleteConversation('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeDeleteConversation('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> \n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmMessageEditOrDeleteDialogOpen\"\n (close)=\"closeMessageEditOrDeleteDialog('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to {{messageEditOrDeleteType}} this message? Doing so will result in any subsequent messages in the conversation being deleted.\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> ", styles: [".layout {\n display: flex;\n flex-direction: row; /* Ensures left and right panels are side by side */\n height: 100%; /* Fill the available height */\n width: 100%; /* Fill the available width */\n position: relative;\n overflow: hidden; /* Prevent content from expanding beyond container */\n}\n\n.left-panel {\n width: 272px; /* Fixed width for the conversation list */\n background-color: #f8f9fa; /* Optional: Background color */\n border-right: 1px solid #ddd; /* Optional: Add a divider */\n overflow-y: auto; /* Enable scrolling if content overflows */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n position: relative;\n\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.left-panel::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.left-panel::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.left-panel::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.left-panel::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n.right-panel {\n flex: 1; /* Take up the remaining space */\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; /* Don't exceed parent container height */\n overflow: hidden; /* Hide overflow to prevent double scrollbars */\n}\n\n.conversation-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel .toggle-icon {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; /* For the right panel toggle */\n}\n\n\n.chat-container {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n /*initial sizes*/\n width: 100%;\n overflow: hidden; /* Prevent container from growing beyond viewport */\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper {\n display: flex;\n flex-direction: column;\n position: relative; /* This ensures child absolute elements position relative to this container */\n background-color: #f9f9f9;\n height: 100%; /* Ensure it takes full height */\n max-height: 100%; /* Don't exceed parent container height */\n flex: 1;\n overflow: auto; /* Allow content to scroll */\n}\n\n.new-conversation {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; /* Add scroll if the content exceeds the height */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history > button {\n height: 25px;\n}\n\n.skip-title {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n/* Center the welcome message vertically and horizontally */\n.welcome-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; /* Push the content up a bit */\n}\n\n.embedded-conversations {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations > span {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message img {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; /* Adds some space between the image and the text below */\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text {\n font-size: larger;\n font-weight: bold;\n}\n\n/* Position the welcome-suggested-questions at the bottom of its container */\n.welcome-suggested-questions {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; /* Push questions down for spacing */\n}\n.welcome-suggested-questions-col {\n display: flex;\n margin-bottom: 10px; /* Space between rows */\n}\n\n/* Flex layout for questions, two per row */\n.welcome-question {\n display: flex;\n flex-direction: column; /* Stack the header and text vertically */\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; /* Adds some space around each question */\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header {\n font-size: 12pt;\n font-weight: bold;\n display: block; /* Ensures the header is on its own line */\n}\n\n/* Non-bold text for the content below the header */\n.welcome-question span:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages {\n overflow-y: auto !important; /* enable scrolling if the content overflows */\n overflow-x: hidden !important; /* hide horizontal scrollbar */\n /* border: solid 1px rgba(0, 0, 0, 0.08); */\n margin-bottom: 5px;\n\n margin-top: 2px; /* align it with the top of converation history exactly*/\n\n background-color: #f9f9f9;\n flex: 1 1 auto; /* Take up available space but don't push parent beyond size */\n height: calc(100% - 50px); /* Ensure messages container has a height */\n max-height: 100%; /* Don't exceed parent height */\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n position: relative; /* For proper positioning of scroll icon */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.messages::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.messages::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.messages::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.messages::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n/* Class for the messages container */\n.messages-container {\n min-height: 20px; /* Ensure container takes space even when empty */\n}\n\n\n\n.new-chat-area {\n display: flex;\n justify-content: space-between; /* Aligns children (img and button) to each end */\n align-items: center; /* Centers children vertically */\n}\n.avatar {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n /* Ensure the image aligns to the left */\n margin-right: auto; /* Pushes everything else to the right */\n}\n\n.conversation-item {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; /* Align items to the top */\n\n flex-wrap: wrap; /* Allow items to wrap to the next line */\n}\n\n.text-container {\n flex: 1; /* Take up remaining space */\n display: flex;\n flex-direction: column; /* Stack children vertically */\n}\n\n.text-container textarea {\n resize: none; /* Disable resizing */\n /* Add more styles for the textarea if needed */\n}\n\n.conversation-item > .conversation-icon {\n margin-top: 3px;\n}\n\n.conversation-item span {\n display: inline-block;\n white-space: pre-wrap; /* Allow text to wrap */\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; /* Move the text to the right */\n}\n\n.conversation-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item > .conversation-icon {\n margin-right: 11px;\n}\n.edit-conversation-panel {\n display: flex;\n justify-content: flex-end; /* Align icons to the right */\n margin-top: 2px; /* litle buffer on top */\n margin-right: 2px; /* litle buffer to the right */\n}\n.edit-conversation-panel > .k-icon {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel > .k-icon:hover {\n color: #ff0000;\n}\n\n\n\n.input-area {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n padding: 10px 20px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-container {\n width: 100%;\n max-width: 800px;\n}\n\n.button-area {\n position: absolute;\n bottom: 8px;\n right: 8px;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n/* All buttons in the button area */\n.button-area > button {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n min-width: 28px;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n.button-area > button:hover:not(:disabled) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.button-area > button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Stop button styling */\n.button-area > button.stop-button {\n background-color: #dc3545;\n color: white;\n border-color: #dc3545;\n}\n\n.button-area > button.stop-button:hover {\n background-color: #c82333;\n border-color: #c82333;\n}\n\n.text-area-wrapper {\n position: relative;\n display: flex;\n padding: 10px 12px;\n padding-right: 120px; /* Space for buttons */\n border: solid 1px rgba(0, 0, 0, 0.08);\n border-radius: 15px;\n min-height: 44px;\n max-height: 200px;\n overflow-y: auto;\n background-color: white;\n align-items: flex-end;\n} \n.text-area-wrapper > textarea {\n border: 0;\n outline: 0;\n resize: none;\n width: 100%;\n min-height: 24px;\n max-height: 180px;\n overflow-y: auto;\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n line-height: 1.5;\n background-color: transparent;\n padding: 0;\n margin: 0;\n}\n\n/* .text-area-wrapper > textarea:disabled {\n background-color: white;\n} */\n\n.input-wrapper {\n flex-grow: 1; /* This will make the input-wrapper take the remaining space */\n height: 100%;\n}\n\n.waiting-for-ai {\n position: absolute;\n display: flex; /* Use flexbox layout */\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon {\n position: fixed; /* Fixed positioning to float over content */\n bottom: 120px; /* Position relative to the viewport */\n /* left position will be set dynamically via inline style */\n transform: translateX(-50%); /* Shift it back by half its width to center it */\n z-index: 1000; /* Ensure it stays on top */\n background-color: white; /* Circle background color */\n color: black; /* Icon color */\n border-radius: 50%; /* Makes the background a circle */\n width: 40px; /* Circle size */\n height: 40px; /* Circle size */\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); /* Subtle shadow for better visibility */\n cursor: pointer;\n opacity: 0.9; /* Slightly transparent */\n}\n\n.loading-convo-messages-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions {\n display: flex;\n flex-wrap: wrap; /* Allows questions to wrap to the next line */\n align-content: flex-end; /* Aligns the content to the bottom */\n }\n}\n \n"] }]
2475
2700
  }], () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.Location }, { type: i0.ChangeDetectorRef }, { type: i3.MJNotificationService }, { type: i4.DialogService }], { AllowSend: [{
2476
2701
  type: Input
2477
2702
  }], Messages: [{