@memberjunction/ng-conversations 2.129.0 → 2.130.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/components/attachment/image-viewer.component.d.ts +95 -0
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/attachment/image-viewer.component.js +293 -0
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +86 -25
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +524 -348
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +12 -3
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +68 -55
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +2 -0
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +157 -145
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts +102 -5
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.js +349 -21
- package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +3 -2
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +29 -2
- package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +79 -12
- package/dist/lib/components/message/message-input-box.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +56 -4
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +227 -60
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +34 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +181 -93
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +4 -1
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +12 -1
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +44 -13
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +82 -108
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +26 -25
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +7 -3
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +23 -0
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +91 -2
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +2 -0
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +20 -3
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +36 -5
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +233 -71
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts +79 -0
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -0
- package/dist/lib/services/conversation-attachment.service.js +327 -0
- package/dist/lib/services/conversation-attachment.service.js.map +1 -0
- package/dist/lib/services/conversation-data.service.d.ts +15 -1
- package/dist/lib/services/conversation-data.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-data.service.js +23 -1
- package/dist/lib/services/conversation-data.service.js.map +1 -1
- package/dist/lib/services/conversation-streaming.service.d.ts +50 -1
- package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-streaming.service.js +92 -4
- package/dist/lib/services/conversation-streaming.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +15 -0
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +30 -0
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +17 -17
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ViewChild, ViewChildren } from '@angular/core';
|
|
2
2
|
import { RunView, RunQuery, Metadata, CompositeKey, LogStatusEx } from '@memberjunction/core';
|
|
3
|
+
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
3
4
|
import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
|
|
4
5
|
import { parseConversationDetailComplete } from '../../models/conversation-complete-query.model';
|
|
5
6
|
import { ArtifactViewerPanelComponent } from '@memberjunction/ng-artifacts';
|
|
6
7
|
import { TestFeedbackDialogComponent } from '@memberjunction/ng-testing';
|
|
7
8
|
import { Subject } from 'rxjs';
|
|
9
|
+
import { takeUntil } from 'rxjs/operators';
|
|
8
10
|
import * as i0 from "@angular/core";
|
|
9
11
|
import * as i1 from "../../services/conversation-data.service";
|
|
10
12
|
import * as i2 from "../../services/agent-state.service";
|
|
@@ -13,30 +15,40 @@ import * as i4 from "../../services/active-tasks.service";
|
|
|
13
15
|
import * as i5 from "../../services/mention-autocomplete.service";
|
|
14
16
|
import * as i6 from "../../services/artifact-permission.service";
|
|
15
17
|
import * as i7 from "@progress/kendo-angular-dialog";
|
|
16
|
-
import * as i8 from "
|
|
17
|
-
import * as i9 from "
|
|
18
|
-
import * as i10 from "@
|
|
19
|
-
import * as i11 from "
|
|
20
|
-
import * as i12 from "
|
|
21
|
-
import * as i13 from "../
|
|
22
|
-
import * as i14 from "../
|
|
23
|
-
import * as i15 from "
|
|
24
|
-
import * as i16 from "../
|
|
25
|
-
import * as i17 from "
|
|
26
|
-
import * as i18 from "../
|
|
27
|
-
import * as i19 from "../
|
|
28
|
-
import * as i20 from "../
|
|
18
|
+
import * as i8 from "../../services/conversation-attachment.service";
|
|
19
|
+
import * as i9 from "../../services/conversation-streaming.service";
|
|
20
|
+
import * as i10 from "@angular/common";
|
|
21
|
+
import * as i11 from "@memberjunction/ng-artifacts";
|
|
22
|
+
import * as i12 from "@memberjunction/ng-shared-generic";
|
|
23
|
+
import * as i13 from "../collection/artifact-collection-picker-modal.component";
|
|
24
|
+
import * as i14 from "../artifact/artifact-share-modal.component";
|
|
25
|
+
import * as i15 from "../message/message-list.component";
|
|
26
|
+
import * as i16 from "../message/message-input.component";
|
|
27
|
+
import * as i17 from "./conversation-empty-state.component";
|
|
28
|
+
import * as i18 from "../thread/thread-panel.component";
|
|
29
|
+
import * as i19 from "../project/project-selector.component";
|
|
30
|
+
import * as i20 from "../agent/active-agent-indicator.component";
|
|
31
|
+
import * as i21 from "../members/members-modal.component";
|
|
32
|
+
import * as i22 from "../export/export-modal.component";
|
|
33
|
+
import * as i23 from "../attachment/image-viewer.component";
|
|
29
34
|
const _c0 = ["scrollContainer"];
|
|
30
35
|
const _c1 = ["messageInput"];
|
|
31
36
|
const _forTrack0 = ($index, $item) => $item.conversationId;
|
|
32
37
|
const _forTrack1 = ($index, $item) => $item.artifactId;
|
|
33
38
|
const _forTrack2 = ($index, $item) => $item.versionId;
|
|
34
39
|
const _c2 = () => [];
|
|
35
|
-
function
|
|
40
|
+
function ConversationChatAreaComponent_div_1_button_2_Template(rf, ctx) { if (rf & 1) {
|
|
36
41
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
37
|
-
i0.ɵɵelementStart(0, "button",
|
|
38
|
-
i0.ɵɵlistener("click", function
|
|
39
|
-
i0.ɵɵelement(1, "i",
|
|
42
|
+
i0.ɵɵelementStart(0, "button", 32);
|
|
43
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.sidebarToggleClicked.emit()); });
|
|
44
|
+
i0.ɵɵelement(1, "i", 33);
|
|
45
|
+
i0.ɵɵelementEnd();
|
|
46
|
+
} }
|
|
47
|
+
function ConversationChatAreaComponent_div_1_button_5_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
49
|
+
i0.ɵɵelementStart(0, "button", 34);
|
|
50
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openProjectSelector()); });
|
|
51
|
+
i0.ɵɵelement(1, "i", 35);
|
|
40
52
|
i0.ɵɵelementStart(2, "span");
|
|
41
53
|
i0.ɵɵtext(3);
|
|
42
54
|
i0.ɵɵelementEnd()();
|
|
@@ -45,21 +57,21 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
|
|
|
45
57
|
i0.ɵɵadvance(3);
|
|
46
58
|
i0.ɵɵtextInterpolate(ctx_r2.conversation.Project || "Project");
|
|
47
59
|
} }
|
|
48
|
-
function
|
|
49
|
-
const
|
|
50
|
-
i0.ɵɵelementStart(0, "button",
|
|
51
|
-
i0.ɵɵlistener("click", function
|
|
52
|
-
i0.ɵɵelement(1, "i",
|
|
60
|
+
function ConversationChatAreaComponent_div_1_button_6_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
62
|
+
i0.ɵɵelementStart(0, "button", 36);
|
|
63
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewTestRun(ctx_r2.conversation.TestRunID)); });
|
|
64
|
+
i0.ɵɵelement(1, "i", 37);
|
|
53
65
|
i0.ɵɵelementStart(2, "span");
|
|
54
66
|
i0.ɵɵtext(3, "Test");
|
|
55
67
|
i0.ɵɵelementEnd()();
|
|
56
68
|
} }
|
|
57
|
-
function
|
|
58
|
-
const
|
|
59
|
-
i0.ɵɵelementStart(0, "button",
|
|
60
|
-
i0.ɵɵlistener("click", function
|
|
61
|
-
i0.ɵɵelement(1, "i",
|
|
62
|
-
i0.ɵɵelementStart(2, "span",
|
|
69
|
+
function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf & 1) {
|
|
70
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
71
|
+
i0.ɵɵelementStart(0, "button", 38);
|
|
72
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewArtifacts()); });
|
|
73
|
+
i0.ɵɵelement(1, "i", 39);
|
|
74
|
+
i0.ɵɵelementStart(2, "span", 40);
|
|
63
75
|
i0.ɵɵtext(3);
|
|
64
76
|
i0.ɵɵelementEnd()();
|
|
65
77
|
} if (rf & 2) {
|
|
@@ -67,12 +79,12 @@ function ConversationChatAreaComponent_div_1_button_8_Template(rf, ctx) { if (rf
|
|
|
67
79
|
i0.ɵɵadvance(3);
|
|
68
80
|
i0.ɵɵtextInterpolate(ctx_r2.artifactCountDisplay);
|
|
69
81
|
} }
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
i0.ɵɵelementStart(0, "button",
|
|
73
|
-
i0.ɵɵlistener("click", function
|
|
74
|
-
i0.ɵɵelement(1, "i",
|
|
75
|
-
i0.ɵɵelementStart(2, "span",
|
|
82
|
+
function ConversationChatAreaComponent_div_1_button_10_Template(rf, ctx) { if (rf & 1) {
|
|
83
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
84
|
+
i0.ɵɵelementStart(0, "button", 41);
|
|
85
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleMembersModal()); });
|
|
86
|
+
i0.ɵɵelement(1, "i", 42);
|
|
87
|
+
i0.ɵɵelementStart(2, "span", 43);
|
|
76
88
|
i0.ɵɵtext(3);
|
|
77
89
|
i0.ɵɵelementEnd()();
|
|
78
90
|
} if (rf & 2) {
|
|
@@ -82,33 +94,39 @@ function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf
|
|
|
82
94
|
} }
|
|
83
95
|
function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
84
96
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
85
|
-
i0.ɵɵelementStart(0, "div",
|
|
86
|
-
i0.ɵɵ
|
|
97
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "div", 18);
|
|
98
|
+
i0.ɵɵtemplate(2, ConversationChatAreaComponent_div_1_button_2_Template, 2, 0, "button", 19);
|
|
99
|
+
i0.ɵɵelementStart(3, "div", 20);
|
|
100
|
+
i0.ɵɵtext(4);
|
|
87
101
|
i0.ɵɵelementEnd();
|
|
88
|
-
i0.ɵɵtemplate(
|
|
89
|
-
i0.ɵɵelementStart(
|
|
90
|
-
i0.ɵɵlistener("togglePanel", function
|
|
102
|
+
i0.ɵɵtemplate(5, ConversationChatAreaComponent_div_1_button_5_Template, 4, 1, "button", 21)(6, ConversationChatAreaComponent_div_1_button_6_Template, 4, 0, "button", 22);
|
|
103
|
+
i0.ɵɵelementStart(7, "mj-active-agent-indicator", 23);
|
|
104
|
+
i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_7_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
|
|
91
105
|
i0.ɵɵelementEnd()();
|
|
92
|
-
i0.ɵɵelementStart(
|
|
93
|
-
i0.ɵɵtemplate(
|
|
94
|
-
i0.ɵɵelementStart(
|
|
95
|
-
i0.ɵɵlistener("click", function
|
|
96
|
-
i0.ɵɵelement(
|
|
97
|
-
i0.ɵɵelementStart(
|
|
98
|
-
i0.ɵɵtext(
|
|
106
|
+
i0.ɵɵelementStart(8, "div", 24);
|
|
107
|
+
i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 1, "button", 25)(10, ConversationChatAreaComponent_div_1_button_10_Template, 4, 1, "button", 26);
|
|
108
|
+
i0.ɵɵelementStart(11, "button", 27);
|
|
109
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.exportConversation()); });
|
|
110
|
+
i0.ɵɵelement(12, "i", 28);
|
|
111
|
+
i0.ɵɵelementStart(13, "span", 29);
|
|
112
|
+
i0.ɵɵtext(14, "Export");
|
|
99
113
|
i0.ɵɵelementEnd()();
|
|
100
|
-
i0.ɵɵelementStart(
|
|
101
|
-
i0.ɵɵlistener("click", function
|
|
102
|
-
i0.ɵɵelement(
|
|
103
|
-
i0.ɵɵelementStart(
|
|
104
|
-
i0.ɵɵtext(
|
|
114
|
+
i0.ɵɵelementStart(15, "button", 30);
|
|
115
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.shareConversation()); });
|
|
116
|
+
i0.ɵɵelement(16, "i", 31);
|
|
117
|
+
i0.ɵɵelementStart(17, "span", 29);
|
|
118
|
+
i0.ɵɵtext(18, "Share");
|
|
105
119
|
i0.ɵɵelementEnd()();
|
|
106
|
-
i0.ɵɵelementStart(
|
|
107
|
-
i0.ɵɵlistener("togglePanel", function
|
|
120
|
+
i0.ɵɵelementStart(19, "mj-active-agent-indicator", 23);
|
|
121
|
+
i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_19_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_19_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
|
|
108
122
|
i0.ɵɵelementEnd()()();
|
|
109
123
|
} if (rf & 2) {
|
|
110
124
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
111
|
-
i0.ɵɵadvance(
|
|
125
|
+
i0.ɵɵadvance();
|
|
126
|
+
i0.ɵɵclassProp("with-sidebar-toggle", ctx_r2.showSidebarToggle);
|
|
127
|
+
i0.ɵɵadvance();
|
|
128
|
+
i0.ɵɵproperty("ngIf", ctx_r2.showSidebarToggle);
|
|
129
|
+
i0.ɵɵadvance(2);
|
|
112
130
|
i0.ɵɵtextInterpolate(ctx_r2.conversation.Name);
|
|
113
131
|
i0.ɵɵadvance();
|
|
114
132
|
i0.ɵɵproperty("ngIf", ctx_r2.conversation.ProjectID);
|
|
@@ -127,44 +145,53 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
127
145
|
i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
|
|
128
146
|
} }
|
|
129
147
|
function ConversationChatAreaComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
-
const
|
|
131
|
-
i0.ɵɵelementStart(0, "mj-conversation-empty-state",
|
|
132
|
-
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(
|
|
148
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
149
|
+
i0.ɵɵelementStart(0, "mj-conversation-empty-state", 44);
|
|
150
|
+
i0.ɵɵlistener("sidebarToggleClicked", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_sidebarToggleClicked_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.sidebarToggleClicked.emit()); })("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEmptyStateMessageSent($event)); });
|
|
133
151
|
i0.ɵɵelementEnd();
|
|
134
152
|
} if (rf & 2) {
|
|
135
153
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
136
|
-
i0.ɵɵproperty("currentUser", ctx_r2.currentUser)("disabled", ctx_r2.isProcessing);
|
|
154
|
+
i0.ɵɵproperty("currentUser", ctx_r2.currentUser)("disabled", ctx_r2.isProcessing)("showSidebarToggle", ctx_r2.showSidebarToggle);
|
|
137
155
|
} }
|
|
138
156
|
function ConversationChatAreaComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
139
157
|
i0.ɵɵelementStart(0, "div", 7);
|
|
140
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
158
|
+
i0.ɵɵelement(1, "mj-loading", 45);
|
|
141
159
|
i0.ɵɵelementEnd();
|
|
142
160
|
} }
|
|
143
|
-
function
|
|
144
|
-
const _r9 = i0.ɵɵgetCurrentView();
|
|
145
|
-
i0.ɵɵelementStart(0, "span", 48);
|
|
146
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_4_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.scrollToBottomAnimate()); });
|
|
147
|
-
i0.ɵɵelement(1, "i", 49);
|
|
148
|
-
i0.ɵɵelementEnd();
|
|
149
|
-
} }
|
|
150
|
-
function ConversationChatAreaComponent_Conditional_6_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
161
|
+
function ConversationChatAreaComponent_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
151
162
|
i0.ɵɵelementStart(0, "div", 46);
|
|
152
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
163
|
+
i0.ɵɵelement(1, "mj-loading", 53);
|
|
153
164
|
i0.ɵɵelementEnd();
|
|
165
|
+
} if (rf & 2) {
|
|
166
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
167
|
+
i0.ɵɵadvance();
|
|
168
|
+
i0.ɵɵproperty("text", ctx_r2.uploadingMessage);
|
|
154
169
|
} }
|
|
155
|
-
function
|
|
170
|
+
function ConversationChatAreaComponent_Conditional_6_span_5_Template(rf, ctx) { if (rf & 1) {
|
|
156
171
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
157
|
-
i0.ɵɵelementStart(0, "
|
|
158
|
-
i0.ɵɵlistener("
|
|
172
|
+
i0.ɵɵelementStart(0, "span", 54);
|
|
173
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_5_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.scrollToBottomAnimate()); });
|
|
174
|
+
i0.ɵɵelement(1, "i", 55);
|
|
175
|
+
i0.ɵɵelementEnd();
|
|
176
|
+
} }
|
|
177
|
+
function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
178
|
+
i0.ɵɵelementStart(0, "div", 51);
|
|
179
|
+
i0.ɵɵelement(1, "mj-loading", 56);
|
|
180
|
+
i0.ɵɵelementEnd();
|
|
181
|
+
} }
|
|
182
|
+
function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
183
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
184
|
+
i0.ɵɵelementStart(0, "mj-message-input", 58, 1);
|
|
185
|
+
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_intentCheckStarted_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckStarted()); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_intentCheckCompleted_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckCompleted()); })("uploadStateChanged", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_uploadStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onUploadStateChanged($event)); });
|
|
159
186
|
i0.ɵɵelementEnd();
|
|
160
187
|
} if (rf & 2) {
|
|
161
|
-
const
|
|
188
|
+
const inputRef_r12 = ctx.$implicit;
|
|
162
189
|
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
163
|
-
i0.ɵɵproperty("hidden",
|
|
190
|
+
i0.ɵɵproperty("hidden", inputRef_r12.conversationId !== ctx_r2.conversationId)("conversationId", inputRef_r12.conversationId)("conversationName", inputRef_r12.conversationName)("currentUser", ctx_r2.currentUser)("conversationHistory", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.messages : i0.ɵɵpureFunction0(16, _c2))("artifactsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.artifactsByDetailId : ctx_r2.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.systemArtifactsByDetailId : ctx_r2.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.agentRunsByDetailId : ctx_r2.emptyAgentRunsMap)("inProgressMessageIds", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.inProgressMessageIds : ctx_r2.emptyInProgressIds)("disabled", ctx_r2.isProcessing)("enableAttachments", ctx_r2.enableAttachments)("maxAttachments", ctx_r2.maxAttachments)("maxAttachmentSizeBytes", ctx_r2.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r2.acceptedFileTypes)("initialMessage", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.pendingMessage : null)("initialAttachments", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.pendingAttachments : null);
|
|
164
191
|
} }
|
|
165
|
-
function
|
|
166
|
-
i0.ɵɵelementStart(0, "div",
|
|
167
|
-
i0.ɵɵrepeaterCreate(1,
|
|
192
|
+
function ConversationChatAreaComponent_Conditional_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
193
|
+
i0.ɵɵelementStart(0, "div", 52);
|
|
194
|
+
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template, 2, 17, "mj-message-input", 57, _forTrack0);
|
|
168
195
|
i0.ɵɵelementEnd();
|
|
169
196
|
} if (rf & 2) {
|
|
170
197
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -172,37 +199,41 @@ function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf,
|
|
|
172
199
|
i0.ɵɵrepeater(ctx_r2.getCachedInputs());
|
|
173
200
|
} }
|
|
174
201
|
function ConversationChatAreaComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
175
|
-
const
|
|
176
|
-
i0.ɵɵelementStart(0, "div", 8)
|
|
177
|
-
i0.ɵɵ
|
|
178
|
-
i0.ɵɵelementStart(
|
|
179
|
-
i0.ɵɵlistener("
|
|
202
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
203
|
+
i0.ɵɵelementStart(0, "div", 8);
|
|
204
|
+
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_6_Conditional_1_Template, 2, 1, "div", 46);
|
|
205
|
+
i0.ɵɵelementStart(2, "div", 47, 0);
|
|
206
|
+
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_6_Template_div_scroll_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.checkScroll()); });
|
|
207
|
+
i0.ɵɵelementStart(4, "mj-conversation-message-list", 48);
|
|
208
|
+
i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_replyInThread_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_viewThread_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_retryMessage_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRetryMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_testFeedbackMessage_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_artifactClicked_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_messageEdited_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_openEntityRecord_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_suggestedResponseSelected_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSuggestedResponseSelected($event)); })("attachmentClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_attachmentClicked_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAttachmentClicked($event)); });
|
|
180
209
|
i0.ɵɵelementEnd();
|
|
181
|
-
i0.ɵɵtemplate(
|
|
210
|
+
i0.ɵɵtemplate(5, ConversationChatAreaComponent_Conditional_6_span_5_Template, 2, 0, "span", 49);
|
|
182
211
|
i0.ɵɵelementEnd();
|
|
183
|
-
i0.ɵɵelementStart(
|
|
184
|
-
i0.ɵɵtemplate(
|
|
212
|
+
i0.ɵɵelementStart(6, "div", 50);
|
|
213
|
+
i0.ɵɵtemplate(7, ConversationChatAreaComponent_Conditional_6_Conditional_7_Template, 2, 0, "div", 51)(8, ConversationChatAreaComponent_Conditional_6_Conditional_8_Template, 3, 0, "div", 52);
|
|
185
214
|
i0.ɵɵelementEnd()();
|
|
186
215
|
} if (rf & 2) {
|
|
187
216
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
217
|
+
i0.ɵɵadvance();
|
|
218
|
+
i0.ɵɵconditional(ctx_r2.isUploadingAttachments ? 1 : -1);
|
|
188
219
|
i0.ɵɵadvance(3);
|
|
189
|
-
i0.ɵɵproperty("messages", ctx_r2.messages)("conversation", ctx_r2.conversation)("currentUser", ctx_r2.currentUser)("isProcessing", ctx_r2.isProcessing)("artifactMap", ctx_r2.effectiveArtifactsMap)("agentRunMap", ctx_r2.agentRunsByDetailId)("ratingsMap", ctx_r2.ratingsByDetailId)("userAvatarMap", ctx_r2.userAvatarMap);
|
|
220
|
+
i0.ɵɵproperty("messages", ctx_r2.messages)("conversation", ctx_r2.conversation)("currentUser", ctx_r2.currentUser)("isProcessing", ctx_r2.isProcessing)("artifactMap", ctx_r2.effectiveArtifactsMap)("agentRunMap", ctx_r2.agentRunsByDetailId)("ratingsMap", ctx_r2.ratingsByDetailId)("userAvatarMap", ctx_r2.userAvatarMap)("attachmentsMap", ctx_r2.attachmentsByDetailId);
|
|
190
221
|
i0.ɵɵadvance();
|
|
191
222
|
i0.ɵɵproperty("ngIf", ctx_r2.showScrollToBottomIcon && ctx_r2.messages && ctx_r2.messages.length > 0);
|
|
192
223
|
i0.ɵɵadvance(2);
|
|
193
|
-
i0.ɵɵconditional(ctx_r2.isLoadingPeripheralData ?
|
|
224
|
+
i0.ɵɵconditional(ctx_r2.isLoadingPeripheralData ? 7 : 8);
|
|
194
225
|
} }
|
|
195
226
|
function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
196
|
-
const
|
|
197
|
-
i0.ɵɵelementStart(0, "div",
|
|
198
|
-
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(
|
|
227
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
228
|
+
i0.ɵɵelementStart(0, "div", 62);
|
|
229
|
+
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeTouchStart($event)); });
|
|
199
230
|
i0.ɵɵelementEnd();
|
|
200
231
|
} }
|
|
201
232
|
function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
202
|
-
const
|
|
203
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_7_Conditional_0_Template, 1, 0, "div",
|
|
204
|
-
i0.ɵɵelementStart(1, "div",
|
|
205
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(
|
|
233
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
234
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_7_Conditional_0_Template, 1, 0, "div", 59);
|
|
235
|
+
i0.ɵɵelementStart(1, "div", 60)(2, "mj-artifact-viewer-panel", 61);
|
|
236
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSaveToCollectionRequested($event)); })("navigateToLink", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_navigateToLink_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactLinkNavigation($event)); })("shareRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_shareRequested_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactShareRequested($event)); })("maximizeToggled", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_maximizeToggled_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMaximizeArtifactPane()); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_openEntityRecord_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
|
|
206
237
|
i0.ɵɵelementEnd()();
|
|
207
238
|
} if (rf & 2) {
|
|
208
239
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -214,29 +245,29 @@ function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf
|
|
|
214
245
|
i0.ɵɵproperty("artifactId", ctx_r2.selectedArtifactId)("currentUser", ctx_r2.currentUser)("environmentId", ctx_r2.environmentId)("versionNumber", ctx_r2.selectedVersionNumber)("viewContext", "conversation")("canShare", ctx_r2.canShareSelectedArtifact)("canEdit", ctx_r2.canEditSelectedArtifact)("isMaximized", ctx_r2.isArtifactPaneMaximized)("refreshTrigger", ctx_r2.artifactViewerRefresh$);
|
|
215
246
|
} }
|
|
216
247
|
function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
217
|
-
const
|
|
218
|
-
i0.ɵɵelementStart(0, "mj-thread-panel",
|
|
219
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(
|
|
248
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
249
|
+
i0.ɵɵelementStart(0, "mj-thread-panel", 63);
|
|
250
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLocalThreadClosed()); })("replyAdded", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onThreadReplyAdded($event)); });
|
|
220
251
|
i0.ɵɵelementEnd();
|
|
221
252
|
} if (rf & 2) {
|
|
222
253
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
223
254
|
i0.ɵɵproperty("parentMessageId", ctx_r2.threadId)("conversationId", ctx_r2.conversationId || "")("currentUser", ctx_r2.currentUser);
|
|
224
255
|
} }
|
|
225
256
|
function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
226
|
-
const
|
|
227
|
-
i0.ɵɵelementStart(0, "div",
|
|
228
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
229
|
-
i0.ɵɵelementStart(1, "div",
|
|
230
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
231
|
-
i0.ɵɵelementStart(2, "div",
|
|
257
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
258
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
259
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
|
|
260
|
+
i0.ɵɵelementStart(1, "div", 65);
|
|
261
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r16); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
262
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3");
|
|
232
263
|
i0.ɵɵtext(4, "Assign Project");
|
|
233
264
|
i0.ɵɵelementEnd();
|
|
234
|
-
i0.ɵɵelementStart(5, "button",
|
|
235
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(
|
|
236
|
-
i0.ɵɵelement(6, "i",
|
|
265
|
+
i0.ɵɵelementStart(5, "button", 67);
|
|
266
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
|
|
267
|
+
i0.ɵɵelement(6, "i", 68);
|
|
237
268
|
i0.ɵɵelementEnd()();
|
|
238
|
-
i0.ɵɵelementStart(7, "div",
|
|
239
|
-
i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(
|
|
269
|
+
i0.ɵɵelementStart(7, "div", 69)(8, "mj-project-selector", 70);
|
|
270
|
+
i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onProjectSelected($event)); });
|
|
240
271
|
i0.ɵɵelementEnd()()()();
|
|
241
272
|
} if (rf & 2) {
|
|
242
273
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -244,10 +275,10 @@ function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf
|
|
|
244
275
|
i0.ɵɵproperty("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("selectedProjectId", ctx_r2.conversation.ProjectID);
|
|
245
276
|
} }
|
|
246
277
|
function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
247
|
-
const
|
|
248
|
-
i0.ɵɵelementStart(0, "button",
|
|
249
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
250
|
-
i0.ɵɵelement(1, "i",
|
|
278
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
279
|
+
i0.ɵɵelementStart(0, "button", 77);
|
|
280
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleSystemArtifacts()); });
|
|
281
|
+
i0.ɵɵelement(1, "i", 78);
|
|
251
282
|
i0.ɵɵelementStart(2, "span");
|
|
252
283
|
i0.ɵɵtext(3);
|
|
253
284
|
i0.ɵɵelementEnd()();
|
|
@@ -258,109 +289,109 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template(rf,
|
|
|
258
289
|
i0.ɵɵtextInterpolate1("", ctx_r2.showSystemArtifacts ? "Hide" : "Show", " System");
|
|
259
290
|
} }
|
|
260
291
|
function ConversationChatAreaComponent_Conditional_13_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
261
|
-
i0.ɵɵelementStart(0, "div",
|
|
262
|
-
i0.ɵɵelement(1, "i",
|
|
263
|
-
i0.ɵɵelementStart(2, "p",
|
|
292
|
+
i0.ɵɵelementStart(0, "div", 75);
|
|
293
|
+
i0.ɵɵelement(1, "i", 79);
|
|
294
|
+
i0.ɵɵelementStart(2, "p", 80);
|
|
264
295
|
i0.ɵɵtext(3, "No artifacts in this conversation yet");
|
|
265
296
|
i0.ɵɵelementEnd()();
|
|
266
297
|
} }
|
|
267
298
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
268
299
|
i0.ɵɵtext(0);
|
|
269
300
|
} if (rf & 2) {
|
|
270
|
-
const
|
|
271
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
301
|
+
const artifact_r20 = i0.ɵɵnextContext().$implicit;
|
|
302
|
+
i0.ɵɵtextInterpolate1(" ", artifact_r20.versionCount, " versions ");
|
|
272
303
|
} }
|
|
273
304
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
274
305
|
i0.ɵɵtext(0, " 1 version ");
|
|
275
306
|
} }
|
|
276
307
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
277
|
-
const
|
|
278
|
-
i0.ɵɵelementStart(0, "button",
|
|
279
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
280
|
-
i0.ɵɵelement(1, "i",
|
|
308
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
309
|
+
i0.ɵɵelementStart(0, "button", 92);
|
|
310
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r21); const artifact_r20 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleArtifactExpansion(artifact_r20.artifactId, $event)); });
|
|
311
|
+
i0.ɵɵelement(1, "i", 93);
|
|
281
312
|
i0.ɵɵelementEnd();
|
|
282
313
|
} if (rf & 2) {
|
|
283
|
-
const
|
|
314
|
+
const artifact_r20 = i0.ɵɵnextContext().$implicit;
|
|
284
315
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
285
316
|
i0.ɵɵadvance();
|
|
286
|
-
i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !==
|
|
317
|
+
i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !== artifact_r20.artifactId)("fa-chevron-up", ctx_r2.expandedArtifactId === artifact_r20.artifactId);
|
|
287
318
|
} }
|
|
288
319
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
289
|
-
const
|
|
290
|
-
i0.ɵɵelementStart(0, "div",
|
|
291
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const
|
|
292
|
-
i0.ɵɵelementStart(1, "span",
|
|
320
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
321
|
+
i0.ɵɵelementStart(0, "div", 95);
|
|
322
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r23 = i0.ɵɵrestoreView(_r22).$implicit; const artifact_r20 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openArtifactFromModal(artifact_r20.artifactId, version_r23.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
323
|
+
i0.ɵɵelementStart(1, "span", 96);
|
|
293
324
|
i0.ɵɵtext(2);
|
|
294
325
|
i0.ɵɵelementEnd();
|
|
295
|
-
i0.ɵɵelementStart(3, "span",
|
|
326
|
+
i0.ɵɵelementStart(3, "span", 97);
|
|
296
327
|
i0.ɵɵtext(4, "Open this version");
|
|
297
328
|
i0.ɵɵelementEnd();
|
|
298
|
-
i0.ɵɵelement(5, "i",
|
|
329
|
+
i0.ɵɵelement(5, "i", 98);
|
|
299
330
|
i0.ɵɵelementEnd();
|
|
300
331
|
} if (rf & 2) {
|
|
301
|
-
const
|
|
332
|
+
const version_r23 = ctx.$implicit;
|
|
302
333
|
i0.ɵɵadvance(2);
|
|
303
|
-
i0.ɵɵtextInterpolate1("v",
|
|
334
|
+
i0.ɵɵtextInterpolate1("v", version_r23.versionNumber, "");
|
|
304
335
|
} }
|
|
305
336
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
306
|
-
i0.ɵɵelementStart(0, "div",
|
|
307
|
-
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template, 6, 1, "div",
|
|
337
|
+
i0.ɵɵelementStart(0, "div", 91);
|
|
338
|
+
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template, 6, 1, "div", 94, _forTrack2);
|
|
308
339
|
i0.ɵɵelementEnd();
|
|
309
340
|
} if (rf & 2) {
|
|
310
|
-
const
|
|
341
|
+
const artifact_r20 = i0.ɵɵnextContext().$implicit;
|
|
311
342
|
i0.ɵɵadvance();
|
|
312
|
-
i0.ɵɵrepeater(
|
|
343
|
+
i0.ɵɵrepeater(artifact_r20.versions);
|
|
313
344
|
} }
|
|
314
345
|
function ConversationChatAreaComponent_Conditional_13_For_12_Template(rf, ctx) { if (rf & 1) {
|
|
315
|
-
const
|
|
316
|
-
i0.ɵɵelementStart(0, "div",
|
|
317
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const
|
|
318
|
-
i0.ɵɵelementStart(2, "div",
|
|
319
|
-
i0.ɵɵelement(3, "i",
|
|
346
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
347
|
+
i0.ɵɵelementStart(0, "div", 81)(1, "div", 82);
|
|
348
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const artifact_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openArtifactFromModal(artifact_r20.artifactId)); });
|
|
349
|
+
i0.ɵɵelementStart(2, "div", 83);
|
|
350
|
+
i0.ɵɵelement(3, "i", 84);
|
|
320
351
|
i0.ɵɵelementEnd();
|
|
321
|
-
i0.ɵɵelementStart(4, "div",
|
|
352
|
+
i0.ɵɵelementStart(4, "div", 85)(5, "div", 86);
|
|
322
353
|
i0.ɵɵtext(6);
|
|
323
354
|
i0.ɵɵelementEnd();
|
|
324
|
-
i0.ɵɵelementStart(7, "div",
|
|
355
|
+
i0.ɵɵelementStart(7, "div", 87);
|
|
325
356
|
i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_9_Template, 1, 0);
|
|
326
357
|
i0.ɵɵelementEnd()();
|
|
327
|
-
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template, 2, 4, "button",
|
|
328
|
-
i0.ɵɵelementStart(11, "div",
|
|
329
|
-
i0.ɵɵelement(12, "i",
|
|
358
|
+
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template, 2, 4, "button", 88);
|
|
359
|
+
i0.ɵɵelementStart(11, "div", 89);
|
|
360
|
+
i0.ɵɵelement(12, "i", 90);
|
|
330
361
|
i0.ɵɵelementEnd()();
|
|
331
|
-
i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template, 3, 0, "div",
|
|
362
|
+
i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template, 3, 0, "div", 91);
|
|
332
363
|
i0.ɵɵelementEnd();
|
|
333
364
|
} if (rf & 2) {
|
|
334
|
-
const
|
|
365
|
+
const artifact_r20 = ctx.$implicit;
|
|
335
366
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
336
|
-
i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId ===
|
|
367
|
+
i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId === artifact_r20.artifactId)("system-artifact", artifact_r20.visibility === "System Only");
|
|
337
368
|
i0.ɵɵadvance(6);
|
|
338
|
-
i0.ɵɵtextInterpolate(
|
|
369
|
+
i0.ɵɵtextInterpolate(artifact_r20.name);
|
|
339
370
|
i0.ɵɵadvance(2);
|
|
340
|
-
i0.ɵɵconditional(
|
|
371
|
+
i0.ɵɵconditional(artifact_r20.versionCount > 1 ? 8 : 9);
|
|
341
372
|
i0.ɵɵadvance(2);
|
|
342
|
-
i0.ɵɵconditional(
|
|
373
|
+
i0.ɵɵconditional(artifact_r20.versionCount > 1 ? 10 : -1);
|
|
343
374
|
i0.ɵɵadvance(3);
|
|
344
|
-
i0.ɵɵconditional(ctx_r2.expandedArtifactId ===
|
|
375
|
+
i0.ɵɵconditional(ctx_r2.expandedArtifactId === artifact_r20.artifactId && artifact_r20.versionCount > 1 ? 13 : -1);
|
|
345
376
|
} }
|
|
346
377
|
function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
347
|
-
const
|
|
348
|
-
i0.ɵɵelementStart(0, "div",
|
|
349
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
350
|
-
i0.ɵɵelementStart(1, "div",
|
|
351
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
352
|
-
i0.ɵɵelementStart(2, "div",
|
|
378
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
379
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
380
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
|
|
381
|
+
i0.ɵɵelementStart(1, "div", 71);
|
|
382
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r17); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
383
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3");
|
|
353
384
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
354
385
|
i0.ɵɵelementEnd();
|
|
355
|
-
i0.ɵɵelementStart(5, "div",
|
|
356
|
-
i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_13_Conditional_6_Template, 4, 3, "button",
|
|
357
|
-
i0.ɵɵelementStart(7, "button",
|
|
358
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(
|
|
359
|
-
i0.ɵɵelement(8, "i",
|
|
386
|
+
i0.ɵɵelementStart(5, "div", 72);
|
|
387
|
+
i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_13_Conditional_6_Template, 4, 3, "button", 73);
|
|
388
|
+
i0.ɵɵelementStart(7, "button", 67);
|
|
389
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
|
|
390
|
+
i0.ɵɵelement(8, "i", 68);
|
|
360
391
|
i0.ɵɵelementEnd()()();
|
|
361
|
-
i0.ɵɵelementStart(9, "div",
|
|
362
|
-
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_Conditional_10_Template, 4, 0, "div",
|
|
363
|
-
i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_13_For_12_Template, 14, 8, "div",
|
|
392
|
+
i0.ɵɵelementStart(9, "div", 74);
|
|
393
|
+
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_Conditional_10_Template, 4, 0, "div", 75);
|
|
394
|
+
i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_13_For_12_Template, 14, 8, "div", 76, _forTrack1);
|
|
364
395
|
i0.ɵɵelementEnd()()();
|
|
365
396
|
} if (rf & 2) {
|
|
366
397
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -372,14 +403,23 @@ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf
|
|
|
372
403
|
i0.ɵɵrepeater(ctx_r2.getArtifactsArray());
|
|
373
404
|
} }
|
|
374
405
|
function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
375
|
-
const
|
|
376
|
-
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal",
|
|
377
|
-
i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(
|
|
406
|
+
const _r24 = i0.ɵɵgetCurrentView();
|
|
407
|
+
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 99);
|
|
408
|
+
i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerSaved($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerCancelled()); });
|
|
378
409
|
i0.ɵɵelementEnd();
|
|
379
410
|
} if (rf & 2) {
|
|
380
411
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
381
412
|
i0.ɵɵproperty("isOpen", ctx_r2.showCollectionPicker)("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("excludeCollectionIds", ctx_r2.collectionPickerExcludedIds);
|
|
382
413
|
} }
|
|
414
|
+
function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
415
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
416
|
+
i0.ɵɵelementStart(0, "mj-image-viewer", 100);
|
|
417
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_15_Template_mj_image_viewer_closed_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onImageViewerClosed()); });
|
|
418
|
+
i0.ɵɵelementEnd();
|
|
419
|
+
} if (rf & 2) {
|
|
420
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
421
|
+
i0.ɵɵproperty("imageUrl", ctx_r2.selectedImageUrl)("alt", ctx_r2.selectedImageAlt)("fileName", ctx_r2.selectedImageFileName)("visible", ctx_r2.showImageViewer);
|
|
422
|
+
} }
|
|
383
423
|
export class ConversationChatAreaComponent {
|
|
384
424
|
conversationData;
|
|
385
425
|
agentStateService;
|
|
@@ -389,6 +429,8 @@ export class ConversationChatAreaComponent {
|
|
|
389
429
|
mentionAutocompleteService;
|
|
390
430
|
artifactPermissionService;
|
|
391
431
|
dialogService;
|
|
432
|
+
attachmentService;
|
|
433
|
+
streamingService;
|
|
392
434
|
environmentId;
|
|
393
435
|
currentUser;
|
|
394
436
|
// LOCAL STATE INPUTS - passed from parent workspace
|
|
@@ -409,19 +451,45 @@ export class ConversationChatAreaComponent {
|
|
|
409
451
|
conversation = null;
|
|
410
452
|
threadId = null;
|
|
411
453
|
isNewConversation = false;
|
|
412
|
-
|
|
454
|
+
// Using getter/setter to ensure correct type handling
|
|
455
|
+
_pendingMessage = null;
|
|
456
|
+
set pendingMessage(value) {
|
|
457
|
+
// Handle case where an object is incorrectly passed
|
|
458
|
+
if (value && typeof value === 'object' && 'text' in value) {
|
|
459
|
+
this._pendingMessage = value.text;
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
this._pendingMessage = value;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
get pendingMessage() {
|
|
466
|
+
return this._pendingMessage;
|
|
467
|
+
}
|
|
468
|
+
// Using getter/setter to ensure reactivity
|
|
469
|
+
_pendingAttachments = null;
|
|
470
|
+
set pendingAttachments(value) {
|
|
471
|
+
this._pendingAttachments = value;
|
|
472
|
+
}
|
|
473
|
+
get pendingAttachments() {
|
|
474
|
+
return this._pendingAttachments;
|
|
475
|
+
}
|
|
413
476
|
pendingArtifactId = null;
|
|
414
477
|
pendingArtifactVersionNumber = null;
|
|
478
|
+
// Sidebar toggle - when true, shows toggle button in header to expand sidebar
|
|
479
|
+
showSidebarToggle = false;
|
|
415
480
|
conversationRenamed = new EventEmitter();
|
|
416
481
|
openEntityRecord = new EventEmitter();
|
|
417
482
|
taskClicked = new EventEmitter();
|
|
418
483
|
artifactLinkClicked = new EventEmitter();
|
|
484
|
+
sidebarToggleClicked = new EventEmitter();
|
|
419
485
|
// STATE CHANGE OUTPUTS - notify parent of state changes
|
|
486
|
+
// conversationCreated now includes pendingMessage and pendingAttachments to ensure atomic state update
|
|
420
487
|
conversationCreated = new EventEmitter();
|
|
421
488
|
threadOpened = new EventEmitter();
|
|
422
489
|
threadClosed = new EventEmitter();
|
|
423
490
|
pendingArtifactConsumed = new EventEmitter();
|
|
424
491
|
pendingMessageConsumed = new EventEmitter();
|
|
492
|
+
// pendingMessageRequested is deprecated - use conversationCreated with pendingMessage instead
|
|
425
493
|
pendingMessageRequested = new EventEmitter();
|
|
426
494
|
scrollContainer;
|
|
427
495
|
messageInputComponents;
|
|
@@ -429,7 +497,7 @@ export class ConversationChatAreaComponent {
|
|
|
429
497
|
messages = [];
|
|
430
498
|
showScrollToBottomIcon = false;
|
|
431
499
|
scrollToBottom = false;
|
|
432
|
-
|
|
500
|
+
loadedPeripheralConversationIds = new Set(); // Track ALL conversations whose peripheral data was loaded
|
|
433
501
|
currentlyLoadingConversationId = null; // Track which conversation is currently being loaded
|
|
434
502
|
isProcessing = false;
|
|
435
503
|
intentCheckMessage = null; // Temporary message shown during intent checking
|
|
@@ -482,15 +550,15 @@ export class ConversationChatAreaComponent {
|
|
|
482
550
|
* Ratings by conversation detail ID (parsed from RatingsJSON)
|
|
483
551
|
*/
|
|
484
552
|
ratingsByDetailId = new Map();
|
|
553
|
+
/**
|
|
554
|
+
* Attachments by conversation detail ID (loaded from ConversationDetailAttachments)
|
|
555
|
+
*/
|
|
556
|
+
attachmentsByDetailId = new Map();
|
|
485
557
|
/**
|
|
486
558
|
* In-progress message IDs for streaming reconnection
|
|
487
559
|
* Passed to message-input component to reconnect PubSub updates
|
|
488
560
|
*/
|
|
489
561
|
inProgressMessageIds = [];
|
|
490
|
-
// Timer for smooth agent run UI updates (updates every second while agent runs)
|
|
491
|
-
agentRunUpdateTimer = null;
|
|
492
|
-
// Track previous message statuses to detect completions after navigation
|
|
493
|
-
previousMessageStatuses = new Map();
|
|
494
562
|
// Cache of message-input metadata for rendering multiple instances
|
|
495
563
|
// Prevents destruction/recreation when switching conversations for performance
|
|
496
564
|
messageInputMetadataCache = new Map();
|
|
@@ -502,6 +570,8 @@ export class ConversationChatAreaComponent {
|
|
|
502
570
|
isLoadingPeripheralData = false;
|
|
503
571
|
// Subject to trigger artifact viewer refresh when new version is created
|
|
504
572
|
artifactViewerRefresh$ = new Subject();
|
|
573
|
+
// Subject for component destruction cleanup
|
|
574
|
+
destroy$ = new Subject();
|
|
505
575
|
// Track initialization state to prevent loading messages before agents are ready
|
|
506
576
|
isInitialized = false;
|
|
507
577
|
// Resize state
|
|
@@ -510,7 +580,22 @@ export class ConversationChatAreaComponent {
|
|
|
510
580
|
startWidth = 0;
|
|
511
581
|
// LocalStorage key
|
|
512
582
|
ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
|
|
513
|
-
|
|
583
|
+
// Image viewer state
|
|
584
|
+
showImageViewer = false;
|
|
585
|
+
selectedImageUrl = '';
|
|
586
|
+
selectedImageAlt = '';
|
|
587
|
+
selectedImageFileName = '';
|
|
588
|
+
// Upload indicator state (shown centered in conversation area)
|
|
589
|
+
isUploadingAttachments = false;
|
|
590
|
+
uploadingMessage = '';
|
|
591
|
+
// Attachment support based on agent modalities
|
|
592
|
+
// Computed from conversation manager (Sage) and any previous agent in conversation
|
|
593
|
+
enableAttachments = false;
|
|
594
|
+
maxAttachments = 10;
|
|
595
|
+
maxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB default
|
|
596
|
+
acceptedFileTypes = 'image/*';
|
|
597
|
+
conversationManagerAgent = null;
|
|
598
|
+
constructor(conversationData, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService, artifactPermissionService, dialogService, attachmentService, streamingService) {
|
|
514
599
|
this.conversationData = conversationData;
|
|
515
600
|
this.agentStateService = agentStateService;
|
|
516
601
|
this.conversationAgentService = conversationAgentService;
|
|
@@ -519,6 +604,8 @@ export class ConversationChatAreaComponent {
|
|
|
519
604
|
this.mentionAutocompleteService = mentionAutocompleteService;
|
|
520
605
|
this.artifactPermissionService = artifactPermissionService;
|
|
521
606
|
this.dialogService = dialogService;
|
|
607
|
+
this.attachmentService = attachmentService;
|
|
608
|
+
this.streamingService = streamingService;
|
|
522
609
|
}
|
|
523
610
|
async ngOnInit() {
|
|
524
611
|
// The workspace component initializes AI Engine and mention service before
|
|
@@ -529,8 +616,22 @@ export class ConversationChatAreaComponent {
|
|
|
529
616
|
console.warn('⚠️ Mention autocomplete not initialized by workspace, initializing now...');
|
|
530
617
|
await this.mentionAutocompleteService.initialize(this.currentUser);
|
|
531
618
|
}
|
|
619
|
+
// Initialize attachment support based on agent modalities
|
|
620
|
+
await this.initializeAttachmentSupport();
|
|
532
621
|
// Load saved artifact pane width
|
|
533
622
|
this.loadArtifactPaneWidth();
|
|
623
|
+
// Subscribe to completion events from streaming service (PubSub-based, replaces polling)
|
|
624
|
+
// This handles real-time completion notifications without timer-based polling
|
|
625
|
+
this.streamingService.completionEvents$
|
|
626
|
+
.pipe(takeUntil(this.destroy$))
|
|
627
|
+
.subscribe(async (event) => {
|
|
628
|
+
// Only handle if it's for a message in our current conversation
|
|
629
|
+
const message = this.messages.find(m => m.ID === event.conversationDetailId);
|
|
630
|
+
if (message) {
|
|
631
|
+
LogStatusEx({ message: `🎉 Received completion event for message ${event.conversationDetailId}`, verboseOnly: true });
|
|
632
|
+
await this.handleMessageCompletion(message, event.agentRunId);
|
|
633
|
+
}
|
|
634
|
+
});
|
|
534
635
|
// Mark as initialized so setter can trigger conversation changes
|
|
535
636
|
this.isInitialized = true;
|
|
536
637
|
// Initial load if there's already an active conversation
|
|
@@ -543,6 +644,70 @@ export class ConversationChatAreaComponent {
|
|
|
543
644
|
window.addEventListener('touchmove', this.onResizeTouchMove.bind(this));
|
|
544
645
|
window.addEventListener('touchend', this.onResizeTouchEnd.bind(this));
|
|
545
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Initializes attachment support by checking if the conversation manager agent (Sage)
|
|
649
|
+
* or any recent agent in the conversation supports non-text input modalities.
|
|
650
|
+
*/
|
|
651
|
+
async initializeAttachmentSupport() {
|
|
652
|
+
try {
|
|
653
|
+
// Ensure AIEngineBase is configured with modality data
|
|
654
|
+
await AIEngineBase.Instance.Config(false);
|
|
655
|
+
// Get the conversation manager agent (Sage)
|
|
656
|
+
this.conversationManagerAgent = await this.conversationAgentService.getConversationManagerAgent();
|
|
657
|
+
if (this.conversationManagerAgent?.ID) {
|
|
658
|
+
// Get attachment limits from agent metadata (uses Agent → Model → System → Default cascade)
|
|
659
|
+
const limits = AIEngineBase.Instance.GetAgentAttachmentLimits(this.conversationManagerAgent.ID);
|
|
660
|
+
this.enableAttachments = limits.enabled;
|
|
661
|
+
this.maxAttachments = limits.maxAttachments;
|
|
662
|
+
this.maxAttachmentSizeBytes = limits.maxAttachmentSizeBytes;
|
|
663
|
+
this.acceptedFileTypes = limits.acceptedFileTypes;
|
|
664
|
+
LogStatusEx({ message: `Attachment support initialized: ${this.enableAttachments} (max ${this.maxAttachments}, ${(this.maxAttachmentSizeBytes / 1024 / 1024).toFixed(0)}MB)`, verboseOnly: true });
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
// Default to false if we can't determine
|
|
668
|
+
this.enableAttachments = false;
|
|
669
|
+
LogStatusEx({ message: 'Attachment support disabled: conversation manager agent not available', verboseOnly: true });
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
catch (error) {
|
|
673
|
+
console.warn('Failed to initialize attachment support:', error);
|
|
674
|
+
this.enableAttachments = false;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Updates attachment support based on the current conversation context.
|
|
679
|
+
* Called when conversation changes to check if any agent in the conversation supports attachments.
|
|
680
|
+
*/
|
|
681
|
+
updateAttachmentSupport() {
|
|
682
|
+
// Determine which agent to use for limits - prefer last non-Sage agent, fall back to Sage
|
|
683
|
+
let agentIdForLimits = this.conversationManagerAgent?.ID || null;
|
|
684
|
+
// Check if any previous non-Sage agent in the conversation supports attachments
|
|
685
|
+
if (this.messages.length > 0) {
|
|
686
|
+
const lastNonSageAgent = this.messages
|
|
687
|
+
.slice()
|
|
688
|
+
.reverse()
|
|
689
|
+
.find(msg => msg.Role === 'AI' &&
|
|
690
|
+
msg.AgentID &&
|
|
691
|
+
msg.AgentID !== this.conversationManagerAgent?.ID);
|
|
692
|
+
if (lastNonSageAgent?.AgentID) {
|
|
693
|
+
// Check if this agent supports attachments
|
|
694
|
+
if (AIEngineBase.Instance.AgentSupportsAttachments(lastNonSageAgent.AgentID)) {
|
|
695
|
+
agentIdForLimits = lastNonSageAgent.AgentID;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// Get limits from the determined agent
|
|
700
|
+
if (agentIdForLimits) {
|
|
701
|
+
const limits = AIEngineBase.Instance.GetAgentAttachmentLimits(agentIdForLimits);
|
|
702
|
+
this.enableAttachments = limits.enabled;
|
|
703
|
+
this.maxAttachments = limits.maxAttachments;
|
|
704
|
+
this.maxAttachmentSizeBytes = limits.maxAttachmentSizeBytes;
|
|
705
|
+
this.acceptedFileTypes = limits.acceptedFileTypes;
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
this.enableAttachments = false;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
546
711
|
ngAfterViewChecked() {
|
|
547
712
|
if (this.scrollToBottom) {
|
|
548
713
|
this.scrollToBottom = false;
|
|
@@ -558,10 +723,11 @@ export class ConversationChatAreaComponent {
|
|
|
558
723
|
}
|
|
559
724
|
}
|
|
560
725
|
ngOnDestroy() {
|
|
726
|
+
// Complete the destroy$ Subject to clean up subscriptions
|
|
727
|
+
this.destroy$.next();
|
|
728
|
+
this.destroy$.complete();
|
|
561
729
|
// Stop polling when component is destroyed
|
|
562
730
|
this.agentStateService.stopPolling();
|
|
563
|
-
// Stop agent run update timer
|
|
564
|
-
this.stopAgentRunUpdateTimer();
|
|
565
731
|
// Remove resize listeners
|
|
566
732
|
window.removeEventListener('mousemove', this.onResizeMove.bind(this));
|
|
567
733
|
window.removeEventListener('mouseup', this.onResizeEnd.bind(this));
|
|
@@ -576,7 +742,6 @@ export class ConversationChatAreaComponent {
|
|
|
576
742
|
}
|
|
577
743
|
// Do NOT clear activeTasks - they are workspace-level and persist across conversations
|
|
578
744
|
// Clearing causes bugs: global tasks panel blanks out, no notifications when switching
|
|
579
|
-
this.previousMessageStatuses.clear();
|
|
580
745
|
this.showArtifactPanel = false;
|
|
581
746
|
this.selectedArtifactId = null;
|
|
582
747
|
if (conversationId) {
|
|
@@ -593,6 +758,7 @@ export class ConversationChatAreaComponent {
|
|
|
593
758
|
try {
|
|
594
759
|
await this.loadMessages(conversationId);
|
|
595
760
|
await this.restoreActiveTasks(conversationId);
|
|
761
|
+
// TODO: Replace polling with PubSub - see plans/repair-conversations-ui-performance.md
|
|
596
762
|
this.agentStateService.startPolling(this.currentUser, conversationId);
|
|
597
763
|
}
|
|
598
764
|
catch (error) {
|
|
@@ -693,13 +859,8 @@ export class ConversationChatAreaComponent {
|
|
|
693
859
|
messages.push(message);
|
|
694
860
|
}
|
|
695
861
|
this.messages = messages;
|
|
696
|
-
//
|
|
697
|
-
this.
|
|
698
|
-
for (const message of messages) {
|
|
699
|
-
if (message.ID && message.Status) {
|
|
700
|
-
this.previousMessageStatuses.set(message.ID, message.Status);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
862
|
+
// Update attachment support based on agents in this conversation
|
|
863
|
+
this.updateAttachmentSupport();
|
|
703
864
|
// Detect in-progress messages for streaming reconnection
|
|
704
865
|
// Always create NEW array reference to trigger Input setter in message-input component
|
|
705
866
|
this.inProgressMessageIds = [...messages
|
|
@@ -707,7 +868,25 @@ export class ConversationChatAreaComponent {
|
|
|
707
868
|
.map(m => m.ID)];
|
|
708
869
|
if (this.inProgressMessageIds.length > 0) {
|
|
709
870
|
LogStatusEx({ message: `🔌 Detected ${this.inProgressMessageIds.length} in-progress messages for reconnection`, verboseOnly: true });
|
|
710
|
-
|
|
871
|
+
// Check for missed completions - handle the "navigate away then back" scenario
|
|
872
|
+
// The streaming service caches recent completions for components that initialize late
|
|
873
|
+
for (const message of messages) {
|
|
874
|
+
if (message.Status === 'In-Progress' && message.ID) {
|
|
875
|
+
const recentCompletion = this.streamingService.getRecentCompletion(message.ID);
|
|
876
|
+
if (recentCompletion) {
|
|
877
|
+
LogStatusEx({ message: `🔄 Found missed completion for message ${message.ID}, processing...`, verboseOnly: true });
|
|
878
|
+
// Process the completion asynchronously (don't await to avoid blocking)
|
|
879
|
+
this.handleMessageCompletion(message, recentCompletion.agentRunId)
|
|
880
|
+
.then(() => {
|
|
881
|
+
// Clear the cached completion after handling
|
|
882
|
+
this.streamingService.clearRecentCompletion(message.ID);
|
|
883
|
+
})
|
|
884
|
+
.catch(error => {
|
|
885
|
+
console.error(`Failed to handle missed completion for message ${message.ID}:`, error);
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
711
890
|
}
|
|
712
891
|
this.scrollToBottom = true;
|
|
713
892
|
LogStatusEx({ message: `✅ Built ${messages.length} messages from cache`, verboseOnly: true });
|
|
@@ -747,12 +926,12 @@ export class ConversationChatAreaComponent {
|
|
|
747
926
|
async loadPeripheralData(conversationId) {
|
|
748
927
|
const timestamp = new Date().toISOString();
|
|
749
928
|
// Skip if we've already processed peripheral data for this conversation
|
|
750
|
-
if (this.
|
|
929
|
+
if (this.loadedPeripheralConversationIds.has(conversationId)) {
|
|
751
930
|
LogStatusEx({ message: `[${timestamp}] ⏭️ Skipping peripheral data processing - already processed for conversation ${conversationId}`, verboseOnly: true });
|
|
752
931
|
return;
|
|
753
932
|
}
|
|
754
933
|
// Mark this conversation as processed to prevent duplicate processing
|
|
755
|
-
this.
|
|
934
|
+
this.loadedPeripheralConversationIds.add(conversationId);
|
|
756
935
|
LogStatusEx({ message: `[${timestamp}] 📊 Processing peripheral data for conversation ${conversationId} from cache`, verboseOnly: true });
|
|
757
936
|
try {
|
|
758
937
|
// Get cached data - should always be present by the time we get here
|
|
@@ -816,9 +995,18 @@ export class ConversationChatAreaComponent {
|
|
|
816
995
|
this.systemArtifactsByDetailId.set(row.ID, systemArtifactList);
|
|
817
996
|
}
|
|
818
997
|
}
|
|
819
|
-
// Build ratings map
|
|
820
|
-
|
|
821
|
-
|
|
998
|
+
// Build ratings map - always set (empty array if no ratings)
|
|
999
|
+
// This tells the rating component not to query the database
|
|
1000
|
+
this.ratingsByDetailId.set(row.ID, parsed.ratings);
|
|
1001
|
+
}
|
|
1002
|
+
// Load attachments for all messages in this conversation
|
|
1003
|
+
// Uses the ConversationAttachmentService to batch-load all attachments
|
|
1004
|
+
this.attachmentsByDetailId.clear();
|
|
1005
|
+
const messageIds = conversationData.map(row => row.ID).filter((id) => !!id);
|
|
1006
|
+
if (messageIds.length > 0) {
|
|
1007
|
+
const attachmentsMap = await this.attachmentService.loadAttachmentsForMessages(messageIds, this.currentUser);
|
|
1008
|
+
for (const [detailId, attachments] of attachmentsMap) {
|
|
1009
|
+
this.attachmentsByDetailId.set(detailId, attachments);
|
|
822
1010
|
}
|
|
823
1011
|
}
|
|
824
1012
|
// Create new Map references to trigger Angular change detection
|
|
@@ -826,13 +1014,15 @@ export class ConversationChatAreaComponent {
|
|
|
826
1014
|
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
827
1015
|
this.ratingsByDetailId = new Map(this.ratingsByDetailId);
|
|
828
1016
|
this.systemArtifactsByDetailId = new Map(this.systemArtifactsByDetailId);
|
|
1017
|
+
this.attachmentsByDetailId = new Map(this.attachmentsByDetailId);
|
|
829
1018
|
// Clear combined cache since we loaded new artifacts
|
|
830
1019
|
this._combinedArtifactsMap = null;
|
|
831
1020
|
// Update artifact count for header display (unique artifacts, not versions)
|
|
832
1021
|
this.artifactCount = this.calculateUniqueArtifactCount();
|
|
833
1022
|
// Debug: Log summary
|
|
834
1023
|
const systemArtifactCount = this.systemArtifactsByDetailId.size;
|
|
835
|
-
|
|
1024
|
+
const attachmentCount = this.attachmentsByDetailId.size;
|
|
1025
|
+
LogStatusEx({ message: `📊 Processed ${this.agentRunsByDetailId.size} agent runs, ${this.artifactsByDetailId.size} user artifact mappings, ${systemArtifactCount} system artifact mappings (${this.artifactCount} unique user artifacts), ${attachmentCount} messages with attachments`, verboseOnly: true });
|
|
836
1026
|
// CRITICAL: Trigger message re-render now that agent runs and artifacts are loaded
|
|
837
1027
|
// This updates all message components with the newly loaded agent run data
|
|
838
1028
|
this.messages = [...this.messages]; // Create new array reference to trigger change detection
|
|
@@ -841,8 +1031,8 @@ export class ConversationChatAreaComponent {
|
|
|
841
1031
|
}
|
|
842
1032
|
catch (error) {
|
|
843
1033
|
console.error('Failed to process peripheral data:', error);
|
|
844
|
-
//
|
|
845
|
-
this.
|
|
1034
|
+
// Remove from loaded set on error so we can retry
|
|
1035
|
+
this.loadedPeripheralConversationIds.delete(conversationId);
|
|
846
1036
|
}
|
|
847
1037
|
}
|
|
848
1038
|
/**
|
|
@@ -854,7 +1044,7 @@ export class ConversationChatAreaComponent {
|
|
|
854
1044
|
// Intentionally empty - ActiveTasksService only tracks in-memory running tasks
|
|
855
1045
|
// Database tasks are loaded separately by TasksDropdownComponent
|
|
856
1046
|
}
|
|
857
|
-
onMessageSent(message) {
|
|
1047
|
+
async onMessageSent(message) {
|
|
858
1048
|
// Clear pending message if it was sent - notify parent via output
|
|
859
1049
|
if (this.pendingMessage) {
|
|
860
1050
|
this.pendingMessageConsumed.emit();
|
|
@@ -881,10 +1071,31 @@ export class ConversationChatAreaComponent {
|
|
|
881
1071
|
if (this.conversationId) {
|
|
882
1072
|
this.invalidateConversationCache(this.conversationId);
|
|
883
1073
|
}
|
|
1074
|
+
// Load attachments for the new message (if any were saved with it)
|
|
1075
|
+
// This ensures attachments are displayed immediately after sending
|
|
1076
|
+
await this.loadAttachmentsForMessage(message.ID);
|
|
884
1077
|
}
|
|
885
1078
|
// Scroll to bottom when new message is sent
|
|
886
1079
|
this.scrollToBottom = true;
|
|
887
1080
|
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Loads attachments for a single message and adds them to the attachmentsByDetailId map.
|
|
1083
|
+
* Called after a new message is sent to ensure attachments are displayed immediately.
|
|
1084
|
+
*/
|
|
1085
|
+
async loadAttachmentsForMessage(messageId) {
|
|
1086
|
+
try {
|
|
1087
|
+
const attachments = await this.attachmentService.loadAttachmentsForMessage(messageId, this.currentUser);
|
|
1088
|
+
if (attachments.length > 0) {
|
|
1089
|
+
this.attachmentsByDetailId.set(messageId, attachments);
|
|
1090
|
+
// Create new map reference to trigger Angular change detection
|
|
1091
|
+
this.attachmentsByDetailId = new Map(this.attachmentsByDetailId);
|
|
1092
|
+
LogStatusEx({ message: `Loaded ${attachments.length} attachment(s) for message ${messageId}`, verboseOnly: true });
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
catch (error) {
|
|
1096
|
+
console.warn('Failed to load attachments for message:', error);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
888
1099
|
/**
|
|
889
1100
|
* Ensures the current user is in the avatar map
|
|
890
1101
|
* Called when new messages are created to ensure avatar data is available
|
|
@@ -925,8 +1136,57 @@ export class ConversationChatAreaComponent {
|
|
|
925
1136
|
// Trigger re-render to show updated status
|
|
926
1137
|
this.messages = [...this.messages];
|
|
927
1138
|
this.cdr.detectChanges();
|
|
928
|
-
|
|
929
|
-
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Handle message completion from PubSub streaming service.
|
|
1143
|
+
* This is the primary completion handler that replaces timer-based polling.
|
|
1144
|
+
* Called when the streaming service receives a completion event from the backend.
|
|
1145
|
+
*
|
|
1146
|
+
* @param message The message entity that completed
|
|
1147
|
+
* @param agentRunId The agent run ID from the completion event
|
|
1148
|
+
*/
|
|
1149
|
+
async handleMessageCompletion(message, agentRunId) {
|
|
1150
|
+
try {
|
|
1151
|
+
LogStatusEx({ message: `🔄 Handling completion for message ${message.ID}`, verboseOnly: true });
|
|
1152
|
+
// 1. Reload message from database to get final content
|
|
1153
|
+
await message.Load(message.ID);
|
|
1154
|
+
// 2. Reload agent run to get final status/timestamps
|
|
1155
|
+
const agentRun = this.agentRunsByDetailId.get(message.ID);
|
|
1156
|
+
if (agentRun?.ID) {
|
|
1157
|
+
await agentRun.Load(agentRun.ID);
|
|
1158
|
+
}
|
|
1159
|
+
// 3. Reload artifacts for this completed message
|
|
1160
|
+
await this.reloadArtifactsForMessage(message.ID);
|
|
1161
|
+
// 4. Reload messages to discover newly delegated agent messages
|
|
1162
|
+
// When Sage delegates to Marketing Agent, a new message is created
|
|
1163
|
+
await this.reloadMessagesForActiveConversation();
|
|
1164
|
+
// 5. Update inProgressMessageIds to track any new delegated agents
|
|
1165
|
+
this.inProgressMessageIds = [...this.messages
|
|
1166
|
+
.filter(m => m.Status === 'In-Progress')
|
|
1167
|
+
.map(m => m.ID)];
|
|
1168
|
+
// 6. Auto-open artifact panel if message has artifacts and no artifact is currently shown
|
|
1169
|
+
if (this.artifactsByDetailId.has(message.ID) && !this.showArtifactPanel) {
|
|
1170
|
+
const artifactList = this.artifactsByDetailId.get(message.ID);
|
|
1171
|
+
if (artifactList && artifactList.length > 0) {
|
|
1172
|
+
// Show the LAST (most recent) artifact
|
|
1173
|
+
this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
|
|
1174
|
+
this.showArtifactPanel = true;
|
|
1175
|
+
await this.loadArtifactPermissions(this.selectedArtifactId);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
// 7. Remove task from ActiveTasksService (clears spinner in conversation list)
|
|
1179
|
+
const task = this.activeTasks.getByConversationDetailId(message.ID);
|
|
1180
|
+
if (task) {
|
|
1181
|
+
this.activeTasks.remove(task.id);
|
|
1182
|
+
}
|
|
1183
|
+
// 8. Trigger re-render with updated data
|
|
1184
|
+
this.messages = [...this.messages];
|
|
1185
|
+
this.cdr.detectChanges();
|
|
1186
|
+
LogStatusEx({ message: `✅ Completion handled for message ${message.ID}`, verboseOnly: true });
|
|
1187
|
+
}
|
|
1188
|
+
catch (error) {
|
|
1189
|
+
console.error(`Failed to handle completion for message ${message.ID}:`, error);
|
|
930
1190
|
}
|
|
931
1191
|
}
|
|
932
1192
|
/**
|
|
@@ -935,75 +1195,19 @@ export class ConversationChatAreaComponent {
|
|
|
935
1195
|
* Provides real-time updates of status, timestamps, tokens, cost during execution
|
|
936
1196
|
*/
|
|
937
1197
|
async onAgentRunUpdate(event) {
|
|
938
|
-
let run;
|
|
939
1198
|
if (event.agentRun) {
|
|
940
1199
|
// Directly update map with fresh data from progress (no database query needed)
|
|
941
1200
|
// Don't create new Map - message-list component needs to keep the same reference
|
|
942
1201
|
this.agentRunsByDetailId.set(event.conversationDetailId, event.agentRun);
|
|
943
|
-
run = event.agentRun;
|
|
944
1202
|
}
|
|
945
1203
|
else {
|
|
946
1204
|
// no agent run, should have agentRunId
|
|
947
|
-
|
|
1205
|
+
await this.addAgentRunToMap(event.conversationDetailId, event.agentRunId);
|
|
948
1206
|
}
|
|
949
1207
|
// Force message list to re-render with updated agent run
|
|
950
1208
|
// This ensures message components receive the fresh agent run data
|
|
951
1209
|
this.messages = [...this.messages];
|
|
952
1210
|
this.cdr.detectChanges();
|
|
953
|
-
// Start 1-second update timer for smooth UI updates (if not already running)
|
|
954
|
-
this.startAgentRunUpdateTimer();
|
|
955
|
-
// If agent completed or failed, stop the timer
|
|
956
|
-
const status = run.Status?.toLowerCase();
|
|
957
|
-
if (status === 'complete' || status === 'completed' || status === 'failed' || status === 'error') {
|
|
958
|
-
this.stopAgentRunUpdateTimer();
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
/**
|
|
962
|
-
* Start 1-second timer for smooth agent run UI updates
|
|
963
|
-
* Updates the message list every second to keep elapsed times current
|
|
964
|
-
* Also detects when messages complete and reloads agent runs
|
|
965
|
-
*/
|
|
966
|
-
startAgentRunUpdateTimer() {
|
|
967
|
-
// Don't start if already running
|
|
968
|
-
if (this.agentRunUpdateTimer !== null) {
|
|
969
|
-
return;
|
|
970
|
-
}
|
|
971
|
-
LogStatusEx({ message: '⏱️ Starting agent run update timer (1-second interval)', verboseOnly: true });
|
|
972
|
-
this.agentRunUpdateTimer = setInterval(async () => {
|
|
973
|
-
// Check for messages that changed from In-Progress to Complete
|
|
974
|
-
// This handles the navigation scenario where onMessageComplete isn't called
|
|
975
|
-
await this.detectAndHandleCompletedMessages();
|
|
976
|
-
// Check if we have any active agent runs
|
|
977
|
-
let hasActiveRuns = false;
|
|
978
|
-
for (const agentRun of this.agentRunsByDetailId.values()) {
|
|
979
|
-
const status = agentRun.Status?.toLowerCase();
|
|
980
|
-
if (status === 'in-progress' || status === 'running') {
|
|
981
|
-
hasActiveRuns = true;
|
|
982
|
-
break;
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
// Keep timer running if we have active runs OR tracking messages for completion
|
|
986
|
-
// This ensures we detect completions even before agent runs are fully loaded
|
|
987
|
-
if (hasActiveRuns || this.previousMessageStatuses.size > 0) {
|
|
988
|
-
// Force message list to re-render so timers update
|
|
989
|
-
this.messages = [...this.messages];
|
|
990
|
-
this.cdr.detectChanges();
|
|
991
|
-
}
|
|
992
|
-
else {
|
|
993
|
-
// Stop only if nothing to monitor
|
|
994
|
-
this.stopAgentRunUpdateTimer();
|
|
995
|
-
}
|
|
996
|
-
}, 1000);
|
|
997
|
-
}
|
|
998
|
-
/**
|
|
999
|
-
* Stop the agent run update timer
|
|
1000
|
-
*/
|
|
1001
|
-
stopAgentRunUpdateTimer() {
|
|
1002
|
-
if (this.agentRunUpdateTimer !== null) {
|
|
1003
|
-
LogStatusEx({ message: '⏹️ Stopping agent run update timer', verboseOnly: true });
|
|
1004
|
-
clearInterval(this.agentRunUpdateTimer);
|
|
1005
|
-
this.agentRunUpdateTimer = null;
|
|
1006
|
-
}
|
|
1007
1211
|
}
|
|
1008
1212
|
/**
|
|
1009
1213
|
* Reload messages for the active conversation from the database
|
|
@@ -1054,80 +1258,6 @@ export class ConversationChatAreaComponent {
|
|
|
1054
1258
|
console.error('Failed to reload messages for active conversation:', error);
|
|
1055
1259
|
}
|
|
1056
1260
|
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Detect messages that changed from In-Progress to Complete and reload their agent runs
|
|
1059
|
-
* This handles the navigation scenario where onMessageComplete event isn't fired
|
|
1060
|
-
*/
|
|
1061
|
-
async detectAndHandleCompletedMessages() {
|
|
1062
|
-
try {
|
|
1063
|
-
for (const message of this.messages) {
|
|
1064
|
-
if (!message.ID)
|
|
1065
|
-
continue;
|
|
1066
|
-
const previousStatus = this.previousMessageStatuses.get(message.ID);
|
|
1067
|
-
// CRITICAL FIX: If message was tracked as In-Progress, reload from database to get actual current status.
|
|
1068
|
-
// This handles the navigation scenario where local state becomes stale while we're away.
|
|
1069
|
-
// The database has the real status and content (updated by streaming callbacks or agent completion).
|
|
1070
|
-
if (previousStatus === 'In-Progress') {
|
|
1071
|
-
try {
|
|
1072
|
-
await message.Load(message.ID);
|
|
1073
|
-
}
|
|
1074
|
-
catch (loadError) {
|
|
1075
|
-
console.error(`Failed to reload message ${message.ID}:`, loadError);
|
|
1076
|
-
continue;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
const currentStatus = message.Status;
|
|
1080
|
-
// Detect completion: was In-Progress, now Complete
|
|
1081
|
-
if (previousStatus === 'In-Progress' && currentStatus === 'Complete') {
|
|
1082
|
-
// Get the agent run for this message
|
|
1083
|
-
const agentRun = this.agentRunsByDetailId.get(message.ID);
|
|
1084
|
-
if (agentRun?.ID) {
|
|
1085
|
-
try {
|
|
1086
|
-
// Reload agent run from database to get updated Status
|
|
1087
|
-
await agentRun.Load(agentRun.ID);
|
|
1088
|
-
// Reload artifacts for this completed message
|
|
1089
|
-
await this.reloadArtifactsForMessage(message.ID);
|
|
1090
|
-
// CRITICAL: Reload messages to pick up newly delegated agent messages
|
|
1091
|
-
// When Sage delegates to Marketing Agent, a new message is created
|
|
1092
|
-
// We need to discover and register callbacks for these new messages
|
|
1093
|
-
await this.reloadMessagesForActiveConversation();
|
|
1094
|
-
// Update inProgressMessageIds to include new delegated agents
|
|
1095
|
-
// This triggers callback registration via the setter in message-input
|
|
1096
|
-
this.inProgressMessageIds = [...this.messages
|
|
1097
|
-
.filter(m => m.Status === 'In-Progress')
|
|
1098
|
-
.map(m => m.ID)];
|
|
1099
|
-
// Auto-open artifact panel if this message has artifacts and no artifact is currently shown
|
|
1100
|
-
if (this.artifactsByDetailId.has(message.ID) && !this.showArtifactPanel) {
|
|
1101
|
-
const artifactList = this.artifactsByDetailId.get(message.ID);
|
|
1102
|
-
if (artifactList && artifactList.length > 0) {
|
|
1103
|
-
// Show the LAST (most recent) artifact - uses display data, no lazy load needed
|
|
1104
|
-
this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
|
|
1105
|
-
this.showArtifactPanel = true;
|
|
1106
|
-
// Load permissions for the new artifact
|
|
1107
|
-
await this.loadArtifactPermissions(this.selectedArtifactId);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
// Force re-render with updated agent run and artifacts
|
|
1111
|
-
this.messages = [...this.messages];
|
|
1112
|
-
this.cdr.detectChanges();
|
|
1113
|
-
// IMPORTANT: Remove from tracking map so timer can stop when all messages complete
|
|
1114
|
-
this.previousMessageStatuses.delete(message.ID);
|
|
1115
|
-
}
|
|
1116
|
-
catch (error) {
|
|
1117
|
-
console.error('Failed to reload agent run on completion:', error);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
else if (currentStatus === 'In-Progress') {
|
|
1122
|
-
// Only track In-Progress messages - don't re-add Complete messages
|
|
1123
|
-
this.previousMessageStatuses.set(message.ID, currentStatus);
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
catch (error) {
|
|
1128
|
-
console.error('Error in detectAndHandleCompletedMessages:', error);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
1261
|
async onAgentResponse(event) {
|
|
1132
1262
|
// Add the agent's response message to the conversation
|
|
1133
1263
|
this.messages = [...this.messages, event.message];
|
|
@@ -1165,6 +1295,7 @@ export class ConversationChatAreaComponent {
|
|
|
1165
1295
|
*/
|
|
1166
1296
|
invalidateConversationCache(conversationId) {
|
|
1167
1297
|
this.conversationDataCache.delete(conversationId);
|
|
1298
|
+
this.loadedPeripheralConversationIds.delete(conversationId);
|
|
1168
1299
|
LogStatusEx({ message: `🗑️ Invalidated cache for conversation ${conversationId}`, verboseOnly: true });
|
|
1169
1300
|
}
|
|
1170
1301
|
/**
|
|
@@ -1502,7 +1633,7 @@ export class ConversationChatAreaComponent {
|
|
|
1502
1633
|
else if (!this.conversation || this.isNewConversation) {
|
|
1503
1634
|
// If no conversation or in new unsaved state, route through empty state handler
|
|
1504
1635
|
// This will create the conversation and send the message
|
|
1505
|
-
await this.onEmptyStateMessageSent(messageText);
|
|
1636
|
+
await this.onEmptyStateMessageSent({ text: messageText, attachments: [] });
|
|
1506
1637
|
}
|
|
1507
1638
|
else {
|
|
1508
1639
|
console.error('MessageInputComponent not available and not in a valid state to create conversation');
|
|
@@ -1514,6 +1645,37 @@ export class ConversationChatAreaComponent {
|
|
|
1514
1645
|
LogStatusEx({ message: 'Retry requested for message', verboseOnly: true, additionalArgs: [message.ID] });
|
|
1515
1646
|
// For now, just log it - full implementation would require refactoring agent invocation
|
|
1516
1647
|
}
|
|
1648
|
+
/**
|
|
1649
|
+
* Handle attachment click - opens the image viewer for images
|
|
1650
|
+
*/
|
|
1651
|
+
onAttachmentClicked(attachment) {
|
|
1652
|
+
if (attachment.type === 'Image' && attachment.contentUrl) {
|
|
1653
|
+
this.selectedImageUrl = attachment.contentUrl;
|
|
1654
|
+
this.selectedImageAlt = attachment.fileName || 'Image attachment';
|
|
1655
|
+
this.selectedImageFileName = attachment.fileName || 'image';
|
|
1656
|
+
this.showImageViewer = true;
|
|
1657
|
+
}
|
|
1658
|
+
else {
|
|
1659
|
+
// For non-image attachments, could trigger download or other action
|
|
1660
|
+
console.log('Non-image attachment clicked:', attachment);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Handle image viewer close
|
|
1665
|
+
*/
|
|
1666
|
+
onImageViewerClosed() {
|
|
1667
|
+
this.showImageViewer = false;
|
|
1668
|
+
this.selectedImageUrl = '';
|
|
1669
|
+
this.selectedImageAlt = '';
|
|
1670
|
+
this.selectedImageFileName = '';
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Handle upload state changes from message input component
|
|
1674
|
+
*/
|
|
1675
|
+
onUploadStateChanged(event) {
|
|
1676
|
+
this.isUploadingAttachments = event.isUploading;
|
|
1677
|
+
this.uploadingMessage = event.message;
|
|
1678
|
+
}
|
|
1517
1679
|
async onArtifactClicked(data) {
|
|
1518
1680
|
this.selectedArtifactId = data.artifactId;
|
|
1519
1681
|
// If versionId is provided, find the version number from display data (no lazy load needed)
|
|
@@ -1727,30 +1889,36 @@ export class ConversationChatAreaComponent {
|
|
|
1727
1889
|
* Handle message sent from empty state component
|
|
1728
1890
|
* Creates a new conversation and emits to parent to update selection
|
|
1729
1891
|
*/
|
|
1730
|
-
async onEmptyStateMessageSent(
|
|
1731
|
-
|
|
1892
|
+
async onEmptyStateMessageSent(event) {
|
|
1893
|
+
const { text, attachments } = event;
|
|
1894
|
+
if (!text?.trim() && (!attachments || attachments.length === 0)) {
|
|
1732
1895
|
return;
|
|
1733
1896
|
}
|
|
1734
|
-
LogStatusEx({ message: '📨 Empty state message received', verboseOnly: true, additionalArgs: [
|
|
1897
|
+
LogStatusEx({ message: '📨 Empty state message received', verboseOnly: true, additionalArgs: [text, `${attachments?.length || 0} attachments`] });
|
|
1735
1898
|
try {
|
|
1736
1899
|
this.isProcessing = true;
|
|
1737
1900
|
// Create a new conversation using the data service
|
|
1738
1901
|
const newConversation = await this.conversationData.createConversation('New Conversation', // Temporary name - will be auto-named after first message
|
|
1739
1902
|
this.environmentId, this.currentUser);
|
|
1740
1903
|
if (!newConversation) {
|
|
1741
|
-
console.error('
|
|
1904
|
+
console.error('Failed to create new conversation');
|
|
1742
1905
|
this.isProcessing = false;
|
|
1743
1906
|
return;
|
|
1744
1907
|
}
|
|
1745
1908
|
LogStatusEx({ message: '✅ Created new conversation', verboseOnly: true, additionalArgs: [newConversation.ID] });
|
|
1746
|
-
// Emit to parent with the new conversation AND the pending message
|
|
1747
|
-
//
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1909
|
+
// Emit to parent with the new conversation AND the pending message/attachments in a single event
|
|
1910
|
+
// This ensures atomic state update - workspace sets all state before Angular change detection
|
|
1911
|
+
// creates the new message-input component
|
|
1912
|
+
const pendingMessage = text?.trim() || '';
|
|
1913
|
+
const pendingAttachments = attachments || [];
|
|
1914
|
+
this.conversationCreated.emit({
|
|
1915
|
+
conversation: newConversation,
|
|
1916
|
+
pendingMessage,
|
|
1917
|
+
pendingAttachments
|
|
1918
|
+
});
|
|
1751
1919
|
}
|
|
1752
1920
|
catch (error) {
|
|
1753
|
-
console.error('
|
|
1921
|
+
console.error('Error creating conversation from empty state:', error);
|
|
1754
1922
|
}
|
|
1755
1923
|
finally {
|
|
1756
1924
|
this.isProcessing = false;
|
|
@@ -2031,7 +2199,7 @@ export class ConversationChatAreaComponent {
|
|
|
2031
2199
|
this.cdr.detectChanges();
|
|
2032
2200
|
}
|
|
2033
2201
|
}
|
|
2034
|
-
static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationDataService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService), i0.ɵɵdirectiveInject(i6.ArtifactPermissionService), i0.ɵɵdirectiveInject(i7.DialogService)); };
|
|
2202
|
+
static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationDataService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService), i0.ɵɵdirectiveInject(i6.ArtifactPermissionService), i0.ɵɵdirectiveInject(i7.DialogService), i0.ɵɵdirectiveInject(i8.ConversationAttachmentService), i0.ɵɵdirectiveInject(i9.ConversationStreamingService)); };
|
|
2035
2203
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
|
|
2036
2204
|
i0.ɵɵviewQuery(_c0, 5);
|
|
2037
2205
|
i0.ɵɵviewQuery(ArtifactViewerPanelComponent, 5);
|
|
@@ -2041,11 +2209,11 @@ export class ConversationChatAreaComponent {
|
|
|
2041
2209
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
|
|
2042
2210
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
|
|
2043
2211
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
|
|
2044
|
-
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested" }, decls:
|
|
2212
|
+
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingAttachments: "pendingAttachments", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", showSidebarToggle: "showSidebarToggle" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", sidebarToggleClicked: "sidebarToggleClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested" }, decls: 16, vars: 21, consts: [["scrollContainer", ""], ["messageInput", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [3, "currentUser", "disabled", "showSidebarToggle"], [1, "conversation-loading-state"], [1, "chat-messages-wrapper"], [1, "chat-artifact-pane", 3, "width", "maximized"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [3, "imageUrl", "alt", "fileName", "visible"], [1, "chat-header"], [1, "chat-info"], ["class", "sidebar-toggle-btn", "title", "Show conversations", 3, "click", 4, "ngIf"], [1, "chat-title"], ["class", "project-tag", "title", "Assign to project", 3, "click", 4, "ngIf"], ["class", "test-indicator", "title", "View Test Run", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions", "chat-actions-buttons"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], ["class", "chat-members", "title", "View members", 3, "click", 4, "ngIf"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "btn-label"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["title", "Show conversations", 1, "sidebar-toggle-btn", 3, "click"], [1, "fas", "fa-table-columns"], ["title", "Assign to project", 1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "artifact-badge"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], [1, "members-badge"], [3, "sidebarToggleClicked", "messageSent", "currentUser", "disabled", "showSidebarToggle"], ["text", "Loading conversation...", "size", "large"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [1, "message-input-container-wrapper"], ["size", "medium", 3, "text"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [3, "messageSent", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "uploadStateChanged", "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [3, "closed", "replyAdded", "parentMessageId", "conversationId", "currentUser"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-header-actions"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "active"], [1, "modal-body", "artifacts-grid"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"], [3, "saved", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [3, "closed", "imageUrl", "alt", "fileName", "visible"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2045
2213
|
i0.ɵɵelementStart(0, "div", 2);
|
|
2046
|
-
i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template,
|
|
2214
|
+
i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 20, 15, "div", 3);
|
|
2047
2215
|
i0.ɵɵelementStart(2, "div", 4)(3, "div", 5);
|
|
2048
|
-
i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_4_Template, 1,
|
|
2216
|
+
i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_4_Template, 1, 3, "mj-conversation-empty-state", 6)(5, ConversationChatAreaComponent_Conditional_5_Template, 2, 0, "div", 7)(6, ConversationChatAreaComponent_Conditional_6_Template, 9, 12, "div", 8);
|
|
2049
2217
|
i0.ɵɵelementEnd();
|
|
2050
2218
|
i0.ɵɵtemplate(7, ConversationChatAreaComponent_Conditional_7_Template, 3, 14, "div", 9);
|
|
2051
2219
|
i0.ɵɵelementStart(8, "mj-artifact-share-modal", 10);
|
|
@@ -2058,7 +2226,7 @@ export class ConversationChatAreaComponent {
|
|
|
2058
2226
|
i0.ɵɵelementStart(11, "mj-members-modal", 13);
|
|
2059
2227
|
i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_11_listener() { return ctx.showMembersModal = false; })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_11_listener() { return ctx.showMembersModal = false; });
|
|
2060
2228
|
i0.ɵɵelementEnd();
|
|
2061
|
-
i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 9, 3, "div", 14)(13, ConversationChatAreaComponent_Conditional_13_Template, 13, 2, "div", 14)(14, ConversationChatAreaComponent_Conditional_14_Template, 1, 4, "mj-artifact-collection-picker-modal", 15);
|
|
2229
|
+
i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 9, 3, "div", 14)(13, ConversationChatAreaComponent_Conditional_13_Template, 13, 2, "div", 14)(14, ConversationChatAreaComponent_Conditional_14_Template, 1, 4, "mj-artifact-collection-picker-modal", 15)(15, ConversationChatAreaComponent_Conditional_15_Template, 1, 4, "mj-image-viewer", 16);
|
|
2062
2230
|
} if (rf & 2) {
|
|
2063
2231
|
i0.ɵɵadvance();
|
|
2064
2232
|
i0.ɵɵproperty("ngIf", ctx.conversation);
|
|
@@ -2082,12 +2250,14 @@ export class ConversationChatAreaComponent {
|
|
|
2082
2250
|
i0.ɵɵconditional(ctx.showArtifactsModal ? 13 : -1);
|
|
2083
2251
|
i0.ɵɵadvance();
|
|
2084
2252
|
i0.ɵɵconditional(ctx.showCollectionPicker ? 14 : -1);
|
|
2085
|
-
} }, dependencies: [i8.NgIf, i9.ArtifactViewerPanelComponent, i10.LoadingComponent, i11.ArtifactCollectionPickerModalComponent, i12.ArtifactShareModalComponent, i13.MessageListComponent, i14.MessageInputComponent, i15.ConversationEmptyStateComponent, i16.ThreadPanelComponent, i17.ProjectSelectorComponent, i18.ActiveAgentIndicatorComponent, i19.MembersModalComponent, i20.ExportModalComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: #3B82F6;\n color: white;\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: #6366F1;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n\n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n\n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n\n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}"] });
|
|
2253
|
+
i0.ɵɵadvance();
|
|
2254
|
+
i0.ɵɵconditional(ctx.showImageViewer ? 15 : -1);
|
|
2255
|
+
} }, dependencies: [i10.NgIf, i11.ArtifactViewerPanelComponent, i12.LoadingComponent, i13.ArtifactCollectionPickerModalComponent, i14.ArtifactShareModalComponent, i15.MessageListComponent, i16.MessageInputComponent, i17.ConversationEmptyStateComponent, i18.ThreadPanelComponent, i19.ProjectSelectorComponent, i20.ActiveAgentIndicatorComponent, i21.MembersModalComponent, i22.ExportModalComponent, i23.ImageViewerComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #666;\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #333;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: #3B82F6;\n color: white;\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: #6366F1;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; \n\n}\n\n\n\n.upload-indicator-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: rgba(255, 255, 255, 0.95);\n border-radius: 12px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n\n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n\n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n\n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}"] });
|
|
2086
2256
|
}
|
|
2087
2257
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
2088
2258
|
type: Component,
|
|
2089
|
-
args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversation\">\n <div class=\"chat-info\">\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation.TestRunID)\" title=\"View Test Run\" *ngIf=\"conversation.TestRunID\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\" *ngIf=\"memberCount > 1\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n <span class=\"btn-label\">Export</span>\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isNewConversation || !conversationId) {\n <!-- Empty State - No conversation selected OR new unsaved conversation -->\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n } @else if (isLoadingConversation) {\n <!-- Loading State - Show centered spinner while conversation loads -->\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing\"\n [initialMessage]=\"inputRef.conversationId === conversationId ? pendingMessage : null\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted()\"\n (intentCheckCompleted)=\"onIntentCheckCompleted()\">\n </mj-message-input>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (threadId) {\n <mj-thread-panel\n [parentMessageId]=\"threadId\"\n [conversationId]=\"conversationId || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onLocalThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n (saved)=\"onCollectionPickerSaved($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n.chat-members,\n.artifact-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover,\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n/* Badge overlay for artifact and member counts */\n.artifact-badge,\n.members-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: #3B82F6;\n color: white;\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge {\n background: #6366F1;\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: #3B82F6;\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: #F3F4F6;\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item i {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item:hover .version-open-text {\n color: #3B82F6;\n}\n.artifact-version-item:hover i {\n color: #3B82F6;\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; /* Hide on mobile to save space */\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n /* Action buttons - icon only on mobile */\n .chat-actions-buttons {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons .action-btn {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons .action-btn .btn-label {\n display: none;\n }\n .chat-actions {\n flex-wrap: nowrap;\n }\n .chat-members,\n .artifact-indicator {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile, overlapping header */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; /* 48px nav + 8px dark strip above blue border */\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n"] }]
|
|
2090
|
-
}], () => [{ type: i1.ConversationDataService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }, { type: i6.ArtifactPermissionService }, { type: i7.DialogService }], { environmentId: [{
|
|
2259
|
+
args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversation\">\n <div class=\"chat-info\" [class.with-sidebar-toggle]=\"showSidebarToggle\">\n <button class=\"sidebar-toggle-btn\"\n *ngIf=\"showSidebarToggle\"\n (click)=\"sidebarToggleClicked.emit()\"\n title=\"Show conversations\">\n <i class=\"fas fa-table-columns\"></i>\n </button>\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation.TestRunID)\" title=\"View Test Run\" *ngIf=\"conversation.TestRunID\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\" *ngIf=\"memberCount > 1\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n <span class=\"btn-label\">Export</span>\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isNewConversation || !conversationId) {\n <!-- Empty State - No conversation selected OR new unsaved conversation -->\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n [showSidebarToggle]=\"showSidebarToggle\"\n (sidebarToggleClicked)=\"sidebarToggleClicked.emit()\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n } @else if (isLoadingConversation) {\n <!-- Loading State - Show centered spinner while conversation loads -->\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n <!-- Upload Indicator Overlay (centered in conversation area) -->\n @if (isUploadingAttachments) {\n <div class=\"upload-indicator-overlay\">\n <mj-loading [text]=\"uploadingMessage\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n [attachmentsMap]=\"attachmentsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [initialMessage]=\"inputRef.conversationId === conversationId ? pendingMessage : null\"\n [initialAttachments]=\"inputRef.conversationId === conversationId ? pendingAttachments : null\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted()\"\n (intentCheckCompleted)=\"onIntentCheckCompleted()\"\n (uploadStateChanged)=\"onUploadStateChanged($event)\">\n </mj-message-input>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (threadId) {\n <mj-thread-panel\n [parentMessageId]=\"threadId\"\n [conversationId]=\"conversationId || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onLocalThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n (saved)=\"onCollectionPickerSaved($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}\n\n<!-- Image Viewer Modal -->\n@if (showImageViewer) {\n <mj-image-viewer\n [imageUrl]=\"selectedImageUrl\"\n [alt]=\"selectedImageAlt\"\n [fileName]=\"selectedImageFileName\"\n [visible]=\"showImageViewer\"\n (closed)=\"onImageViewerClosed()\">\n </mj-image-viewer>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n/* Sidebar toggle button in header */\n.sidebar-toggle-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.sidebar-toggle-btn:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.sidebar-toggle-btn i {\n color: #666;\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn:hover i {\n color: #333;\n}\n\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n.chat-members,\n.artifact-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover,\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n/* Badge overlay for artifact and member counts */\n.artifact-badge,\n.members-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: #3B82F6;\n color: white;\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge {\n background: #6366F1;\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: #3B82F6;\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; /* For upload overlay positioning */\n}\n\n/* Upload indicator overlay - centered in conversation area */\n.upload-indicator-overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: rgba(255, 255, 255, 0.95);\n border-radius: 12px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: #F3F4F6;\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item i {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item:hover .version-open-text {\n color: #3B82F6;\n}\n.artifact-version-item:hover i {\n color: #3B82F6;\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; /* Hide on mobile to save space */\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n /* Action buttons - icon only on mobile */\n .chat-actions-buttons {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons .action-btn {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons .action-btn .btn-label {\n display: none;\n }\n .chat-actions {\n flex-wrap: nowrap;\n }\n .chat-members,\n .artifact-indicator {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile, overlapping header */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; /* 48px nav + 8px dark strip above blue border */\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n"] }]
|
|
2260
|
+
}], () => [{ type: i1.ConversationDataService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }, { type: i6.ArtifactPermissionService }, { type: i7.DialogService }, { type: i8.ConversationAttachmentService }, { type: i9.ConversationStreamingService }], { environmentId: [{
|
|
2091
2261
|
type: Input
|
|
2092
2262
|
}], currentUser: [{
|
|
2093
2263
|
type: Input
|
|
@@ -2101,10 +2271,14 @@ export class ConversationChatAreaComponent {
|
|
|
2101
2271
|
type: Input
|
|
2102
2272
|
}], pendingMessage: [{
|
|
2103
2273
|
type: Input
|
|
2274
|
+
}], pendingAttachments: [{
|
|
2275
|
+
type: Input
|
|
2104
2276
|
}], pendingArtifactId: [{
|
|
2105
2277
|
type: Input
|
|
2106
2278
|
}], pendingArtifactVersionNumber: [{
|
|
2107
2279
|
type: Input
|
|
2280
|
+
}], showSidebarToggle: [{
|
|
2281
|
+
type: Input
|
|
2108
2282
|
}], conversationRenamed: [{
|
|
2109
2283
|
type: Output
|
|
2110
2284
|
}], openEntityRecord: [{
|
|
@@ -2113,6 +2287,8 @@ export class ConversationChatAreaComponent {
|
|
|
2113
2287
|
type: Output
|
|
2114
2288
|
}], artifactLinkClicked: [{
|
|
2115
2289
|
type: Output
|
|
2290
|
+
}], sidebarToggleClicked: [{
|
|
2291
|
+
type: Output
|
|
2116
2292
|
}], conversationCreated: [{
|
|
2117
2293
|
type: Output
|
|
2118
2294
|
}], threadOpened: [{
|
|
@@ -2135,5 +2311,5 @@ export class ConversationChatAreaComponent {
|
|
|
2135
2311
|
type: ViewChild,
|
|
2136
2312
|
args: [ArtifactViewerPanelComponent]
|
|
2137
2313
|
}] }); })();
|
|
2138
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber:
|
|
2314
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 30 }); })();
|
|
2139
2315
|
//# sourceMappingURL=conversation-chat-area.component.js.map
|