@memberjunction/ng-conversations 2.122.1 → 2.123.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/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +22 -5
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +25 -11
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +215 -184
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +10 -5
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +49 -30
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +2 -2
- package/dist/lib/components/message/message-input.component.d.ts +3 -3
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +7 -7
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.js +2 -2
- package/dist/lib/components/message/message-list.component.d.ts +4 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +15 -2
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts +2 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +7 -3
- package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +6 -8
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +31 -29
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +3 -4
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +13 -15
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +50 -3
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +124 -43
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/services/{conversation-state.service.d.ts → conversation-data.service.d.ts} +22 -62
- package/dist/lib/services/conversation-data.service.d.ts.map +1 -0
- package/dist/lib/services/{conversation-state.service.js → conversation-data.service.js} +36 -106
- package/dist/lib/services/conversation-data.service.js.map +1 -0
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +26 -23
- package/dist/lib/services/conversation-state.service.d.ts.map +0 -1
- package/dist/lib/services/conversation-state.service.js.map +0 -1
|
@@ -6,7 +6,7 @@ import { ArtifactViewerPanelComponent } from '@memberjunction/ng-artifacts';
|
|
|
6
6
|
import { TestFeedbackDialogComponent } from '@memberjunction/ng-testing';
|
|
7
7
|
import { Subject } from 'rxjs';
|
|
8
8
|
import * as i0 from "@angular/core";
|
|
9
|
-
import * as i1 from "../../services/conversation-
|
|
9
|
+
import * as i1 from "../../services/conversation-data.service";
|
|
10
10
|
import * as i2 from "../../services/agent-state.service";
|
|
11
11
|
import * as i3 from "../../services/conversation-agent.service";
|
|
12
12
|
import * as i4 from "../../services/active-tasks.service";
|
|
@@ -41,23 +41,23 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
|
|
|
41
41
|
i0.ɵɵtext(3);
|
|
42
42
|
i0.ɵɵelementEnd()();
|
|
43
43
|
} if (rf & 2) {
|
|
44
|
-
const
|
|
44
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
45
45
|
i0.ɵɵadvance(3);
|
|
46
|
-
i0.ɵɵtextInterpolate(
|
|
46
|
+
i0.ɵɵtextInterpolate(ctx_r2.conversation.Project || "Project");
|
|
47
47
|
} }
|
|
48
48
|
function ConversationChatAreaComponent_div_1_button_5_Template(rf, ctx) { if (rf & 1) {
|
|
49
|
-
const
|
|
49
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
50
50
|
i0.ɵɵelementStart(0, "button", 32);
|
|
51
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
51
|
+
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.viewTestRun(ctx_r2.conversation.TestRunID)); });
|
|
52
52
|
i0.ɵɵelement(1, "i", 33);
|
|
53
53
|
i0.ɵɵelementStart(2, "span");
|
|
54
54
|
i0.ɵɵtext(3, "Test");
|
|
55
55
|
i0.ɵɵelementEnd()();
|
|
56
56
|
} }
|
|
57
57
|
function ConversationChatAreaComponent_div_1_button_12_Template(rf, ctx) { if (rf & 1) {
|
|
58
|
-
const
|
|
58
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
59
59
|
i0.ɵɵelementStart(0, "button", 34);
|
|
60
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
60
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewArtifacts()); });
|
|
61
61
|
i0.ɵɵelement(1, "i", 35);
|
|
62
62
|
i0.ɵɵelementStart(2, "span");
|
|
63
63
|
i0.ɵɵtext(3);
|
|
@@ -97,30 +97,29 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
97
97
|
i0.ɵɵtext(20, " Share ");
|
|
98
98
|
i0.ɵɵelementEnd()()();
|
|
99
99
|
} if (rf & 2) {
|
|
100
|
-
const conversation_r4 = ctx.ngIf;
|
|
101
100
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
102
101
|
i0.ɵɵadvance(3);
|
|
103
|
-
i0.ɵɵtextInterpolate(
|
|
102
|
+
i0.ɵɵtextInterpolate(ctx_r2.conversation.Name);
|
|
104
103
|
i0.ɵɵadvance();
|
|
105
|
-
i0.ɵɵproperty("ngIf",
|
|
104
|
+
i0.ɵɵproperty("ngIf", ctx_r2.conversation.ProjectID);
|
|
106
105
|
i0.ɵɵadvance();
|
|
107
|
-
i0.ɵɵproperty("ngIf",
|
|
106
|
+
i0.ɵɵproperty("ngIf", ctx_r2.conversation.TestRunID);
|
|
108
107
|
i0.ɵɵadvance();
|
|
109
|
-
i0.ɵɵproperty("conversationId", ctx_r2.
|
|
108
|
+
i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
|
|
110
109
|
i0.ɵɵadvance(5);
|
|
111
110
|
i0.ɵɵtextInterpolate2("", ctx_r2.memberCount, " member", ctx_r2.memberCount !== 1 ? "s" : "", "");
|
|
112
111
|
i0.ɵɵadvance();
|
|
113
112
|
i0.ɵɵproperty("ngIf", ctx_r2.artifactCountDisplay > 0);
|
|
114
113
|
i0.ɵɵadvance();
|
|
115
|
-
i0.ɵɵproperty("conversationId", ctx_r2.
|
|
114
|
+
i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
|
|
116
115
|
i0.ɵɵadvance(5);
|
|
117
116
|
i0.ɵɵclassProp("shared", ctx_r2.isShared);
|
|
118
117
|
i0.ɵɵproperty("title", ctx_r2.isShared ? "Manage sharing" : "Share conversation");
|
|
119
118
|
} }
|
|
120
119
|
function ConversationChatAreaComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
121
|
-
const
|
|
120
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
122
121
|
i0.ɵɵelementStart(0, "mj-conversation-empty-state", 36);
|
|
123
|
-
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(
|
|
122
|
+
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEmptyStateMessageSent($event)); });
|
|
124
123
|
i0.ɵɵelementEnd();
|
|
125
124
|
} if (rf & 2) {
|
|
126
125
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -132,9 +131,9 @@ function ConversationChatAreaComponent_Conditional_5_Template(rf, ctx) { if (rf
|
|
|
132
131
|
i0.ɵɵelementEnd();
|
|
133
132
|
} }
|
|
134
133
|
function ConversationChatAreaComponent_Conditional_6_span_4_Template(rf, ctx) { if (rf & 1) {
|
|
135
|
-
const
|
|
134
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
136
135
|
i0.ɵɵelementStart(0, "span", 44);
|
|
137
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_4_Template_span_click_0_listener() { i0.ɵɵrestoreView(
|
|
136
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_4_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.scrollToBottomAnimate()); });
|
|
138
137
|
i0.ɵɵelement(1, "i", 45);
|
|
139
138
|
i0.ɵɵelementEnd();
|
|
140
139
|
} }
|
|
@@ -144,14 +143,14 @@ function ConversationChatAreaComponent_Conditional_6_Conditional_6_Template(rf,
|
|
|
144
143
|
i0.ɵɵelementEnd();
|
|
145
144
|
} }
|
|
146
145
|
function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
147
|
-
const
|
|
146
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
148
147
|
i0.ɵɵelementStart(0, "mj-message-input", 48, 1);
|
|
149
|
-
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(
|
|
148
|
+
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_intentCheckStarted_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckStarted()); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_intentCheckCompleted_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckCompleted()); });
|
|
150
149
|
i0.ɵɵelementEnd();
|
|
151
150
|
} if (rf & 2) {
|
|
152
|
-
const
|
|
151
|
+
const inputRef_r10 = ctx.$implicit;
|
|
153
152
|
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
154
|
-
i0.ɵɵproperty("hidden",
|
|
153
|
+
i0.ɵɵproperty("hidden", inputRef_r10.conversationId !== ctx_r2.conversationId)("conversationId", inputRef_r10.conversationId)("conversationName", inputRef_r10.conversationName)("currentUser", ctx_r2.currentUser)("conversationHistory", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.messages : i0.ɵɵpureFunction0(11, _c2))("artifactsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.artifactsByDetailId : ctx_r2.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.systemArtifactsByDetailId : ctx_r2.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.agentRunsByDetailId : ctx_r2.emptyAgentRunsMap)("inProgressMessageIds", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.inProgressMessageIds : ctx_r2.emptyInProgressIds)("disabled", ctx_r2.isProcessing)("initialMessage", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.pendingMessage : null);
|
|
155
154
|
} }
|
|
156
155
|
function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
157
156
|
i0.ɵɵelementStart(0, "div", 43);
|
|
@@ -163,11 +162,11 @@ function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf,
|
|
|
163
162
|
i0.ɵɵrepeater(ctx_r2.getCachedInputs());
|
|
164
163
|
} }
|
|
165
164
|
function ConversationChatAreaComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
166
|
-
const
|
|
165
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
167
166
|
i0.ɵɵelementStart(0, "div", 8)(1, "div", 38, 0);
|
|
168
|
-
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_6_Template_div_scroll_1_listener() { i0.ɵɵrestoreView(
|
|
167
|
+
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_6_Template_div_scroll_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.checkScroll()); });
|
|
169
168
|
i0.ɵɵelementStart(3, "mj-conversation-message-list", 39);
|
|
170
|
-
i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_replyInThread_3_listener($event) { i0.ɵɵrestoreView(
|
|
169
|
+
i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_replyInThread_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_viewThread_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_retryMessage_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRetryMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_testFeedbackMessage_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_artifactClicked_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_messageEdited_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_openEntityRecord_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_suggestedResponseSelected_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSuggestedResponseSelected($event)); });
|
|
171
170
|
i0.ɵɵelementEnd();
|
|
172
171
|
i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_6_span_4_Template, 2, 0, "span", 40);
|
|
173
172
|
i0.ɵɵelementEnd();
|
|
@@ -177,23 +176,23 @@ function ConversationChatAreaComponent_Conditional_6_Template(rf, ctx) { if (rf
|
|
|
177
176
|
} if (rf & 2) {
|
|
178
177
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
179
178
|
i0.ɵɵadvance(3);
|
|
180
|
-
i0.ɵɵproperty("messages", ctx_r2.messages)("conversation", ctx_r2.
|
|
179
|
+
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);
|
|
181
180
|
i0.ɵɵadvance();
|
|
182
181
|
i0.ɵɵproperty("ngIf", ctx_r2.showScrollToBottomIcon && ctx_r2.messages && ctx_r2.messages.length > 0);
|
|
183
182
|
i0.ɵɵadvance(2);
|
|
184
183
|
i0.ɵɵconditional(ctx_r2.isLoadingPeripheralData ? 6 : 7);
|
|
185
184
|
} }
|
|
186
185
|
function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
187
|
-
const
|
|
186
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
188
187
|
i0.ɵɵelementStart(0, "div", 52);
|
|
189
|
-
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(
|
|
188
|
+
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r12); 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(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeTouchStart($event)); });
|
|
190
189
|
i0.ɵɵelementEnd();
|
|
191
190
|
} }
|
|
192
191
|
function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
193
|
-
const
|
|
192
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
194
193
|
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_7_Conditional_0_Template, 1, 0, "div", 49);
|
|
195
194
|
i0.ɵɵelementStart(1, "div", 50)(2, "mj-artifact-viewer-panel", 51);
|
|
196
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(
|
|
195
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r11); 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(_r11); 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(_r11); 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(_r11); 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(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMaximizeArtifactPane()); });
|
|
197
196
|
i0.ɵɵelementEnd()();
|
|
198
197
|
} if (rf & 2) {
|
|
199
198
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -205,39 +204,39 @@ function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf
|
|
|
205
204
|
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$);
|
|
206
205
|
} }
|
|
207
206
|
function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
208
|
-
const
|
|
207
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
209
208
|
i0.ɵɵelementStart(0, "mj-thread-panel", 53);
|
|
210
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(
|
|
209
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r13); 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(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onThreadReplyAdded($event)); });
|
|
211
210
|
i0.ɵɵelementEnd();
|
|
212
211
|
} if (rf & 2) {
|
|
213
212
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
214
|
-
i0.ɵɵproperty("parentMessageId", ctx_r2.
|
|
213
|
+
i0.ɵɵproperty("parentMessageId", ctx_r2.threadId)("conversationId", ctx_r2.conversationId || "")("currentUser", ctx_r2.currentUser);
|
|
215
214
|
} }
|
|
216
215
|
function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
217
|
-
const
|
|
216
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
218
217
|
i0.ɵɵelementStart(0, "div", 54);
|
|
219
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
218
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
|
|
220
219
|
i0.ɵɵelementStart(1, "div", 55);
|
|
221
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
220
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
222
221
|
i0.ɵɵelementStart(2, "div", 56)(3, "h3");
|
|
223
222
|
i0.ɵɵtext(4, "Assign Project");
|
|
224
223
|
i0.ɵɵelementEnd();
|
|
225
224
|
i0.ɵɵelementStart(5, "button", 57);
|
|
226
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(
|
|
225
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
|
|
227
226
|
i0.ɵɵelement(6, "i", 58);
|
|
228
227
|
i0.ɵɵelementEnd()();
|
|
229
228
|
i0.ɵɵelementStart(7, "div", 59)(8, "mj-project-selector", 60);
|
|
230
|
-
i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(
|
|
229
|
+
i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onProjectSelected($event)); });
|
|
231
230
|
i0.ɵɵelementEnd()()()();
|
|
232
231
|
} if (rf & 2) {
|
|
233
232
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
234
233
|
i0.ɵɵadvance(8);
|
|
235
|
-
i0.ɵɵproperty("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("selectedProjectId", ctx_r2.
|
|
234
|
+
i0.ɵɵproperty("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("selectedProjectId", ctx_r2.conversation.ProjectID);
|
|
236
235
|
} }
|
|
237
236
|
function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
238
|
-
const
|
|
237
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
239
238
|
i0.ɵɵelementStart(0, "button", 67);
|
|
240
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
239
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleSystemArtifacts()); });
|
|
241
240
|
i0.ɵɵelement(1, "i", 68);
|
|
242
241
|
i0.ɵɵelementStart(2, "span");
|
|
243
242
|
i0.ɵɵtext(3);
|
|
@@ -258,28 +257,28 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_10_Template(rf
|
|
|
258
257
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
259
258
|
i0.ɵɵtext(0);
|
|
260
259
|
} if (rf & 2) {
|
|
261
|
-
const
|
|
262
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
260
|
+
const artifact_r18 = i0.ɵɵnextContext().$implicit;
|
|
261
|
+
i0.ɵɵtextInterpolate1(" ", artifact_r18.versionCount, " versions ");
|
|
263
262
|
} }
|
|
264
263
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
265
264
|
i0.ɵɵtext(0, " 1 version ");
|
|
266
265
|
} }
|
|
267
266
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
268
|
-
const
|
|
267
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
269
268
|
i0.ɵɵelementStart(0, "button", 82);
|
|
270
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
269
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r19); const artifact_r18 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleArtifactExpansion(artifact_r18.artifactId, $event)); });
|
|
271
270
|
i0.ɵɵelement(1, "i", 83);
|
|
272
271
|
i0.ɵɵelementEnd();
|
|
273
272
|
} if (rf & 2) {
|
|
274
|
-
const
|
|
273
|
+
const artifact_r18 = i0.ɵɵnextContext().$implicit;
|
|
275
274
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
276
275
|
i0.ɵɵadvance();
|
|
277
|
-
i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !==
|
|
276
|
+
i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !== artifact_r18.artifactId)("fa-chevron-up", ctx_r2.expandedArtifactId === artifact_r18.artifactId);
|
|
278
277
|
} }
|
|
279
278
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
280
|
-
const
|
|
279
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
281
280
|
i0.ɵɵelementStart(0, "div", 85);
|
|
282
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const
|
|
281
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r21 = i0.ɵɵrestoreView(_r20).$implicit; const artifact_r18 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openArtifactFromModal(artifact_r18.artifactId, version_r21.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
283
282
|
i0.ɵɵelementStart(1, "span", 86);
|
|
284
283
|
i0.ɵɵtext(2);
|
|
285
284
|
i0.ɵɵelementEnd();
|
|
@@ -289,23 +288,23 @@ function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_
|
|
|
289
288
|
i0.ɵɵelement(5, "i", 88);
|
|
290
289
|
i0.ɵɵelementEnd();
|
|
291
290
|
} if (rf & 2) {
|
|
292
|
-
const
|
|
291
|
+
const version_r21 = ctx.$implicit;
|
|
293
292
|
i0.ɵɵadvance(2);
|
|
294
|
-
i0.ɵɵtextInterpolate1("v",
|
|
293
|
+
i0.ɵɵtextInterpolate1("v", version_r21.versionNumber, "");
|
|
295
294
|
} }
|
|
296
295
|
function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
297
296
|
i0.ɵɵelementStart(0, "div", 81);
|
|
298
297
|
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template, 6, 1, "div", 84, _forTrack2);
|
|
299
298
|
i0.ɵɵelementEnd();
|
|
300
299
|
} if (rf & 2) {
|
|
301
|
-
const
|
|
300
|
+
const artifact_r18 = i0.ɵɵnextContext().$implicit;
|
|
302
301
|
i0.ɵɵadvance();
|
|
303
|
-
i0.ɵɵrepeater(
|
|
302
|
+
i0.ɵɵrepeater(artifact_r18.versions);
|
|
304
303
|
} }
|
|
305
304
|
function ConversationChatAreaComponent_Conditional_13_For_12_Template(rf, ctx) { if (rf & 1) {
|
|
306
|
-
const
|
|
305
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
307
306
|
i0.ɵɵelementStart(0, "div", 71)(1, "div", 72);
|
|
308
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const
|
|
307
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const artifact_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openArtifactFromModal(artifact_r18.artifactId)); });
|
|
309
308
|
i0.ɵɵelementStart(2, "div", 73);
|
|
310
309
|
i0.ɵɵelement(3, "i", 74);
|
|
311
310
|
i0.ɵɵelementEnd();
|
|
@@ -322,31 +321,31 @@ function ConversationChatAreaComponent_Conditional_13_For_12_Template(rf, ctx) {
|
|
|
322
321
|
i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template, 3, 0, "div", 81);
|
|
323
322
|
i0.ɵɵelementEnd();
|
|
324
323
|
} if (rf & 2) {
|
|
325
|
-
const
|
|
324
|
+
const artifact_r18 = ctx.$implicit;
|
|
326
325
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
327
|
-
i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId ===
|
|
326
|
+
i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId === artifact_r18.artifactId)("system-artifact", artifact_r18.visibility === "System Only");
|
|
328
327
|
i0.ɵɵadvance(6);
|
|
329
|
-
i0.ɵɵtextInterpolate(
|
|
328
|
+
i0.ɵɵtextInterpolate(artifact_r18.name);
|
|
330
329
|
i0.ɵɵadvance(2);
|
|
331
|
-
i0.ɵɵconditional(
|
|
330
|
+
i0.ɵɵconditional(artifact_r18.versionCount > 1 ? 8 : 9);
|
|
332
331
|
i0.ɵɵadvance(2);
|
|
333
|
-
i0.ɵɵconditional(
|
|
332
|
+
i0.ɵɵconditional(artifact_r18.versionCount > 1 ? 10 : -1);
|
|
334
333
|
i0.ɵɵadvance(3);
|
|
335
|
-
i0.ɵɵconditional(ctx_r2.expandedArtifactId ===
|
|
334
|
+
i0.ɵɵconditional(ctx_r2.expandedArtifactId === artifact_r18.artifactId && artifact_r18.versionCount > 1 ? 13 : -1);
|
|
336
335
|
} }
|
|
337
336
|
function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
338
|
-
const
|
|
337
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
339
338
|
i0.ɵɵelementStart(0, "div", 54);
|
|
340
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
339
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
|
|
341
340
|
i0.ɵɵelementStart(1, "div", 61);
|
|
342
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(
|
|
341
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r15); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
343
342
|
i0.ɵɵelementStart(2, "div", 56)(3, "h3");
|
|
344
343
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
345
344
|
i0.ɵɵelementEnd();
|
|
346
345
|
i0.ɵɵelementStart(5, "div", 62);
|
|
347
346
|
i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_13_Conditional_6_Template, 4, 3, "button", 63);
|
|
348
347
|
i0.ɵɵelementStart(7, "button", 57);
|
|
349
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(
|
|
348
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
|
|
350
349
|
i0.ɵɵelement(8, "i", 58);
|
|
351
350
|
i0.ɵɵelementEnd()()();
|
|
352
351
|
i0.ɵɵelementStart(9, "div", 64);
|
|
@@ -363,16 +362,16 @@ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf
|
|
|
363
362
|
i0.ɵɵrepeater(ctx_r2.getArtifactsArray());
|
|
364
363
|
} }
|
|
365
364
|
function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
366
|
-
const
|
|
365
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
367
366
|
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 89);
|
|
368
|
-
i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(
|
|
367
|
+
i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r22); 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(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerCancelled()); });
|
|
369
368
|
i0.ɵɵelementEnd();
|
|
370
369
|
} if (rf & 2) {
|
|
371
370
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
372
371
|
i0.ɵɵproperty("isOpen", ctx_r2.showCollectionPicker)("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("excludeCollectionIds", ctx_r2.collectionPickerExcludedIds);
|
|
373
372
|
} }
|
|
374
373
|
export class ConversationChatAreaComponent {
|
|
375
|
-
|
|
374
|
+
conversationData;
|
|
376
375
|
agentStateService;
|
|
377
376
|
conversationAgentService;
|
|
378
377
|
activeTasks;
|
|
@@ -382,18 +381,46 @@ export class ConversationChatAreaComponent {
|
|
|
382
381
|
dialogService;
|
|
383
382
|
environmentId;
|
|
384
383
|
currentUser;
|
|
384
|
+
// LOCAL STATE INPUTS - passed from parent workspace
|
|
385
|
+
_conversationId = null;
|
|
386
|
+
set conversationId(value) {
|
|
387
|
+
if (value !== this._conversationId) {
|
|
388
|
+
this._conversationId = value;
|
|
389
|
+
// Trigger change handler after initialization is complete
|
|
390
|
+
// Only skip during Angular's initial binding before ngOnInit completes
|
|
391
|
+
if (this.isInitialized) {
|
|
392
|
+
this.onConversationChanged(value);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
get conversationId() {
|
|
397
|
+
return this._conversationId;
|
|
398
|
+
}
|
|
399
|
+
conversation = null;
|
|
400
|
+
threadId = null;
|
|
401
|
+
isNewConversation = false;
|
|
402
|
+
pendingMessage = null;
|
|
403
|
+
pendingArtifactId = null;
|
|
404
|
+
pendingArtifactVersionNumber = null;
|
|
385
405
|
conversationRenamed = new EventEmitter();
|
|
386
406
|
openEntityRecord = new EventEmitter();
|
|
387
407
|
taskClicked = new EventEmitter();
|
|
388
408
|
artifactLinkClicked = new EventEmitter();
|
|
409
|
+
// STATE CHANGE OUTPUTS - notify parent of state changes
|
|
410
|
+
conversationCreated = new EventEmitter();
|
|
411
|
+
threadOpened = new EventEmitter();
|
|
412
|
+
threadClosed = new EventEmitter();
|
|
413
|
+
pendingArtifactConsumed = new EventEmitter();
|
|
414
|
+
pendingMessageConsumed = new EventEmitter();
|
|
415
|
+
pendingMessageRequested = new EventEmitter();
|
|
389
416
|
scrollContainer;
|
|
390
417
|
messageInputComponent;
|
|
391
418
|
artifactViewerComponent;
|
|
392
419
|
messages = [];
|
|
393
420
|
showScrollToBottomIcon = false;
|
|
394
421
|
scrollToBottom = false;
|
|
395
|
-
previousConversationId = null;
|
|
396
422
|
lastLoadedConversationId = null; // Track which conversation's peripheral data was loaded
|
|
423
|
+
currentlyLoadingConversationId = null; // Track which conversation is currently being loaded
|
|
397
424
|
isProcessing = false;
|
|
398
425
|
intentCheckMessage = null; // Temporary message shown during intent checking
|
|
399
426
|
isLoadingConversation = true; // True while loading initial conversation messages
|
|
@@ -473,8 +500,8 @@ export class ConversationChatAreaComponent {
|
|
|
473
500
|
startWidth = 0;
|
|
474
501
|
// LocalStorage key
|
|
475
502
|
ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
|
|
476
|
-
constructor(
|
|
477
|
-
this.
|
|
503
|
+
constructor(conversationData, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService, artifactPermissionService, dialogService) {
|
|
504
|
+
this.conversationData = conversationData;
|
|
478
505
|
this.agentStateService = agentStateService;
|
|
479
506
|
this.conversationAgentService = conversationAgentService;
|
|
480
507
|
this.activeTasks = activeTasks;
|
|
@@ -494,11 +521,11 @@ export class ConversationChatAreaComponent {
|
|
|
494
521
|
}
|
|
495
522
|
// Load saved artifact pane width
|
|
496
523
|
this.loadArtifactPaneWidth();
|
|
497
|
-
// Mark as initialized so
|
|
524
|
+
// Mark as initialized so setter can trigger conversation changes
|
|
498
525
|
this.isInitialized = true;
|
|
499
526
|
// Initial load if there's already an active conversation
|
|
500
|
-
if (this.
|
|
501
|
-
await this.onConversationChanged(this.
|
|
527
|
+
if (this.conversationId) {
|
|
528
|
+
await this.onConversationChanged(this.conversationId);
|
|
502
529
|
}
|
|
503
530
|
// Setup resize listeners
|
|
504
531
|
window.addEventListener('mousemove', this.onResizeMove.bind(this));
|
|
@@ -506,19 +533,6 @@ export class ConversationChatAreaComponent {
|
|
|
506
533
|
window.addEventListener('touchmove', this.onResizeTouchMove.bind(this));
|
|
507
534
|
window.addEventListener('touchend', this.onResizeTouchEnd.bind(this));
|
|
508
535
|
}
|
|
509
|
-
ngDoCheck() {
|
|
510
|
-
// Don't process conversation changes until initialization is complete
|
|
511
|
-
// This prevents race condition where messages load before agents are ready
|
|
512
|
-
if (!this.isInitialized) {
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
// Detect conversation ID changes using change detection
|
|
516
|
-
const currentId = this.conversationState.activeConversationId;
|
|
517
|
-
if (currentId !== this.previousConversationId) {
|
|
518
|
-
this.previousConversationId = currentId;
|
|
519
|
-
this.onConversationChanged(currentId);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
536
|
ngAfterViewChecked() {
|
|
523
537
|
if (this.scrollToBottom) {
|
|
524
538
|
this.scrollToBottom = false;
|
|
@@ -545,44 +559,56 @@ export class ConversationChatAreaComponent {
|
|
|
545
559
|
window.removeEventListener('touchend', this.onResizeTouchEnd.bind(this));
|
|
546
560
|
}
|
|
547
561
|
async onConversationChanged(conversationId) {
|
|
548
|
-
//
|
|
549
|
-
//
|
|
550
|
-
|
|
551
|
-
|
|
562
|
+
// Prevent double-loading if we're already loading this same conversation
|
|
563
|
+
// (ngDoCheck can fire multiple times during state changes)
|
|
564
|
+
if (this.currentlyLoadingConversationId === conversationId && conversationId !== null) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
// Do NOT clear activeTasks - they are workspace-level and persist across conversations
|
|
568
|
+
// Clearing causes bugs: global tasks panel blanks out, no notifications when switching
|
|
552
569
|
this.previousMessageStatuses.clear();
|
|
553
|
-
// Hide artifact panel when conversation changes
|
|
554
570
|
this.showArtifactPanel = false;
|
|
555
571
|
this.selectedArtifactId = null;
|
|
556
572
|
if (conversationId) {
|
|
557
|
-
|
|
573
|
+
this.currentlyLoadingConversationId = conversationId;
|
|
558
574
|
if (!this.messageInputMetadataCache.has(conversationId)) {
|
|
559
|
-
const conversation = this.conversationState.activeConversation;
|
|
560
575
|
this.messageInputMetadataCache.set(conversationId, {
|
|
561
576
|
conversationId: conversationId,
|
|
562
|
-
conversationName: conversation?.Name || null
|
|
577
|
+
conversationName: this.conversation?.Name || null
|
|
563
578
|
});
|
|
564
579
|
}
|
|
565
|
-
// Show loading state
|
|
566
580
|
this.isLoadingConversation = true;
|
|
567
|
-
this.messages = [];
|
|
581
|
+
this.messages = [];
|
|
568
582
|
this.cdr.detectChanges();
|
|
569
583
|
try {
|
|
570
584
|
await this.loadMessages(conversationId);
|
|
571
585
|
await this.restoreActiveTasks(conversationId);
|
|
572
586
|
this.agentStateService.startPolling(this.currentUser, conversationId);
|
|
573
587
|
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
console.error('Error loading conversation:', error);
|
|
590
|
+
this.messages = [];
|
|
591
|
+
}
|
|
574
592
|
finally {
|
|
575
|
-
|
|
593
|
+
this.currentlyLoadingConversationId = null;
|
|
576
594
|
this.isLoadingConversation = false;
|
|
595
|
+
// Create new array reference to trigger Angular change detection
|
|
596
|
+
this.messages = [...this.messages];
|
|
577
597
|
this.cdr.detectChanges();
|
|
578
|
-
//
|
|
579
|
-
|
|
598
|
+
// Defensive fallback: force another change detection cycle after async ops complete
|
|
599
|
+
setTimeout(() => {
|
|
600
|
+
if (conversationId === this._conversationId && this.messages.length > 0) {
|
|
601
|
+
this.messages = [...this.messages];
|
|
602
|
+
this.cdr.detectChanges();
|
|
603
|
+
}
|
|
604
|
+
}, 50);
|
|
580
605
|
}
|
|
581
606
|
}
|
|
582
607
|
else {
|
|
583
608
|
// No active conversation - show empty state
|
|
584
609
|
this.messages = [];
|
|
585
610
|
this.isLoadingConversation = false;
|
|
611
|
+
this.currentlyLoadingConversationId = null;
|
|
586
612
|
this.agentStateService.stopPolling();
|
|
587
613
|
}
|
|
588
614
|
}
|
|
@@ -596,15 +622,12 @@ export class ConversationChatAreaComponent {
|
|
|
596
622
|
}
|
|
597
623
|
async loadMessages(conversationId) {
|
|
598
624
|
try {
|
|
599
|
-
// Check if we have cached data for this conversation
|
|
600
625
|
const cachedData = this.conversationDataCache.get(conversationId);
|
|
601
626
|
if (cachedData) {
|
|
602
|
-
|
|
603
|
-
this.
|
|
604
|
-
this.loadPeripheralData(conversationId); // Process cached data for maps
|
|
627
|
+
await this.buildMessagesFromCache(cachedData);
|
|
628
|
+
await this.loadPeripheralData(conversationId);
|
|
605
629
|
}
|
|
606
630
|
else {
|
|
607
|
-
// Load from database with single optimized query
|
|
608
631
|
const rq = new RunQuery();
|
|
609
632
|
const result = await rq.RunQuery({
|
|
610
633
|
QueryName: 'GetConversationComplete',
|
|
@@ -616,20 +639,15 @@ export class ConversationChatAreaComponent {
|
|
|
616
639
|
this.messages = [];
|
|
617
640
|
return;
|
|
618
641
|
}
|
|
619
|
-
// Cache the raw results for future use
|
|
620
642
|
const conversationData = result.Results;
|
|
621
643
|
this.conversationDataCache.set(conversationId, conversationData);
|
|
622
|
-
|
|
623
|
-
this.buildMessagesFromCache(conversationData);
|
|
624
|
-
// Process peripheral data (agent runs & artifacts) in background
|
|
644
|
+
await this.buildMessagesFromCache(conversationData);
|
|
625
645
|
this.isLoadingPeripheralData = true;
|
|
626
646
|
await this.loadPeripheralData(conversationId);
|
|
627
647
|
this.isLoadingPeripheralData = false;
|
|
628
648
|
this.cdr.detectChanges();
|
|
629
649
|
}
|
|
630
|
-
// After loading messages, check for in-progress runs and ensure we're receiving updates
|
|
631
650
|
await this.detectAndReconnectToInProgressRuns(conversationId);
|
|
632
|
-
// Check for pending artifact navigation (from collection link)
|
|
633
651
|
await this.handlePendingArtifactNavigation();
|
|
634
652
|
}
|
|
635
653
|
catch (error) {
|
|
@@ -644,23 +662,17 @@ export class ConversationChatAreaComponent {
|
|
|
644
662
|
async buildMessagesFromCache(conversationData) {
|
|
645
663
|
const md = new Metadata();
|
|
646
664
|
const messages = [];
|
|
647
|
-
// Store raw conversation data for access to query-specific fields
|
|
648
665
|
this.rawConversationData = conversationData;
|
|
649
|
-
// Build user avatar map for fast lookups
|
|
650
666
|
this.buildUserAvatarMap(conversationData);
|
|
651
667
|
for (const row of conversationData) {
|
|
652
668
|
if (!row.ID)
|
|
653
669
|
continue;
|
|
654
|
-
// Create entity object and load from raw data
|
|
655
670
|
const message = await md.GetEntityObject('Conversation Details', this.currentUser);
|
|
656
|
-
// LoadFromData expects the same structure as the query result
|
|
657
|
-
// Since we're using SELECT *, all fields should be present
|
|
658
671
|
message.LoadFromData(row);
|
|
659
672
|
messages.push(message);
|
|
660
673
|
}
|
|
661
674
|
this.messages = messages;
|
|
662
|
-
//
|
|
663
|
-
// This captures the initial state so the completion detector can see transitions
|
|
675
|
+
// Initialize status tracking to detect message completion
|
|
664
676
|
this.previousMessageStatuses.clear();
|
|
665
677
|
for (const message of messages) {
|
|
666
678
|
if (message.ID && message.Status) {
|
|
@@ -668,19 +680,16 @@ export class ConversationChatAreaComponent {
|
|
|
668
680
|
}
|
|
669
681
|
}
|
|
670
682
|
// Detect in-progress messages for streaming reconnection
|
|
671
|
-
//
|
|
683
|
+
// Always create NEW array reference to trigger Input setter in message-input component
|
|
672
684
|
this.inProgressMessageIds = [...messages
|
|
673
685
|
.filter(m => m.Status === 'In-Progress')
|
|
674
686
|
.map(m => m.ID)];
|
|
675
687
|
if (this.inProgressMessageIds.length > 0) {
|
|
676
688
|
LogStatusEx({ message: `🔌 Detected ${this.inProgressMessageIds.length} in-progress messages for reconnection`, verboseOnly: true });
|
|
677
|
-
// Note: Reconnection now happens automatically via Input setter in message-input component
|
|
678
|
-
// CRITICAL: Restart the timer to monitor these in-progress messages for completion
|
|
679
|
-
// This ensures the completion detector runs even if the timer stopped before tracking was initialized
|
|
680
689
|
this.startAgentRunUpdateTimer();
|
|
681
690
|
}
|
|
682
691
|
this.scrollToBottom = true;
|
|
683
|
-
|
|
692
|
+
LogStatusEx({ message: `✅ Built ${messages.length} messages from cache`, verboseOnly: true });
|
|
684
693
|
}
|
|
685
694
|
/**
|
|
686
695
|
* Builds a map of UserID -> Avatar data for fast lookups
|
|
@@ -825,9 +834,9 @@ export class ConversationChatAreaComponent {
|
|
|
825
834
|
// Database tasks are loaded separately by TasksDropdownComponent
|
|
826
835
|
}
|
|
827
836
|
onMessageSent(message) {
|
|
828
|
-
// Clear pending message if it was sent
|
|
829
|
-
if (this.
|
|
830
|
-
this.
|
|
837
|
+
// Clear pending message if it was sent - notify parent via output
|
|
838
|
+
if (this.pendingMessage) {
|
|
839
|
+
this.pendingMessageConsumed.emit();
|
|
831
840
|
}
|
|
832
841
|
// Check if message already exists in the array (by ID) to prevent duplicates
|
|
833
842
|
// Messages can be emitted multiple times as they're updated (e.g., status changes)
|
|
@@ -974,7 +983,7 @@ export class ConversationChatAreaComponent {
|
|
|
974
983
|
* Called when completion is detected to discover newly delegated agent messages
|
|
975
984
|
*/
|
|
976
985
|
async reloadMessagesForActiveConversation() {
|
|
977
|
-
const conversationId = this.
|
|
986
|
+
const conversationId = this.conversationId;
|
|
978
987
|
if (!conversationId) {
|
|
979
988
|
return;
|
|
980
989
|
}
|
|
@@ -1084,9 +1093,8 @@ export class ConversationChatAreaComponent {
|
|
|
1084
1093
|
// Add the agent's response message to the conversation
|
|
1085
1094
|
this.messages = [...this.messages, event.message];
|
|
1086
1095
|
// Invalidate cache for this conversation since we have new messages
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
this.invalidateConversationCache(conversationId);
|
|
1096
|
+
if (this.conversationId) {
|
|
1097
|
+
this.invalidateConversationCache(this.conversationId);
|
|
1090
1098
|
}
|
|
1091
1099
|
// Scroll to bottom when agent responds
|
|
1092
1100
|
this.scrollToBottom = true;
|
|
@@ -1367,7 +1375,7 @@ export class ConversationChatAreaComponent {
|
|
|
1367
1375
|
await this.loadArtifactPermissions(artifactId);
|
|
1368
1376
|
}
|
|
1369
1377
|
exportConversation() {
|
|
1370
|
-
if (this.
|
|
1378
|
+
if (this.conversation) {
|
|
1371
1379
|
this.showExportModal = true;
|
|
1372
1380
|
}
|
|
1373
1381
|
}
|
|
@@ -1378,20 +1386,19 @@ export class ConversationChatAreaComponent {
|
|
|
1378
1386
|
this.showExportModal = false;
|
|
1379
1387
|
}
|
|
1380
1388
|
async onProjectSelected(project) {
|
|
1381
|
-
|
|
1382
|
-
if (activeConv && project) {
|
|
1389
|
+
if (this.conversation && project) {
|
|
1383
1390
|
try {
|
|
1384
|
-
await this.
|
|
1391
|
+
await this.conversationData.saveConversation(this.conversation.ID, { ProjectID: project.ID }, this.currentUser);
|
|
1385
1392
|
this.showProjectSelector = false;
|
|
1386
1393
|
}
|
|
1387
1394
|
catch (error) {
|
|
1388
1395
|
console.error('Failed to assign project:', error);
|
|
1389
1396
|
}
|
|
1390
1397
|
}
|
|
1391
|
-
else if (
|
|
1398
|
+
else if (this.conversation && !project) {
|
|
1392
1399
|
// Remove project assignment
|
|
1393
1400
|
try {
|
|
1394
|
-
await this.
|
|
1401
|
+
await this.conversationData.saveConversation(this.conversation.ID, { ProjectID: null }, this.currentUser);
|
|
1395
1402
|
this.showProjectSelector = false;
|
|
1396
1403
|
}
|
|
1397
1404
|
catch (error) {
|
|
@@ -1404,25 +1411,24 @@ export class ConversationChatAreaComponent {
|
|
|
1404
1411
|
LogStatusEx({ message: 'Share conversation', verboseOnly: true });
|
|
1405
1412
|
}
|
|
1406
1413
|
onReplyInThread(message) {
|
|
1407
|
-
// Open thread panel for this message
|
|
1408
|
-
this.
|
|
1414
|
+
// Open thread panel for this message - emit to parent
|
|
1415
|
+
this.threadOpened.emit(message.ID);
|
|
1409
1416
|
}
|
|
1410
1417
|
onViewThread(message) {
|
|
1411
|
-
// Open thread panel for this message
|
|
1412
|
-
this.
|
|
1418
|
+
// Open thread panel for this message - emit to parent
|
|
1419
|
+
this.threadOpened.emit(message.ID);
|
|
1413
1420
|
}
|
|
1414
|
-
|
|
1415
|
-
// Close the thread panel
|
|
1416
|
-
this.
|
|
1421
|
+
onLocalThreadClosed() {
|
|
1422
|
+
// Close the thread panel - emit to parent
|
|
1423
|
+
this.threadClosed.emit();
|
|
1417
1424
|
}
|
|
1418
1425
|
onThreadReplyAdded(reply) {
|
|
1419
1426
|
// Optionally refresh the message list to update thread counts
|
|
1420
1427
|
// For now, we'll just log it
|
|
1421
1428
|
LogStatusEx({ message: 'Thread reply added', verboseOnly: true, additionalArgs: [reply] });
|
|
1422
1429
|
// Reload messages to get updated thread counts
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
this.loadMessages(activeConv.ID);
|
|
1430
|
+
if (this.conversationId) {
|
|
1431
|
+
this.loadMessages(this.conversationId);
|
|
1426
1432
|
}
|
|
1427
1433
|
}
|
|
1428
1434
|
onToggleAgentPanel() {
|
|
@@ -1448,10 +1454,10 @@ export class ConversationChatAreaComponent {
|
|
|
1448
1454
|
async onSuggestedResponseSelected(event) {
|
|
1449
1455
|
const messageText = event.customInput || event.text;
|
|
1450
1456
|
// If we have an active conversation with message input available, use it
|
|
1451
|
-
if (this.messageInputComponent && !this.
|
|
1457
|
+
if (this.messageInputComponent && !this.isNewConversation) {
|
|
1452
1458
|
await this.messageInputComponent.sendMessageWithText(messageText);
|
|
1453
1459
|
}
|
|
1454
|
-
else if (!this.
|
|
1460
|
+
else if (!this.conversation || this.isNewConversation) {
|
|
1455
1461
|
// If no conversation or in new unsaved state, route through empty state handler
|
|
1456
1462
|
// This will create the conversation and send the message
|
|
1457
1463
|
await this.onEmptyStateMessageSent(messageText);
|
|
@@ -1677,7 +1683,7 @@ export class ConversationChatAreaComponent {
|
|
|
1677
1683
|
}
|
|
1678
1684
|
/**
|
|
1679
1685
|
* Handle message sent from empty state component
|
|
1680
|
-
* Creates a new conversation and
|
|
1686
|
+
* Creates a new conversation and emits to parent to update selection
|
|
1681
1687
|
*/
|
|
1682
1688
|
async onEmptyStateMessageSent(messageText) {
|
|
1683
1689
|
if (!messageText || !messageText.trim()) {
|
|
@@ -1686,27 +1692,23 @@ export class ConversationChatAreaComponent {
|
|
|
1686
1692
|
LogStatusEx({ message: '📨 Empty state message received', verboseOnly: true, additionalArgs: [messageText] });
|
|
1687
1693
|
try {
|
|
1688
1694
|
this.isProcessing = true;
|
|
1689
|
-
//
|
|
1690
|
-
this.
|
|
1691
|
-
LogStatusEx({ message: '💾 Stored pending message in service', verboseOnly: true, additionalArgs: [this.conversationState.pendingMessageToSend] });
|
|
1692
|
-
// Create a new conversation
|
|
1693
|
-
const newConversation = await this.conversationState.createConversation('New Conversation', // Temporary name - will be auto-named after first message
|
|
1695
|
+
// Create a new conversation using the data service
|
|
1696
|
+
const newConversation = await this.conversationData.createConversation('New Conversation', // Temporary name - will be auto-named after first message
|
|
1694
1697
|
this.environmentId, this.currentUser);
|
|
1695
1698
|
if (!newConversation) {
|
|
1696
1699
|
console.error('❌ Failed to create new conversation');
|
|
1697
|
-
this.conversationState.pendingMessageToSend = null;
|
|
1698
1700
|
this.isProcessing = false;
|
|
1699
1701
|
return;
|
|
1700
1702
|
}
|
|
1701
1703
|
LogStatusEx({ message: '✅ Created new conversation', verboseOnly: true, additionalArgs: [newConversation.ID] });
|
|
1702
|
-
//
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1704
|
+
// Emit to parent with the new conversation AND the pending message
|
|
1705
|
+
// Parent will update its state and pass back the message via pendingMessage input
|
|
1706
|
+
this.conversationCreated.emit(newConversation);
|
|
1707
|
+
// Also emit the pending message to be sent (parent will pass it back via input)
|
|
1708
|
+
this.pendingMessageRequested.emit(messageText.trim());
|
|
1706
1709
|
}
|
|
1707
1710
|
catch (error) {
|
|
1708
1711
|
console.error('❌ Error creating conversation from empty state:', error);
|
|
1709
|
-
this.conversationState.pendingMessageToSend = null;
|
|
1710
1712
|
}
|
|
1711
1713
|
finally {
|
|
1712
1714
|
this.isProcessing = false;
|
|
@@ -1757,8 +1759,11 @@ export class ConversationChatAreaComponent {
|
|
|
1757
1759
|
this.taskClicked.emit(task);
|
|
1758
1760
|
}
|
|
1759
1761
|
onNavigateToConversation(event) {
|
|
1760
|
-
// Navigate to the conversation with the active task
|
|
1761
|
-
|
|
1762
|
+
// Navigate to the conversation with the active task - emit to parent
|
|
1763
|
+
// Parent will update its selection state
|
|
1764
|
+
// For now, we can't navigate to a different conversation from within chat area
|
|
1765
|
+
// This would require emitting an event to the parent
|
|
1766
|
+
console.log('Navigate to conversation requested:', event.conversationId);
|
|
1762
1767
|
}
|
|
1763
1768
|
/**
|
|
1764
1769
|
* Handle navigation request from artifact viewer Links tab
|
|
@@ -1894,22 +1899,22 @@ export class ConversationChatAreaComponent {
|
|
|
1894
1899
|
* Opens the artifact and scrolls to the message containing it
|
|
1895
1900
|
*/
|
|
1896
1901
|
async handlePendingArtifactNavigation() {
|
|
1897
|
-
|
|
1898
|
-
const pendingVersionNumber = this.conversationState.pendingArtifactVersionNumber;
|
|
1899
|
-
if (!pendingArtifactId) {
|
|
1902
|
+
if (!this.pendingArtifactId) {
|
|
1900
1903
|
return; // No pending navigation
|
|
1901
1904
|
}
|
|
1902
|
-
console.log('📦 Processing pending artifact navigation:', pendingArtifactId, 'v' +
|
|
1903
|
-
//
|
|
1904
|
-
this.
|
|
1905
|
-
this.
|
|
1905
|
+
console.log('📦 Processing pending artifact navigation:', this.pendingArtifactId, 'v' + this.pendingArtifactVersionNumber);
|
|
1906
|
+
// Capture values before emitting consumed event
|
|
1907
|
+
const artifactIdToOpen = this.pendingArtifactId;
|
|
1908
|
+
const versionNumberToOpen = this.pendingArtifactVersionNumber;
|
|
1909
|
+
// Notify parent that we consumed the pending artifact
|
|
1910
|
+
this.pendingArtifactConsumed.emit();
|
|
1906
1911
|
// Find the message containing this artifact version
|
|
1907
1912
|
let messageIdWithArtifact = null;
|
|
1908
1913
|
for (const [detailId, artifactList] of this.artifactsByDetailId.entries()) {
|
|
1909
1914
|
for (const artifactInfo of artifactList) {
|
|
1910
|
-
if (artifactInfo.artifactId ===
|
|
1915
|
+
if (artifactInfo.artifactId === artifactIdToOpen) {
|
|
1911
1916
|
// Found the artifact - check if version matches (if specified)
|
|
1912
|
-
if (
|
|
1917
|
+
if (versionNumberToOpen == null || artifactInfo.versionNumber === versionNumberToOpen) {
|
|
1913
1918
|
messageIdWithArtifact = detailId;
|
|
1914
1919
|
console.log('✅ Found artifact in message:', detailId);
|
|
1915
1920
|
break;
|
|
@@ -1920,15 +1925,15 @@ export class ConversationChatAreaComponent {
|
|
|
1920
1925
|
break;
|
|
1921
1926
|
}
|
|
1922
1927
|
if (!messageIdWithArtifact) {
|
|
1923
|
-
console.warn('⚠️ Could not find message containing artifact:',
|
|
1928
|
+
console.warn('⚠️ Could not find message containing artifact:', artifactIdToOpen);
|
|
1924
1929
|
return;
|
|
1925
1930
|
}
|
|
1926
1931
|
// Open the artifact panel
|
|
1927
|
-
this.selectedArtifactId =
|
|
1928
|
-
this.selectedVersionNumber =
|
|
1932
|
+
this.selectedArtifactId = artifactIdToOpen;
|
|
1933
|
+
this.selectedVersionNumber = versionNumberToOpen ?? undefined;
|
|
1929
1934
|
this.showArtifactPanel = true;
|
|
1930
1935
|
// Load permissions for the artifact
|
|
1931
|
-
await this.loadArtifactPermissions(
|
|
1936
|
+
await this.loadArtifactPermissions(artifactIdToOpen);
|
|
1932
1937
|
// Scroll to the message
|
|
1933
1938
|
this.scrollToMessage(messageIdWithArtifact);
|
|
1934
1939
|
console.log('✅ Opened artifact and scrolled to message:', messageIdWithArtifact);
|
|
@@ -1984,7 +1989,7 @@ export class ConversationChatAreaComponent {
|
|
|
1984
1989
|
this.cdr.detectChanges();
|
|
1985
1990
|
}
|
|
1986
1991
|
}
|
|
1987
|
-
static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.
|
|
1992
|
+
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)); };
|
|
1988
1993
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1989
1994
|
i0.ɵɵviewQuery(_c0, 5);
|
|
1990
1995
|
i0.ɵɵviewQuery(_c1, 5);
|
|
@@ -1994,7 +1999,7 @@ export class ConversationChatAreaComponent {
|
|
|
1994
1999
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
|
|
1995
2000
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponent = _t.first);
|
|
1996
2001
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
|
|
1997
|
-
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked" }, decls: 15, vars: 20, consts: [["scrollContainer", ""], ["messageInput", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [3, "currentUser", "disabled"], [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"], [1, "chat-header"], [1, "chat-info"], [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"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["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"], [3, "messageSent", "currentUser", "disabled"], ["text", "Loading conversation...", "size", "large"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap"], ["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"], [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", "initialMessage"], [3, "messageSent", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "initialMessage"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "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"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2002
|
+
} }, 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: 15, vars: 20, consts: [["scrollContainer", ""], ["messageInput", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [3, "currentUser", "disabled"], [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"], [1, "chat-header"], [1, "chat-info"], [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"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["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"], [3, "messageSent", "currentUser", "disabled"], ["text", "Loading conversation...", "size", "large"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap"], ["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"], [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", "initialMessage"], [3, "messageSent", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "initialMessage"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "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"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1998
2003
|
i0.ɵɵelementStart(0, "div", 2);
|
|
1999
2004
|
i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 21, 13, "div", 3);
|
|
2000
2005
|
i0.ɵɵelementStart(2, "div", 4)(3, "div", 5);
|
|
@@ -2014,23 +2019,23 @@ export class ConversationChatAreaComponent {
|
|
|
2014
2019
|
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);
|
|
2015
2020
|
} if (rf & 2) {
|
|
2016
2021
|
i0.ɵɵadvance();
|
|
2017
|
-
i0.ɵɵproperty("ngIf", ctx.
|
|
2022
|
+
i0.ɵɵproperty("ngIf", ctx.conversation);
|
|
2018
2023
|
i0.ɵɵadvance(2);
|
|
2019
2024
|
i0.ɵɵclassProp("full-width", !ctx.showArtifactPanel)("hidden", ctx.isArtifactPaneMaximized);
|
|
2020
2025
|
i0.ɵɵadvance();
|
|
2021
|
-
i0.ɵɵconditional(
|
|
2026
|
+
i0.ɵɵconditional(ctx.isNewConversation || !ctx.conversationId ? 4 : ctx.isLoadingConversation ? 5 : 6);
|
|
2022
2027
|
i0.ɵɵadvance(3);
|
|
2023
2028
|
i0.ɵɵconditional(ctx.showArtifactPanel && ctx.selectedArtifactId ? 7 : -1);
|
|
2024
2029
|
i0.ɵɵadvance();
|
|
2025
2030
|
i0.ɵɵproperty("isOpen", ctx.isArtifactShareModalOpen)("artifact", ctx.artifactToShare)("currentUser", ctx.currentUser);
|
|
2026
2031
|
i0.ɵɵadvance();
|
|
2027
|
-
i0.ɵɵconditional(ctx.
|
|
2032
|
+
i0.ɵɵconditional(ctx.threadId ? 9 : -1);
|
|
2028
2033
|
i0.ɵɵadvance();
|
|
2029
|
-
i0.ɵɵproperty("isVisible", ctx.showExportModal)("conversation", ctx.
|
|
2034
|
+
i0.ɵɵproperty("isVisible", ctx.showExportModal)("conversation", ctx.conversation || undefined)("currentUser", ctx.currentUser);
|
|
2030
2035
|
i0.ɵɵadvance();
|
|
2031
|
-
i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.
|
|
2036
|
+
i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.conversation || undefined)("currentUser", ctx.currentUser);
|
|
2032
2037
|
i0.ɵɵadvance();
|
|
2033
|
-
i0.ɵɵconditional(ctx.showProjectSelector && ctx.
|
|
2038
|
+
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ? 12 : -1);
|
|
2034
2039
|
i0.ɵɵadvance();
|
|
2035
2040
|
i0.ɵɵconditional(ctx.showArtifactsModal ? 13 : -1);
|
|
2036
2041
|
i0.ɵɵadvance();
|
|
@@ -2039,11 +2044,25 @@ export class ConversationChatAreaComponent {
|
|
|
2039
2044
|
}
|
|
2040
2045
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
2041
2046
|
type: Component,
|
|
2042
|
-
args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversationState.activeConversation as 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]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span>{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }}</span>\n </button>\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCountDisplay }} artifact{{ artifactCountDisplay !== 1 ? 's' : '' }}</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\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 Share\n </button>\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 (!conversationState.activeConversation || conversationState.isNewUnsavedConversation) {\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]=\"conversationState.activeConversation\"\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 !== conversationState.activeConversation.ID\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationState.activeConversation.ID ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationState.activeConversation.ID ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationState.activeConversation.ID ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationState.activeConversation.ID ? agentRunsByDetailId : emptyAgentRunsMap\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationState.activeConversation.ID ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing\"\n [initialMessage]=\"inputRef.conversationId === conversationState.activeConversation.ID ? conversationState.pendingMessageToSend : 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 </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 (conversationState.activeThreadId) {\n <mj-thread-panel\n [parentMessageId]=\"conversationState.activeThreadId\"\n [conversationId]=\"conversationState.activeConversation?.ID || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversationState.activeConversation || 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]=\"conversationState.activeConversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversationState.activeConversation) {\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]=\"conversationState.activeConversation.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 display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\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: 300px;\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: 8px;\n flex-direction: column;\n align-items: stretch;\n }\n .chat-info {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .chat-title {\n font-size: 14px;\n width: 100%;\n white-space: normal;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .chat-actions {\n flex-wrap: wrap;\n justify-content: flex-start;\n width: 100%;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 6px 10px;\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 */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 80px;\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: 6px;\n }\n .chat-title {\n font-size: 13px;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 4px 8px;\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"] }]
|
|
2043
|
-
}], () => [{ type: i1.
|
|
2047
|
+
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\">\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span>{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }}</span>\n </button>\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCountDisplay }} artifact{{ artifactCountDisplay !== 1 ? 's' : '' }}</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\">\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\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 Share\n </button>\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 </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 display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\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: 300px;\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: 8px;\n flex-direction: column;\n align-items: stretch;\n }\n .chat-info {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .chat-title {\n font-size: 14px;\n width: 100%;\n white-space: normal;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .chat-actions {\n flex-wrap: wrap;\n justify-content: flex-start;\n width: 100%;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 6px 10px;\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 */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 80px;\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: 6px;\n }\n .chat-title {\n font-size: 13px;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 4px 8px;\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"] }]
|
|
2048
|
+
}], () => [{ 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: [{
|
|
2044
2049
|
type: Input
|
|
2045
2050
|
}], currentUser: [{
|
|
2046
2051
|
type: Input
|
|
2052
|
+
}], conversationId: [{
|
|
2053
|
+
type: Input
|
|
2054
|
+
}], conversation: [{
|
|
2055
|
+
type: Input
|
|
2056
|
+
}], threadId: [{
|
|
2057
|
+
type: Input
|
|
2058
|
+
}], isNewConversation: [{
|
|
2059
|
+
type: Input
|
|
2060
|
+
}], pendingMessage: [{
|
|
2061
|
+
type: Input
|
|
2062
|
+
}], pendingArtifactId: [{
|
|
2063
|
+
type: Input
|
|
2064
|
+
}], pendingArtifactVersionNumber: [{
|
|
2065
|
+
type: Input
|
|
2047
2066
|
}], conversationRenamed: [{
|
|
2048
2067
|
type: Output
|
|
2049
2068
|
}], openEntityRecord: [{
|
|
@@ -2052,6 +2071,18 @@ export class ConversationChatAreaComponent {
|
|
|
2052
2071
|
type: Output
|
|
2053
2072
|
}], artifactLinkClicked: [{
|
|
2054
2073
|
type: Output
|
|
2074
|
+
}], conversationCreated: [{
|
|
2075
|
+
type: Output
|
|
2076
|
+
}], threadOpened: [{
|
|
2077
|
+
type: Output
|
|
2078
|
+
}], threadClosed: [{
|
|
2079
|
+
type: Output
|
|
2080
|
+
}], pendingArtifactConsumed: [{
|
|
2081
|
+
type: Output
|
|
2082
|
+
}], pendingMessageConsumed: [{
|
|
2083
|
+
type: Output
|
|
2084
|
+
}], pendingMessageRequested: [{
|
|
2085
|
+
type: Output
|
|
2055
2086
|
}], scrollContainer: [{
|
|
2056
2087
|
type: ViewChild,
|
|
2057
2088
|
args: ['scrollContainer']
|