@memberjunction/ng-skip-chat 2.94.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.
- package/dist/lib/skip-chat/skip-chat.component.d.ts +12 -0
- package/dist/lib/skip-chat/skip-chat.component.d.ts.map +1 -1
- package/dist/lib/skip-chat/skip-chat.component.js +323 -98
- package/dist/lib/skip-chat/skip-chat.component.js.map +1 -1
- package/dist/lib/skip-single-message/skip-single-message.component.js +66 -64
- package/dist/lib/skip-single-message/skip-single-message.component.js.map +1 -1
- package/package.json +15 -15
|
@@ -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
|
|
230
|
+
function SkipChatComponent_Conditional_17_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
231
231
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
232
|
-
i0.ɵɵelementStart(0, "button",
|
|
233
|
-
i0.ɵɵlistener("click", function
|
|
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
|
|
236
|
+
function SkipChatComponent_Conditional_17_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
237
237
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
238
|
-
i0.ɵɵelementStart(0, "button",
|
|
239
|
-
i0.ɵɵlistener("click", function
|
|
240
|
-
i0.ɵɵelement(1, "span",
|
|
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
|
|
243
|
+
function SkipChatComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
244
244
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
245
|
-
i0.ɵɵelementStart(0, "button",
|
|
246
|
-
i0.ɵɵlistener("click", function
|
|
247
|
-
i0.ɵɵelement(1, "span",
|
|
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
|
|
253
|
+
function SkipChatComponent_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
254
254
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
255
|
-
i0.ɵɵelementStart(0, "button",
|
|
256
|
-
i0.ɵɵlistener("click", function
|
|
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, "
|
|
262
|
-
i0.ɵɵlistener("keyup.enter", function
|
|
263
|
-
i0.ɵɵelementEnd()
|
|
264
|
-
i0.ɵɵelementStart(
|
|
265
|
-
i0.ɵɵtemplate(
|
|
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(
|
|
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(
|
|
272
|
-
i0.ɵɵ
|
|
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) ?
|
|
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" ?
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
303
|
-
i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button",
|
|
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",
|
|
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",
|
|
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",
|
|
319
|
+
i0.ɵɵelementStart(1, "p", 82);
|
|
322
320
|
i0.ɵɵtext(2);
|
|
323
321
|
i0.ɵɵelementEnd();
|
|
324
|
-
i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button",
|
|
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",
|
|
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",
|
|
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",
|
|
340
|
+
i0.ɵɵelementStart(1, "p", 82);
|
|
343
341
|
i0.ɵɵtext(2);
|
|
344
342
|
i0.ɵɵelementEnd();
|
|
345
|
-
i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button",
|
|
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",
|
|
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
|
|
591
|
-
|
|
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
|
-
|
|
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:
|
|
614
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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
|
|
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
|
-
//
|
|
1396
|
-
this.
|
|
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
|
-
//
|
|
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
|
-
}
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
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,
|
|
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: [{
|