@memberjunction/ng-conversations 2.107.0 → 2.108.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/artifact-collection-picker-modal.component.d.ts +67 -0
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -0
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +725 -0
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -0
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts +39 -0
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -0
- package/dist/lib/components/collection/artifact-create-modal.component.js +351 -0
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -0
- package/dist/lib/components/collection/collection-form-modal.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +60 -10
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +43 -0
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collection-share-modal.component.js +728 -0
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -0
- package/dist/lib/components/collection/collection-tree.component.d.ts +8 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +217 -115
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +2 -1
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +52 -34
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +45 -9
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +586 -220
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +42 -15
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +336 -219
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +7 -1
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +65 -10
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +39 -5
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +259 -137
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +5 -1
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +26 -12
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/message/suggested-responses.component.d.ts +55 -0
- package/dist/lib/components/message/suggested-responses.component.d.ts.map +1 -0
- package/dist/lib/components/message/suggested-responses.component.js +207 -0
- package/dist/lib/components/message/suggested-responses.component.js.map +1 -0
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +245 -113
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts +29 -0
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -0
- package/dist/lib/components/shared/user-picker.component.js +229 -0
- package/dist/lib/components/shared/user-picker.component.js.map +1 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +7 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +36 -6
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +19 -2
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +167 -58
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +52 -47
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +27 -4
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/models/conversation-complete-query.model.d.ts +75 -0
- package/dist/lib/models/conversation-complete-query.model.d.ts.map +1 -0
- package/dist/lib/models/conversation-complete-query.model.js +19 -0
- package/dist/lib/models/conversation-complete-query.model.js.map +1 -0
- package/dist/lib/models/conversation-state.model.d.ts +27 -0
- package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +5 -0
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +14 -9
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/collection-permission.service.d.ts +96 -0
- package/dist/lib/services/collection-permission.service.d.ts.map +1 -0
- package/dist/lib/services/collection-permission.service.js +303 -0
- package/dist/lib/services/collection-permission.service.js.map +1 -0
- package/dist/lib/services/collection-state.service.d.ts +34 -0
- package/dist/lib/services/collection-state.service.d.ts.map +1 -0
- package/dist/lib/services/collection-state.service.js +50 -0
- package/dist/lib/services/collection-state.service.js.map +1 -0
- package/dist/lib/services/conversation-agent.service.d.ts +9 -4
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +41 -12
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +5 -0
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +1 -1
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +0 -5
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/search.service.d.ts +26 -3
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +172 -12
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +12 -12
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { RunQuery, Metadata } from '@memberjunction/core';
|
|
3
3
|
import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
|
|
4
|
+
import { parseConversationDetailComplete } from '../../models/conversation-complete-query.model';
|
|
5
|
+
import { MessageInputComponent } from '../message/message-input.component';
|
|
6
|
+
import { ArtifactViewerPanelComponent } from '@memberjunction/ng-artifacts';
|
|
4
7
|
import { Subject } from 'rxjs';
|
|
5
8
|
import * as i0 from "@angular/core";
|
|
6
9
|
import * as i1 from "../../services/conversation-state.service";
|
|
7
|
-
import * as i2 from "../../services/
|
|
8
|
-
import * as i3 from "../../services/agent
|
|
9
|
-
import * as i4 from "../../services/
|
|
10
|
-
import * as i5 from "../../services/
|
|
10
|
+
import * as i2 from "../../services/agent-state.service";
|
|
11
|
+
import * as i3 from "../../services/conversation-agent.service";
|
|
12
|
+
import * as i4 from "../../services/active-tasks.service";
|
|
13
|
+
import * as i5 from "../../services/mention-autocomplete.service";
|
|
11
14
|
import * as i6 from "@angular/common";
|
|
12
15
|
import * as i7 from "@memberjunction/ng-artifacts";
|
|
13
|
-
import * as i8 from "../
|
|
14
|
-
import * as i9 from "../message/message-
|
|
15
|
-
import * as i10 from "../
|
|
16
|
-
import * as i11 from "../
|
|
17
|
-
import * as i12 from "../
|
|
18
|
-
import * as i13 from "../
|
|
19
|
-
import * as i14 from "../
|
|
20
|
-
import * as i15 from "../
|
|
16
|
+
import * as i8 from "../collection/artifact-collection-picker-modal.component";
|
|
17
|
+
import * as i9 from "../message/message-list.component";
|
|
18
|
+
import * as i10 from "../message/message-input.component";
|
|
19
|
+
import * as i11 from "../thread/thread-panel.component";
|
|
20
|
+
import * as i12 from "../project/project-selector.component";
|
|
21
|
+
import * as i13 from "../tasks/tasks-dropdown.component";
|
|
22
|
+
import * as i14 from "../agent/active-agent-indicator.component";
|
|
23
|
+
import * as i15 from "../members/members-modal.component";
|
|
24
|
+
import * as i16 from "../export/export-modal.component";
|
|
21
25
|
const _c0 = ["scrollContainer"];
|
|
22
26
|
const _forTrack0 = ($index, $item) => $item.artifactId;
|
|
23
27
|
const _forTrack1 = ($index, $item) => $item.versionId;
|
|
24
28
|
function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf & 1) {
|
|
25
29
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
26
|
-
i0.ɵɵelementStart(0, "button",
|
|
30
|
+
i0.ɵɵelementStart(0, "button", 31);
|
|
27
31
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.openProjectSelector()); });
|
|
28
|
-
i0.ɵɵelement(1, "i",
|
|
32
|
+
i0.ɵɵelement(1, "i", 32);
|
|
29
33
|
i0.ɵɵelementStart(2, "span");
|
|
30
34
|
i0.ɵɵtext(3);
|
|
31
35
|
i0.ɵɵelementEnd()();
|
|
@@ -36,9 +40,9 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
|
|
|
36
40
|
} }
|
|
37
41
|
function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf & 1) {
|
|
38
42
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
39
|
-
i0.ɵɵelementStart(0, "button",
|
|
43
|
+
i0.ɵɵelementStart(0, "button", 33);
|
|
40
44
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.viewArtifacts()); });
|
|
41
|
-
i0.ɵɵelement(1, "i",
|
|
45
|
+
i0.ɵɵelement(1, "i", 34);
|
|
42
46
|
i0.ɵɵelementStart(2, "span");
|
|
43
47
|
i0.ɵɵtext(3);
|
|
44
48
|
i0.ɵɵelementEnd()();
|
|
@@ -49,31 +53,31 @@ function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf
|
|
|
49
53
|
} }
|
|
50
54
|
function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
51
55
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
52
|
-
i0.ɵɵelementStart(0, "div",
|
|
56
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "div", 18)(2, "div", 19);
|
|
53
57
|
i0.ɵɵtext(3);
|
|
54
58
|
i0.ɵɵelementEnd();
|
|
55
|
-
i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button",
|
|
56
|
-
i0.ɵɵelementStart(5, "button",
|
|
59
|
+
i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 20);
|
|
60
|
+
i0.ɵɵelementStart(5, "button", 21);
|
|
57
61
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleMembersModal()); });
|
|
58
|
-
i0.ɵɵelement(6, "i",
|
|
62
|
+
i0.ɵɵelement(6, "i", 22);
|
|
59
63
|
i0.ɵɵelementStart(7, "span");
|
|
60
64
|
i0.ɵɵtext(8);
|
|
61
65
|
i0.ɵɵelementEnd()();
|
|
62
|
-
i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button",
|
|
63
|
-
i0.ɵɵelementStart(10, "mj-active-agent-indicator",
|
|
66
|
+
i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button", 23);
|
|
67
|
+
i0.ɵɵelementStart(10, "mj-active-agent-indicator", 24);
|
|
64
68
|
i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_10_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_10_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAgentSelected($event)); });
|
|
65
69
|
i0.ɵɵelementEnd()();
|
|
66
|
-
i0.ɵɵelementStart(11, "div",
|
|
70
|
+
i0.ɵɵelementStart(11, "div", 25)(12, "mj-tasks-dropdown", 26);
|
|
67
71
|
i0.ɵɵlistener("taskClicked", function ConversationChatAreaComponent_div_1_Template_mj_tasks_dropdown_taskClicked_12_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onTaskClicked($event)); });
|
|
68
72
|
i0.ɵɵelementEnd();
|
|
69
|
-
i0.ɵɵelementStart(13, "button",
|
|
73
|
+
i0.ɵɵelementStart(13, "button", 27);
|
|
70
74
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.exportConversation()); });
|
|
71
|
-
i0.ɵɵelement(14, "i",
|
|
75
|
+
i0.ɵɵelement(14, "i", 28);
|
|
72
76
|
i0.ɵɵtext(15, " Export ");
|
|
73
77
|
i0.ɵɵelementEnd();
|
|
74
|
-
i0.ɵɵelementStart(16, "button",
|
|
78
|
+
i0.ɵɵelementStart(16, "button", 29);
|
|
75
79
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.shareConversation()); });
|
|
76
|
-
i0.ɵɵelement(17, "i",
|
|
80
|
+
i0.ɵɵelement(17, "i", 30);
|
|
77
81
|
i0.ɵɵtext(18, " Share ");
|
|
78
82
|
i0.ɵɵelementEnd()()();
|
|
79
83
|
} if (rf & 2) {
|
|
@@ -97,21 +101,21 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
97
101
|
} }
|
|
98
102
|
function ConversationChatAreaComponent_span_8_Template(rf, ctx) { if (rf & 1) {
|
|
99
103
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
100
|
-
i0.ɵɵelementStart(0, "span",
|
|
104
|
+
i0.ɵɵelementStart(0, "span", 35);
|
|
101
105
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_span_8_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.scrollToBottomAnimate()); });
|
|
102
|
-
i0.ɵɵelement(1, "i",
|
|
106
|
+
i0.ɵɵelement(1, "i", 36);
|
|
103
107
|
i0.ɵɵelementEnd();
|
|
104
108
|
} }
|
|
105
109
|
function ConversationChatAreaComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
106
|
-
i0.ɵɵelementStart(0, "div", 10)(1, "div",
|
|
107
|
-
i0.ɵɵelement(2, "i",
|
|
110
|
+
i0.ɵɵelementStart(0, "div", 10)(1, "div", 37);
|
|
111
|
+
i0.ɵɵelement(2, "i", 38);
|
|
108
112
|
i0.ɵɵelementStart(3, "span");
|
|
109
113
|
i0.ɵɵtext(4, "Loading conversation data...");
|
|
110
114
|
i0.ɵɵelementEnd()()();
|
|
111
115
|
} }
|
|
112
116
|
function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template(rf, ctx) { if (rf & 1) {
|
|
113
117
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
114
|
-
i0.ɵɵelementStart(0, "mj-message-input",
|
|
118
|
+
i0.ɵɵelementStart(0, "mj-message-input", 40);
|
|
115
119
|
i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onAgentRunDetected($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onConversationRenamed($event)); });
|
|
116
120
|
i0.ɵɵelementEnd();
|
|
117
121
|
} if (rf & 2) {
|
|
@@ -119,18 +123,18 @@ function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Templat
|
|
|
119
123
|
i0.ɵɵproperty("conversationId", ctx_r3.conversationState.activeConversation.ID)("currentUser", ctx_r3.currentUser)("conversationHistory", ctx_r3.messages)("disabled", ctx_r3.isProcessing);
|
|
120
124
|
} }
|
|
121
125
|
function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
122
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template, 1, 4, "mj-message-input",
|
|
126
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template, 1, 4, "mj-message-input", 39);
|
|
123
127
|
} if (rf & 2) {
|
|
124
128
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
125
129
|
i0.ɵɵproperty("ngIf", ctx_r3.conversationState.activeConversation);
|
|
126
130
|
} }
|
|
127
131
|
function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
128
132
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
129
|
-
i0.ɵɵelementStart(0, "div",
|
|
133
|
+
i0.ɵɵelementStart(0, "div", 41);
|
|
130
134
|
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_12_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onResizeStart($event)); });
|
|
131
135
|
i0.ɵɵelementEnd();
|
|
132
|
-
i0.ɵɵelementStart(1, "div",
|
|
133
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseArtifactPanel()); });
|
|
136
|
+
i0.ɵɵelementStart(1, "div", 42)(2, "mj-artifact-viewer-panel", 43);
|
|
137
|
+
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_12_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSaveToCollectionRequested($event)); });
|
|
134
138
|
i0.ɵɵelementEnd()();
|
|
135
139
|
} if (rf & 2) {
|
|
136
140
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -141,7 +145,7 @@ function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf
|
|
|
141
145
|
} }
|
|
142
146
|
function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
143
147
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
144
|
-
i0.ɵɵelementStart(0, "mj-thread-panel",
|
|
148
|
+
i0.ɵɵelementStart(0, "mj-thread-panel", 44);
|
|
145
149
|
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_13_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onThreadClosed()); })("replyAdded", function ConversationChatAreaComponent_Conditional_13_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onThreadReplyAdded($event)); });
|
|
146
150
|
i0.ɵɵelementEnd();
|
|
147
151
|
} if (rf & 2) {
|
|
@@ -150,18 +154,18 @@ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf
|
|
|
150
154
|
} }
|
|
151
155
|
function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
152
156
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
153
|
-
i0.ɵɵelementStart(0, "div",
|
|
157
|
+
i0.ɵɵelementStart(0, "div", 45);
|
|
154
158
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
|
|
155
|
-
i0.ɵɵelementStart(1, "div",
|
|
159
|
+
i0.ɵɵelementStart(1, "div", 46);
|
|
156
160
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
157
|
-
i0.ɵɵelementStart(2, "div",
|
|
161
|
+
i0.ɵɵelementStart(2, "div", 47)(3, "h3");
|
|
158
162
|
i0.ɵɵtext(4, "Assign Project");
|
|
159
163
|
i0.ɵɵelementEnd();
|
|
160
|
-
i0.ɵɵelementStart(5, "button",
|
|
164
|
+
i0.ɵɵelementStart(5, "button", 48);
|
|
161
165
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
|
|
162
|
-
i0.ɵɵelement(6, "i",
|
|
166
|
+
i0.ɵɵelement(6, "i", 49);
|
|
163
167
|
i0.ɵɵelementEnd()();
|
|
164
|
-
i0.ɵɵelementStart(7, "div",
|
|
168
|
+
i0.ɵɵelementStart(7, "div", 50)(8, "mj-project-selector", 51);
|
|
165
169
|
i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_16_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onProjectSelected($event)); });
|
|
166
170
|
i0.ɵɵelementEnd()()()();
|
|
167
171
|
} if (rf & 2) {
|
|
@@ -170,9 +174,9 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
|
|
|
170
174
|
i0.ɵɵproperty("environmentId", ctx_r3.environmentId)("currentUser", ctx_r3.currentUser)("selectedProjectId", ctx_r3.conversationState.activeConversation.ProjectID);
|
|
171
175
|
} }
|
|
172
176
|
function ConversationChatAreaComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
173
|
-
i0.ɵɵelementStart(0, "div",
|
|
174
|
-
i0.ɵɵelement(1, "i",
|
|
175
|
-
i0.ɵɵelementStart(2, "p",
|
|
177
|
+
i0.ɵɵelementStart(0, "div", 54);
|
|
178
|
+
i0.ɵɵelement(1, "i", 56);
|
|
179
|
+
i0.ɵɵelementStart(2, "p", 57);
|
|
176
180
|
i0.ɵɵtext(3, "No artifacts in this conversation yet");
|
|
177
181
|
i0.ɵɵelementEnd()();
|
|
178
182
|
} }
|
|
@@ -187,9 +191,9 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Templ
|
|
|
187
191
|
} }
|
|
188
192
|
function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
189
193
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
190
|
-
i0.ɵɵelementStart(0, "button",
|
|
194
|
+
i0.ɵɵelementStart(0, "button", 69);
|
|
191
195
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r15); const artifact_r14 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.toggleArtifactExpansion(artifact_r14.artifactId, $event)); });
|
|
192
|
-
i0.ɵɵelement(1, "i",
|
|
196
|
+
i0.ɵɵelement(1, "i", 70);
|
|
193
197
|
i0.ɵɵelementEnd();
|
|
194
198
|
} if (rf & 2) {
|
|
195
199
|
const artifact_r14 = i0.ɵɵnextContext().$implicit;
|
|
@@ -199,15 +203,15 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Temp
|
|
|
199
203
|
} }
|
|
200
204
|
function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
201
205
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
202
|
-
i0.ɵɵelementStart(0, "div",
|
|
206
|
+
i0.ɵɵelementStart(0, "div", 72);
|
|
203
207
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r17 = i0.ɵɵrestoreView(_r16).$implicit; const artifact_r14 = i0.ɵɵnextContext(2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.openArtifactFromModal(artifact_r14.artifactId, version_r17.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
204
|
-
i0.ɵɵelementStart(1, "span",
|
|
208
|
+
i0.ɵɵelementStart(1, "span", 73);
|
|
205
209
|
i0.ɵɵtext(2);
|
|
206
210
|
i0.ɵɵelementEnd();
|
|
207
|
-
i0.ɵɵelementStart(3, "span",
|
|
211
|
+
i0.ɵɵelementStart(3, "span", 74);
|
|
208
212
|
i0.ɵɵtext(4, "Open this version");
|
|
209
213
|
i0.ɵɵelementEnd();
|
|
210
|
-
i0.ɵɵelement(5, "i",
|
|
214
|
+
i0.ɵɵelement(5, "i", 75);
|
|
211
215
|
i0.ɵɵelementEnd();
|
|
212
216
|
} if (rf & 2) {
|
|
213
217
|
const version_r17 = ctx.$implicit;
|
|
@@ -215,8 +219,8 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_
|
|
|
215
219
|
i0.ɵɵtextInterpolate1("v", version_r17.versionNumber, "");
|
|
216
220
|
} }
|
|
217
221
|
function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
218
|
-
i0.ɵɵelementStart(0, "div",
|
|
219
|
-
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template, 6, 1, "div",
|
|
222
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
223
|
+
i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template, 6, 1, "div", 71, _forTrack1);
|
|
220
224
|
i0.ɵɵelementEnd();
|
|
221
225
|
} if (rf & 2) {
|
|
222
226
|
const artifact_r14 = i0.ɵɵnextContext().$implicit;
|
|
@@ -225,22 +229,22 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Temp
|
|
|
225
229
|
} }
|
|
226
230
|
function ConversationChatAreaComponent_Conditional_17_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
227
231
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
228
|
-
i0.ɵɵelementStart(0, "div",
|
|
232
|
+
i0.ɵɵelementStart(0, "div", 58)(1, "div", 59);
|
|
229
233
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Template_div_click_1_listener() { const artifact_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.openArtifactFromModal(artifact_r14.artifactId)); });
|
|
230
|
-
i0.ɵɵelementStart(2, "div",
|
|
231
|
-
i0.ɵɵelement(3, "i",
|
|
234
|
+
i0.ɵɵelementStart(2, "div", 60);
|
|
235
|
+
i0.ɵɵelement(3, "i", 61);
|
|
232
236
|
i0.ɵɵelementEnd();
|
|
233
|
-
i0.ɵɵelementStart(4, "div",
|
|
237
|
+
i0.ɵɵelementStart(4, "div", 62)(5, "div", 63);
|
|
234
238
|
i0.ɵɵtext(6);
|
|
235
239
|
i0.ɵɵelementEnd();
|
|
236
|
-
i0.ɵɵelementStart(7, "div",
|
|
240
|
+
i0.ɵɵelementStart(7, "div", 64);
|
|
237
241
|
i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Template, 1, 0);
|
|
238
242
|
i0.ɵɵelementEnd()();
|
|
239
|
-
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template, 2, 4, "button",
|
|
240
|
-
i0.ɵɵelementStart(11, "div",
|
|
241
|
-
i0.ɵɵelement(12, "i",
|
|
243
|
+
i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template, 2, 4, "button", 65);
|
|
244
|
+
i0.ɵɵelementStart(11, "div", 66);
|
|
245
|
+
i0.ɵɵelement(12, "i", 67);
|
|
242
246
|
i0.ɵɵelementEnd()();
|
|
243
|
-
i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template, 3, 0, "div",
|
|
247
|
+
i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template, 3, 0, "div", 68);
|
|
244
248
|
i0.ɵɵelementEnd();
|
|
245
249
|
} if (rf & 2) {
|
|
246
250
|
const artifact_r14 = ctx.$implicit;
|
|
@@ -257,20 +261,20 @@ function ConversationChatAreaComponent_Conditional_17_For_10_Template(rf, ctx) {
|
|
|
257
261
|
} }
|
|
258
262
|
function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
259
263
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
260
|
-
i0.ɵɵelementStart(0, "div",
|
|
264
|
+
i0.ɵɵelementStart(0, "div", 45);
|
|
261
265
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showArtifactsModal = false); });
|
|
262
|
-
i0.ɵɵelementStart(1, "div",
|
|
266
|
+
i0.ɵɵelementStart(1, "div", 52);
|
|
263
267
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
264
|
-
i0.ɵɵelementStart(2, "div",
|
|
268
|
+
i0.ɵɵelementStart(2, "div", 47)(3, "h3");
|
|
265
269
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
266
270
|
i0.ɵɵelementEnd();
|
|
267
|
-
i0.ɵɵelementStart(5, "button",
|
|
271
|
+
i0.ɵɵelementStart(5, "button", 48);
|
|
268
272
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showArtifactsModal = false); });
|
|
269
|
-
i0.ɵɵelement(6, "i",
|
|
273
|
+
i0.ɵɵelement(6, "i", 49);
|
|
270
274
|
i0.ɵɵelementEnd()();
|
|
271
|
-
i0.ɵɵelementStart(7, "div",
|
|
272
|
-
i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div",
|
|
273
|
-
i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 14, 6, "div",
|
|
275
|
+
i0.ɵɵelementStart(7, "div", 53);
|
|
276
|
+
i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div", 54);
|
|
277
|
+
i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 14, 6, "div", 55, _forTrack0);
|
|
274
278
|
i0.ɵɵelementEnd()()();
|
|
275
279
|
} if (rf & 2) {
|
|
276
280
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -279,19 +283,30 @@ function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf
|
|
|
279
283
|
i0.ɵɵadvance();
|
|
280
284
|
i0.ɵɵrepeater(ctx_r3.getArtifactsArray());
|
|
281
285
|
} }
|
|
286
|
+
function ConversationChatAreaComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
287
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
288
|
+
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 76);
|
|
289
|
+
i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_18_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCollectionPickerSaved($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_18_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCollectionPickerCancelled()); });
|
|
290
|
+
i0.ɵɵelementEnd();
|
|
291
|
+
} if (rf & 2) {
|
|
292
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
293
|
+
i0.ɵɵproperty("isOpen", ctx_r3.showCollectionPicker)("environmentId", ctx_r3.environmentId)("currentUser", ctx_r3.currentUser)("excludeCollectionIds", ctx_r3.collectionPickerExcludedIds);
|
|
294
|
+
} }
|
|
282
295
|
export class ConversationChatAreaComponent {
|
|
283
296
|
conversationState;
|
|
284
|
-
dataCache;
|
|
285
297
|
agentStateService;
|
|
286
298
|
conversationAgentService;
|
|
287
299
|
activeTasks;
|
|
288
300
|
cdr;
|
|
301
|
+
mentionAutocompleteService;
|
|
289
302
|
environmentId;
|
|
290
303
|
currentUser;
|
|
291
304
|
conversationRenamed = new EventEmitter();
|
|
292
305
|
openEntityRecord = new EventEmitter();
|
|
293
306
|
taskClicked = new EventEmitter();
|
|
294
307
|
scrollContainer;
|
|
308
|
+
messageInputComponent;
|
|
309
|
+
artifactViewerComponent;
|
|
295
310
|
messages = [];
|
|
296
311
|
showScrollToBottomIcon = false;
|
|
297
312
|
scrollToBottom = false;
|
|
@@ -311,6 +326,12 @@ export class ConversationChatAreaComponent {
|
|
|
311
326
|
selectedVersionNumber = undefined; // Version to show in artifact viewer
|
|
312
327
|
artifactPaneWidth = 40; // Default 40% width
|
|
313
328
|
expandedArtifactId = null; // Track which artifact card is expanded in modal
|
|
329
|
+
showCollectionPicker = false;
|
|
330
|
+
collectionPickerArtifactId = null;
|
|
331
|
+
collectionPickerExcludedIds = [];
|
|
332
|
+
// Conversation data cache: ConversationID -> Array of ConversationDetailComplete
|
|
333
|
+
// Stores raw query results so we don't need to re-query when switching conversations
|
|
334
|
+
conversationDataCache = new Map();
|
|
314
335
|
// Artifact mapping: ConversationDetailID -> Array of LazyArtifactInfo
|
|
315
336
|
// Uses lazy-loading pattern: display data loaded immediately, full entities on-demand
|
|
316
337
|
// Supports multiple artifacts per conversation detail (0-N relationship)
|
|
@@ -328,15 +349,18 @@ export class ConversationChatAreaComponent {
|
|
|
328
349
|
startWidth = 0;
|
|
329
350
|
// LocalStorage key
|
|
330
351
|
ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
|
|
331
|
-
constructor(conversationState,
|
|
352
|
+
constructor(conversationState, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService) {
|
|
332
353
|
this.conversationState = conversationState;
|
|
333
|
-
this.dataCache = dataCache;
|
|
334
354
|
this.agentStateService = agentStateService;
|
|
335
355
|
this.conversationAgentService = conversationAgentService;
|
|
336
356
|
this.activeTasks = activeTasks;
|
|
337
357
|
this.cdr = cdr;
|
|
358
|
+
this.mentionAutocompleteService = mentionAutocompleteService;
|
|
338
359
|
}
|
|
339
|
-
ngOnInit() {
|
|
360
|
+
async ngOnInit() {
|
|
361
|
+
// Initialize mention service BEFORE loading messages
|
|
362
|
+
// This ensures agents are loaded and available for @mention parsing in existing messages
|
|
363
|
+
await this.mentionAutocompleteService.initialize(this.currentUser);
|
|
340
364
|
// Load saved artifact pane width
|
|
341
365
|
this.loadArtifactPaneWidth();
|
|
342
366
|
// Initial load if there's already an active conversation
|
|
@@ -392,18 +416,41 @@ export class ConversationChatAreaComponent {
|
|
|
392
416
|
}
|
|
393
417
|
async loadMessages(conversationId) {
|
|
394
418
|
try {
|
|
395
|
-
//
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
419
|
+
// Check if we have cached data for this conversation
|
|
420
|
+
const cachedData = this.conversationDataCache.get(conversationId);
|
|
421
|
+
if (cachedData) {
|
|
422
|
+
// Use cached data - instant load!
|
|
423
|
+
console.log(`📦 Loading conversation ${conversationId} from cache - instant!`);
|
|
424
|
+
this.buildMessagesFromCache(cachedData);
|
|
425
|
+
this.loadPeripheralData(conversationId); // Process cached data for maps
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
// Load from database with single optimized query
|
|
429
|
+
console.log(`🔍 Loading conversation ${conversationId} from database - single query`);
|
|
430
|
+
const rq = new RunQuery();
|
|
431
|
+
const result = await rq.RunQuery({
|
|
432
|
+
QueryName: 'GetConversationComplete',
|
|
433
|
+
CategoryPath: 'MJ/Conversations',
|
|
434
|
+
Parameters: { ConversationID: conversationId }
|
|
435
|
+
}, this.currentUser);
|
|
436
|
+
if (!result.Success || !result.Results) {
|
|
437
|
+
console.error('Failed to load conversation data:', result.ErrorMessage);
|
|
438
|
+
this.messages = [];
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// Cache the raw results for future use
|
|
442
|
+
const conversationData = result.Results;
|
|
443
|
+
this.conversationDataCache.set(conversationId, conversationData);
|
|
444
|
+
console.log(`💾 Cached ${conversationData.length} conversation details for conversation ${conversationId}`);
|
|
445
|
+
// Build messages and show immediately
|
|
446
|
+
this.buildMessagesFromCache(conversationData);
|
|
447
|
+
// Process peripheral data (agent runs & artifacts) in background
|
|
448
|
+
this.isLoadingPeripheralData = true;
|
|
449
|
+
this.loadPeripheralData(conversationId).finally(() => {
|
|
450
|
+
this.isLoadingPeripheralData = false;
|
|
451
|
+
this.cdr.detectChanges();
|
|
452
|
+
});
|
|
453
|
+
}
|
|
407
454
|
}
|
|
408
455
|
catch (error) {
|
|
409
456
|
console.error('Error loading messages:', error);
|
|
@@ -411,118 +458,112 @@ export class ConversationChatAreaComponent {
|
|
|
411
458
|
}
|
|
412
459
|
}
|
|
413
460
|
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
461
|
+
* Build message entities from cached conversation data
|
|
462
|
+
* Creates ConversationDetailEntity objects from the raw query results
|
|
463
|
+
*/
|
|
464
|
+
async buildMessagesFromCache(conversationData) {
|
|
465
|
+
const md = new Metadata();
|
|
466
|
+
const messages = [];
|
|
467
|
+
for (const row of conversationData) {
|
|
468
|
+
if (!row.ID)
|
|
469
|
+
continue;
|
|
470
|
+
// Create entity object and load from raw data
|
|
471
|
+
const message = await md.GetEntityObject('Conversation Details', this.currentUser);
|
|
472
|
+
// LoadFromData expects the same structure as the query result
|
|
473
|
+
// Since we're using SELECT *, all fields should be present
|
|
474
|
+
message.LoadFromData(row);
|
|
475
|
+
messages.push(message);
|
|
476
|
+
}
|
|
477
|
+
this.messages = messages;
|
|
478
|
+
this.scrollToBottom = true;
|
|
479
|
+
this.cdr.detectChanges(); // Show messages immediately
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Process peripheral data (agent runs and artifacts) from cached conversation data
|
|
483
|
+
* Parses JSON columns and builds maps for display
|
|
421
484
|
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
485
|
+
* PERFORMANCE OPTIMIZATION: Uses cached data instead of querying
|
|
486
|
+
* - Data already loaded by loadMessages() - no additional queries needed
|
|
487
|
+
* - Processes cached JSON data to build display maps
|
|
488
|
+
* - Instant when switching between conversations
|
|
424
489
|
*/
|
|
425
490
|
async loadPeripheralData(conversationId) {
|
|
426
|
-
|
|
427
|
-
|
|
491
|
+
const timestamp = new Date().toISOString();
|
|
492
|
+
// Skip if we've already processed peripheral data for this conversation
|
|
428
493
|
if (this.lastLoadedConversationId === conversationId) {
|
|
429
|
-
console.log(
|
|
494
|
+
console.log(`[${timestamp}] ⏭️ Skipping peripheral data processing - already processed for conversation ${conversationId}`);
|
|
430
495
|
return;
|
|
431
496
|
}
|
|
432
|
-
// Mark this conversation as
|
|
497
|
+
// Mark this conversation as processed to prevent duplicate processing
|
|
433
498
|
this.lastLoadedConversationId = conversationId;
|
|
434
|
-
console.log(
|
|
499
|
+
console.log(`[${timestamp}] 📊 Processing peripheral data for conversation ${conversationId} from cache`);
|
|
435
500
|
try {
|
|
436
|
-
|
|
437
|
-
const
|
|
501
|
+
// Get cached data - should always be present by the time we get here
|
|
502
|
+
const conversationData = this.conversationDataCache.get(conversationId);
|
|
503
|
+
if (!conversationData) {
|
|
504
|
+
console.warn(`No cached data found for conversation ${conversationId}`);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
438
507
|
const md = new Metadata();
|
|
439
|
-
|
|
440
|
-
// Load agent runs and artifacts in parallel
|
|
441
|
-
const [agentRunsResult, artifactMapResult] = await Promise.all([
|
|
442
|
-
rv.RunView({
|
|
443
|
-
EntityName: 'MJ: AI Agent Runs',
|
|
444
|
-
ExtraFilter: `ConversationDetailID IN (SELECT ID FROM [${convoDetailEntity.SchemaName}].[${convoDetailEntity.BaseView}] WHERE ConversationID='${conversationId}')`,
|
|
445
|
-
ResultType: 'entity_object',
|
|
446
|
-
// Only fetch fields we actually display to reduce payload size
|
|
447
|
-
Fields: ['ID', 'AgentID', 'Agent', 'Status', '__mj_CreatedAt', '__mj_UpdatedAt', 'TotalPromptTokensUsed', 'TotalCompletionTokensUsed', 'TotalCost', 'ConversationDetailID']
|
|
448
|
-
}, this.currentUser),
|
|
449
|
-
rq.RunQuery({
|
|
450
|
-
QueryName: 'GetConversationArtifactsMap',
|
|
451
|
-
CategoryPath: '/MJ/Conversations',
|
|
452
|
-
Parameters: { ConversationID: conversationId }
|
|
453
|
-
}, this.currentUser)
|
|
454
|
-
]);
|
|
455
|
-
// Build agent runs map - single query loads all runs for this conversation
|
|
508
|
+
// Clear and rebuild maps from cached data
|
|
456
509
|
this.agentRunsByDetailId.clear();
|
|
457
|
-
if (agentRunsResult.Success && agentRunsResult.Results) {
|
|
458
|
-
for (const run of agentRunsResult.Results) {
|
|
459
|
-
if (run.ConversationDetailID) {
|
|
460
|
-
this.agentRunsByDetailId.set(run.ConversationDetailID, run);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
// Build artifact map using batch-loading pattern for better performance
|
|
465
510
|
this.artifactsByDetailId.clear();
|
|
466
|
-
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
for (const row of artifactMapResult.Results) {
|
|
472
|
-
artifactIds.add(row.ArtifactID);
|
|
473
|
-
versionIds.add(row.ArtifactVersionID);
|
|
511
|
+
for (const row of conversationData) {
|
|
512
|
+
// Skip rows without ID (should never happen, but type safety check)
|
|
513
|
+
if (!row.ID) {
|
|
514
|
+
console.warn('Skipping conversation detail row without ID');
|
|
515
|
+
continue;
|
|
474
516
|
}
|
|
475
|
-
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
517
|
+
const parsed = parseConversationDetailComplete(row);
|
|
518
|
+
// Build agent runs map
|
|
519
|
+
if (parsed.agentRuns.length > 0) {
|
|
520
|
+
// Convert AgentRunJSON to AIAgentRunEntityExtended
|
|
521
|
+
const agentRunData = parsed.agentRuns[0]; // Should only be one per detail
|
|
522
|
+
const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
|
|
523
|
+
// Convert ISO date strings to Date objects
|
|
524
|
+
agentRun.LoadFromData({
|
|
525
|
+
ID: agentRunData.ID,
|
|
526
|
+
AgentID: agentRunData.AgentID,
|
|
527
|
+
Agent: agentRunData.Agent,
|
|
528
|
+
Status: agentRunData.Status,
|
|
529
|
+
__mj_CreatedAt: new Date(agentRunData.__mj_CreatedAt),
|
|
530
|
+
__mj_UpdatedAt: new Date(agentRunData.__mj_UpdatedAt),
|
|
531
|
+
TotalPromptTokensUsed: agentRunData.TotalPromptTokensUsed,
|
|
532
|
+
TotalCompletionTokensUsed: agentRunData.TotalCompletionTokensUsed,
|
|
533
|
+
TotalCost: agentRunData.TotalCost,
|
|
534
|
+
ConversationDetailID: agentRunData.ConversationDetailID
|
|
535
|
+
});
|
|
536
|
+
this.agentRunsByDetailId.set(row.ID, agentRun);
|
|
537
|
+
}
|
|
538
|
+
// Build artifacts map - no need to load full entities, just create LazyArtifactInfo
|
|
539
|
+
if (parsed.artifacts.length > 0) {
|
|
540
|
+
const artifactList = [];
|
|
541
|
+
for (const artifactData of parsed.artifacts) {
|
|
542
|
+
// Create LazyArtifactInfo with display data from query
|
|
543
|
+
// Full entities will be loaded on-demand when artifact is clicked
|
|
544
|
+
const lazyInfo = new LazyArtifactInfo(artifactData, this.currentUser);
|
|
545
|
+
artifactList.push(lazyInfo);
|
|
546
|
+
}
|
|
547
|
+
this.artifactsByDetailId.set(row.ID, artifactList);
|
|
501
548
|
}
|
|
502
|
-
// Create new Map reference to trigger Angular change detection
|
|
503
|
-
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
504
|
-
console.log(`📦 Loaded ${this.artifactsByDetailId.size} artifact mappings for conversation ${conversationId} (batch-loaded, no lazy loading needed)`);
|
|
505
549
|
}
|
|
550
|
+
// Create new Map references to trigger Angular change detection
|
|
551
|
+
this.agentRunsByDetailId = new Map(this.agentRunsByDetailId);
|
|
552
|
+
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
506
553
|
// Update artifact count for header display (unique artifacts, not versions)
|
|
507
554
|
this.artifactCount = this.calculateUniqueArtifactCount();
|
|
508
|
-
// Debug: Log
|
|
509
|
-
console.log(`📊
|
|
510
|
-
console.log(`📦 Artifacts by Detail ID:`, Array.from(this.artifactsByDetailId.entries()).flatMap(([detailId, artifactList]) => artifactList.map(info => ({
|
|
511
|
-
conversationDetailId: detailId,
|
|
512
|
-
artifactId: info.artifactId,
|
|
513
|
-
artifactName: info.artifactName,
|
|
514
|
-
versionId: info.artifactVersionId,
|
|
515
|
-
versionNumber: info.versionNumber
|
|
516
|
-
}))));
|
|
555
|
+
// Debug: Log summary
|
|
556
|
+
console.log(`📊 Processed ${this.agentRunsByDetailId.size} agent runs, ${this.artifactsByDetailId.size} artifact mappings (${this.artifactCount} unique artifacts)`);
|
|
517
557
|
// CRITICAL: Trigger message re-render now that agent runs and artifacts are loaded
|
|
518
558
|
// This updates all message components with the newly loaded agent run data
|
|
519
559
|
this.messages = [...this.messages]; // Create new array reference to trigger change detection
|
|
520
560
|
this.cdr.detectChanges();
|
|
521
|
-
console.log(`✅ Peripheral data
|
|
561
|
+
console.log(`✅ Peripheral data processed successfully for conversation ${conversationId} from cache`);
|
|
522
562
|
}
|
|
523
563
|
catch (error) {
|
|
524
|
-
console.error('Failed to
|
|
564
|
+
console.error('Failed to process peripheral data:', error);
|
|
525
565
|
// Don't set lastLoadedConversationId on error so we can retry
|
|
566
|
+
this.lastLoadedConversationId = null;
|
|
526
567
|
}
|
|
527
568
|
}
|
|
528
569
|
/**
|
|
@@ -563,6 +604,11 @@ export class ConversationChatAreaComponent {
|
|
|
563
604
|
async onAgentResponse(event) {
|
|
564
605
|
// Add the agent's response message to the conversation
|
|
565
606
|
this.messages = [...this.messages, event.message];
|
|
607
|
+
// Invalidate cache for this conversation since we have new messages
|
|
608
|
+
const conversationId = this.conversationState.activeConversationId;
|
|
609
|
+
if (conversationId) {
|
|
610
|
+
this.invalidateConversationCache(conversationId);
|
|
611
|
+
}
|
|
566
612
|
// Scroll to bottom when agent responds
|
|
567
613
|
this.scrollToBottom = true;
|
|
568
614
|
// Add agent run to the map if present (fallback if not already loaded from progress)
|
|
@@ -579,24 +625,38 @@ export class ConversationChatAreaComponent {
|
|
|
579
625
|
if (this.artifactsByDetailId.has(event.message.ID) && !this.showArtifactPanel) {
|
|
580
626
|
const artifactList = this.artifactsByDetailId.get(event.message.ID);
|
|
581
627
|
if (artifactList && artifactList.length > 0) {
|
|
582
|
-
// Show the
|
|
583
|
-
this.selectedArtifactId = artifactList[
|
|
628
|
+
// Show the LAST (most recent) artifact - uses display data, no lazy load needed
|
|
629
|
+
this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
|
|
584
630
|
this.showArtifactPanel = true;
|
|
585
631
|
}
|
|
586
632
|
}
|
|
587
633
|
// Force change detection to update the UI
|
|
588
634
|
this.cdr.detectChanges();
|
|
589
635
|
}
|
|
636
|
+
/**
|
|
637
|
+
* Invalidate cached conversation data
|
|
638
|
+
* Called when new messages are added or conversation data changes
|
|
639
|
+
*/
|
|
640
|
+
invalidateConversationCache(conversationId) {
|
|
641
|
+
this.conversationDataCache.delete(conversationId);
|
|
642
|
+
console.log(`🗑️ Invalidated cache for conversation ${conversationId}`);
|
|
643
|
+
}
|
|
590
644
|
/**
|
|
591
645
|
* Add or update an agent run in the map
|
|
592
646
|
* Called when a new agent run completes to keep the map in sync
|
|
593
647
|
*/
|
|
594
648
|
async addAgentRunToMap(conversationDetailId, agentRunId) {
|
|
595
649
|
try {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
650
|
+
if (!this.agentRunsByDetailId.has(conversationDetailId)) {
|
|
651
|
+
const md = new Metadata();
|
|
652
|
+
const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
|
|
653
|
+
if (await agentRun.Load(agentRunId)) {
|
|
654
|
+
this.agentRunsByDetailId.set(conversationDetailId, agentRun);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
// nothing to do, temp console log to catch how many of these where we were wasting time
|
|
659
|
+
console.log(`⏭️ Agent run for detail ${conversationDetailId} already in map, skipping load`);
|
|
600
660
|
}
|
|
601
661
|
}
|
|
602
662
|
catch (error) {
|
|
@@ -606,48 +666,56 @@ export class ConversationChatAreaComponent {
|
|
|
606
666
|
/**
|
|
607
667
|
* Reload artifacts for a specific message ID
|
|
608
668
|
* Called after an artifact is created to update the UI immediately
|
|
609
|
-
*
|
|
669
|
+
* Invalidates and refreshes the conversation cache
|
|
610
670
|
*/
|
|
611
671
|
async reloadArtifactsForMessage(conversationDetailId) {
|
|
612
672
|
console.log(`🔄 Reloading artifacts for message ${conversationDetailId}`);
|
|
613
673
|
try {
|
|
614
674
|
const rq = new RunQuery();
|
|
615
|
-
// Get the ConversationID for this detail
|
|
616
675
|
const md = new Metadata();
|
|
676
|
+
// Get the ConversationID for this detail
|
|
617
677
|
const detail = await md.GetEntityObject('Conversation Details', this.currentUser);
|
|
618
678
|
if (!(await detail.Load(conversationDetailId))) {
|
|
619
679
|
console.error('Failed to load conversation detail');
|
|
620
680
|
return;
|
|
621
681
|
}
|
|
622
|
-
//
|
|
623
|
-
|
|
624
|
-
|
|
682
|
+
// Invalidate cache since artifacts changed
|
|
683
|
+
this.invalidateConversationCache(detail.ConversationID);
|
|
684
|
+
// Use optimized single query to reload all conversation data
|
|
685
|
+
const result = await rq.RunQuery({
|
|
686
|
+
QueryName: 'GetConversationComplete',
|
|
625
687
|
CategoryPath: '/MJ/Conversations',
|
|
626
688
|
Parameters: { ConversationID: detail.ConversationID }
|
|
627
689
|
}, this.currentUser);
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
if (
|
|
639
|
-
const
|
|
640
|
-
for
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
690
|
+
if (!result.Success || !result.Results) {
|
|
691
|
+
console.error('Failed to reload artifacts:', result.ErrorMessage);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
console.log(`📊 Query result: ${result.Results.length} conversation details loaded`);
|
|
695
|
+
// Update cache with fresh data
|
|
696
|
+
const conversationData = result.Results;
|
|
697
|
+
this.conversationDataCache.set(detail.ConversationID, conversationData);
|
|
698
|
+
// Find the specific conversation detail we're reloading and update its artifacts
|
|
699
|
+
for (const row of conversationData) {
|
|
700
|
+
if (row.ID === conversationDetailId) {
|
|
701
|
+
const parsed = parseConversationDetailComplete(row);
|
|
702
|
+
// Clear existing artifacts for this detail and rebuild
|
|
703
|
+
this.artifactsByDetailId.delete(conversationDetailId);
|
|
704
|
+
if (parsed.artifacts.length > 0) {
|
|
705
|
+
const artifactList = [];
|
|
706
|
+
for (const artifactData of parsed.artifacts) {
|
|
707
|
+
const lazyInfo = new LazyArtifactInfo(artifactData, this.currentUser);
|
|
708
|
+
artifactList.push(lazyInfo);
|
|
709
|
+
console.log(`✅ Loaded artifact ${artifactData.ArtifactID} v${artifactData.VersionNumber} for message ${conversationDetailId}`);
|
|
710
|
+
}
|
|
711
|
+
this.artifactsByDetailId.set(conversationDetailId, artifactList);
|
|
644
712
|
}
|
|
645
|
-
|
|
713
|
+
// Create new Map reference to trigger Angular change detection
|
|
714
|
+
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
715
|
+
// Update artifact count
|
|
716
|
+
this.artifactCount = this.calculateUniqueArtifactCount();
|
|
717
|
+
break; // Found and updated the target message
|
|
646
718
|
}
|
|
647
|
-
// Create new Map reference to trigger Angular change detection
|
|
648
|
-
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
649
|
-
// Update artifact count
|
|
650
|
-
this.artifactCount = this.calculateUniqueArtifactCount();
|
|
651
719
|
}
|
|
652
720
|
}
|
|
653
721
|
catch (error) {
|
|
@@ -803,6 +871,19 @@ export class ConversationChatAreaComponent {
|
|
|
803
871
|
// The message entity is already updated in place, so no need to reload
|
|
804
872
|
// Just ensure the UI reflects the changes
|
|
805
873
|
}
|
|
874
|
+
/**
|
|
875
|
+
* Handle suggested response selection from user
|
|
876
|
+
* Sends the selected response as a new user message WITHOUT modifying the visible input
|
|
877
|
+
*/
|
|
878
|
+
async onSuggestedResponseSelected(event) {
|
|
879
|
+
const messageText = event.customInput || event.text;
|
|
880
|
+
if (this.messageInputComponent) {
|
|
881
|
+
await this.messageInputComponent.sendMessageWithText(messageText);
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
console.error('MessageInputComponent not available');
|
|
885
|
+
}
|
|
886
|
+
}
|
|
806
887
|
onRetryMessage(message) {
|
|
807
888
|
// TODO: Implement retry logic
|
|
808
889
|
// This should find the parent user message and re-trigger the agent invocation
|
|
@@ -849,6 +930,28 @@ export class ConversationChatAreaComponent {
|
|
|
849
930
|
this.showArtifactPanel = false;
|
|
850
931
|
this.selectedArtifactId = null;
|
|
851
932
|
}
|
|
933
|
+
onSaveToCollectionRequested(event) {
|
|
934
|
+
this.collectionPickerArtifactId = event.artifactId;
|
|
935
|
+
this.collectionPickerExcludedIds = event.excludedCollectionIds;
|
|
936
|
+
this.showCollectionPicker = true;
|
|
937
|
+
}
|
|
938
|
+
async onCollectionPickerSaved(collectionIds) {
|
|
939
|
+
if (!this.collectionPickerArtifactId || !this.artifactViewerComponent) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
// Call the artifact viewer's save method
|
|
943
|
+
const success = await this.artifactViewerComponent.saveToCollections(collectionIds);
|
|
944
|
+
if (success) {
|
|
945
|
+
this.showCollectionPicker = false;
|
|
946
|
+
this.collectionPickerArtifactId = null;
|
|
947
|
+
this.collectionPickerExcludedIds = [];
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
onCollectionPickerCancelled() {
|
|
951
|
+
this.showCollectionPicker = false;
|
|
952
|
+
this.collectionPickerArtifactId = null;
|
|
953
|
+
this.collectionPickerExcludedIds = [];
|
|
954
|
+
}
|
|
852
955
|
/**
|
|
853
956
|
* Helper method to check if a conversation detail has an artifact
|
|
854
957
|
* Used by message components to determine whether to show artifact card
|
|
@@ -858,12 +961,14 @@ export class ConversationChatAreaComponent {
|
|
|
858
961
|
}
|
|
859
962
|
/**
|
|
860
963
|
* Get artifact info for a conversation detail
|
|
861
|
-
* Returns the
|
|
964
|
+
* Returns the LAST (most recent) artifact if multiple exist
|
|
862
965
|
* Returns LazyArtifactInfo - caller can trigger lazy load if full entities needed
|
|
863
966
|
*/
|
|
864
967
|
getArtifactInfo(conversationDetailId) {
|
|
865
968
|
const artifactList = this.artifactsByDetailId.get(conversationDetailId);
|
|
866
|
-
return artifactList && artifactList.length > 0
|
|
969
|
+
return artifactList && artifactList.length > 0
|
|
970
|
+
? artifactList[artifactList.length - 1]
|
|
971
|
+
: undefined;
|
|
867
972
|
}
|
|
868
973
|
/**
|
|
869
974
|
* Get ALL artifacts for a conversation detail
|
|
@@ -979,20 +1084,24 @@ export class ConversationChatAreaComponent {
|
|
|
979
1084
|
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
|
|
980
1085
|
}
|
|
981
1086
|
}
|
|
982
|
-
static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationStateService), i0.ɵɵdirectiveInject(i2.
|
|
1087
|
+
static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationStateService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService)); };
|
|
983
1088
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
|
|
984
1089
|
i0.ɵɵviewQuery(_c0, 5);
|
|
1090
|
+
i0.ɵɵviewQuery(MessageInputComponent, 5);
|
|
1091
|
+
i0.ɵɵviewQuery(ArtifactViewerPanelComponent, 5);
|
|
985
1092
|
} if (rf & 2) {
|
|
986
1093
|
let _t;
|
|
987
1094
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
|
|
988
|
-
|
|
1095
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponent = _t.first);
|
|
1096
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
|
|
1097
|
+
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked" }, decls: 19, vars: 22, consts: [["scrollContainer", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [3, "conversationId", "currentUser", "conversationHistory", "disabled"], [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"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions"], [3, "taskClicked", "currentUser"], ["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 artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "loading-peripheral-content"], [1, "fas", "fa-spinner", "fa-spin"], [3, "conversationId", "currentUser", "conversationHistory", "disabled", "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", 4, "ngIf"], [3, "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", "conversationId", "currentUser", "conversationHistory", "disabled"], [1, "resize-handle", 3, "mousedown"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "artifactId", "currentUser", "environmentId", "versionNumber", "refreshTrigger"], [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-body", "artifacts-grid"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded"], [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) {
|
|
989
1098
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
990
1099
|
i0.ɵɵelementStart(0, "div", 1);
|
|
991
1100
|
i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 19, 11, "div", 2);
|
|
992
1101
|
i0.ɵɵelementStart(2, "div", 3)(3, "div", 4)(4, "div", 5)(5, "div", 6, 0);
|
|
993
1102
|
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Template_div_scroll_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.checkScroll()); });
|
|
994
1103
|
i0.ɵɵelementStart(7, "mj-conversation-message-list", 7);
|
|
995
|
-
i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_replyInThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_viewThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Template_mj_conversation_message_list_retryMessage_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRetryMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Template_mj_conversation_message_list_artifactClicked_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Template_mj_conversation_message_list_messageEdited_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Template_mj_conversation_message_list_openEntityRecord_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onOpenEntityRecord($event)); });
|
|
1104
|
+
i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_replyInThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Template_mj_conversation_message_list_viewThread_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Template_mj_conversation_message_list_retryMessage_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRetryMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Template_mj_conversation_message_list_artifactClicked_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Template_mj_conversation_message_list_messageEdited_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Template_mj_conversation_message_list_openEntityRecord_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Template_mj_conversation_message_list_suggestedResponseSelected_7_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSuggestedResponseSelected($event)); });
|
|
996
1105
|
i0.ɵɵelementEnd();
|
|
997
1106
|
i0.ɵɵtemplate(8, ConversationChatAreaComponent_span_8_Template, 2, 0, "span", 8);
|
|
998
1107
|
i0.ɵɵelementEnd();
|
|
@@ -1008,7 +1117,7 @@ export class ConversationChatAreaComponent {
|
|
|
1008
1117
|
i0.ɵɵelementStart(15, "mj-members-modal", 14);
|
|
1009
1118
|
i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_15_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_15_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); });
|
|
1010
1119
|
i0.ɵɵelementEnd();
|
|
1011
|
-
i0.ɵɵtemplate(16, ConversationChatAreaComponent_Conditional_16_Template, 9, 3, "div", 15)(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 15);
|
|
1120
|
+
i0.ɵɵtemplate(16, ConversationChatAreaComponent_Conditional_16_Template, 9, 3, "div", 15)(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 15)(18, ConversationChatAreaComponent_Conditional_18_Template, 1, 4, "mj-artifact-collection-picker-modal", 16);
|
|
1012
1121
|
} if (rf & 2) {
|
|
1013
1122
|
i0.ɵɵadvance();
|
|
1014
1123
|
i0.ɵɵproperty("ngIf", ctx.conversationState.activeConversation);
|
|
@@ -1032,12 +1141,14 @@ export class ConversationChatAreaComponent {
|
|
|
1032
1141
|
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversationState.activeConversation ? 16 : -1);
|
|
1033
1142
|
i0.ɵɵadvance();
|
|
1034
1143
|
i0.ɵɵconditional(ctx.showArtifactsModal ? 17 : -1);
|
|
1035
|
-
} }, dependencies: [i6.NgIf, i7.ArtifactViewerPanelComponent, i8.MessageListComponent, i9.MessageInputComponent, i10.ThreadPanelComponent, i11.ProjectSelectorComponent, i12.TasksDropdownComponent, i13.ActiveAgentIndicatorComponent, i14.MembersModalComponent, i15.ExportModalComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.chat-members[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.chat-members[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane[_ngcontent-%COMP%] {\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.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n.resize-handle[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\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.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] placeholder[_ngcontent-%COMP%] -[_ngcontent-%COMP%] replaces[_ngcontent-%COMP%] input[_ngcontent-%COMP%] while[_ngcontent-%COMP%] loading\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .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\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] content[_ngcontent-%COMP%] styling\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] });
|
|
1144
|
+
i0.ɵɵadvance();
|
|
1145
|
+
i0.ɵɵconditional(ctx.showCollectionPicker ? 18 : -1);
|
|
1146
|
+
} }, dependencies: [i6.NgIf, i7.ArtifactViewerPanelComponent, i8.ArtifactCollectionPickerModalComponent, i9.MessageListComponent, i10.MessageInputComponent, i11.ThreadPanelComponent, i12.ProjectSelectorComponent, i13.TasksDropdownComponent, i14.ActiveAgentIndicatorComponent, i15.MembersModalComponent, i16.ExportModalComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n.project-tag[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.chat-members[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members[_ngcontent-%COMP%]:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.chat-members[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n}\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n.chat-messages-pane[_ngcontent-%COMP%] {\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.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n}\n.resize-handle[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\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.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] placeholder[_ngcontent-%COMP%] -[_ngcontent-%COMP%] replaces[_ngcontent-%COMP%] input[_ngcontent-%COMP%] while[_ngcontent-%COMP%] loading\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n.empty-state[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n}\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .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\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] content[_ngcontent-%COMP%] styling\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n\n i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] });
|
|
1036
1147
|
}
|
|
1037
1148
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
1038
1149
|
type: Component,
|
|
1039
|
-
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=\"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=\"artifactCount > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCount }} artifact{{ artifactCount !== 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 <mj-tasks-dropdown\n [currentUser]=\"currentUser\"\n (taskClicked)=\"onTaskClicked($event)\">\n </mj-tasks-dropdown>\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\" [class.full-width]=\"!showArtifactPanel\">\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]=\"artifactsByDetailId\"\n [agentRunMap]=\"agentRunsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($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 <div class=\"loading-peripheral-content\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading conversation data...</span>\n </div>\n </div>\n } @else {\n <!-- Input Component -->\n <mj-message-input\n *ngIf=\"conversationState.activeConversation\"\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"messages\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\">\n </mj-message-input>\n }\n </div>\n </div>\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\"></div>\n <div class=\"chat-artifact-pane\" [style.width.%]=\"artifactPaneWidth\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\">\n </mj-artifact-viewer-panel>\n </div>\n }\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 <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\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\" [class.expanded]=\"expandedArtifactId === artifact.artifactId\">\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}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\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.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\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.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.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag i {\n font-size: 10px;\n}\n.chat-members {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members i {\n font-size: 12px;\n}\n.chat-members span {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator:hover {\n background: #2563EB;\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.ambient-agent-indicator i {\n color: #0076B6;\n}\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\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.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\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.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.chat-messages-pane.full-width {\n width: 100%;\n}\n.chat-messages-pane:not(.full-width) {\n flex: 1;\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.resize-handle:hover {\n background: #3B82F6;\n}\n.resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\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.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\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.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\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.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.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n// Loading placeholder - replaces input while loading\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\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.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.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.project-selector-modal {\n width: 600px;\n height: 500px;\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.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\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.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\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.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.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header:hover {\n background: #F9FAFB;\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.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.artifact-modal-icon i {\n font-size: 18px;\n}\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\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 &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .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\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n// Loading content styling\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 i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] }]
|
|
1040
|
-
}], () => [{ type: i1.ConversationStateService }, { type: i2.
|
|
1150
|
+
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=\"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=\"artifactCount > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCount }} artifact{{ artifactCount !== 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 <mj-tasks-dropdown\n [currentUser]=\"currentUser\"\n (taskClicked)=\"onTaskClicked($event)\">\n </mj-tasks-dropdown>\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\" [class.full-width]=\"!showArtifactPanel\">\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]=\"artifactsByDetailId\"\n [agentRunMap]=\"agentRunsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($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 <div class=\"loading-peripheral-content\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading conversation data...</span>\n </div>\n </div>\n } @else {\n <!-- Input Component -->\n <mj-message-input\n *ngIf=\"conversationState.activeConversation\"\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"messages\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\">\n </mj-message-input>\n }\n </div>\n </div>\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\"></div>\n <div class=\"chat-artifact-pane\" [style.width.%]=\"artifactPaneWidth\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\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 <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\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\" [class.expanded]=\"expandedArtifactId === artifact.artifactId\">\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.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\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.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\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.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.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n.project-tag i {\n font-size: 10px;\n}\n.chat-members {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: #F4F4F4;\n border: none;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 32px;\n}\n.chat-members:hover {\n background: #D9D9D9;\n color: #333;\n}\n.chat-members i {\n font-size: 12px;\n}\n.chat-members span {\n font-size: 12px;\n font-weight: 500;\n}\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: white;\n cursor: pointer;\n transition: all 150ms ease;\n}\n.artifact-indicator:hover {\n background: #2563EB;\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.ambient-agent-indicator i {\n color: #0076B6;\n}\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\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.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\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.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.chat-messages-pane.full-width {\n width: 100%;\n}\n.chat-messages-pane:not(.full-width) {\n flex: 1;\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.resize-handle:hover {\n background: #3B82F6;\n}\n.resize-handle::before {\n content: '';\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\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.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\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.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px; // 21px from bottom of visible scroll area (moved up 5px from original 16px)\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px; // Negative margin to not affect scroll height\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.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.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n border-top: 1px solid #E5E7EB;\n}\n\n// Loading placeholder - replaces input while loading\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px; // Match typical input area height\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.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.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.project-selector-modal {\n width: 600px;\n height: 500px;\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.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\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.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\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.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.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n.artifact-card-header:hover {\n background: #F9FAFB;\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.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.artifact-modal-icon i {\n font-size: 18px;\n}\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\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 &:hover {\n background: #F3F4F6;\n color: #3B82F6;\n }\n}\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n border-top: 1px solid #E5E7EB;\n background: #F9FAFB;\n}\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px; // Indent to align with title\n cursor: pointer;\n transition: background 0.15s;\n\n &:hover {\n background: #F3F4F6;\n }\n\n .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\n .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n }\n\n i {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n &:hover {\n .version-badge {\n background: #4F46E5;\n color: white;\n }\n .version-open-text {\n color: #3B82F6;\n }\n i {\n color: #3B82F6;\n }\n }\n}\n\n// Loading content styling\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 i {\n font-size: 20px;\n color: #9333EA;\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}"] }]
|
|
1151
|
+
}], () => [{ type: i1.ConversationStateService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }], { environmentId: [{
|
|
1041
1152
|
type: Input
|
|
1042
1153
|
}], currentUser: [{
|
|
1043
1154
|
type: Input
|
|
@@ -1050,6 +1161,12 @@ export class ConversationChatAreaComponent {
|
|
|
1050
1161
|
}], scrollContainer: [{
|
|
1051
1162
|
type: ViewChild,
|
|
1052
1163
|
args: ['scrollContainer']
|
|
1164
|
+
}], messageInputComponent: [{
|
|
1165
|
+
type: ViewChild,
|
|
1166
|
+
args: [MessageInputComponent]
|
|
1167
|
+
}], artifactViewerComponent: [{
|
|
1168
|
+
type: ViewChild,
|
|
1169
|
+
args: [ArtifactViewerPanelComponent]
|
|
1053
1170
|
}] }); })();
|
|
1054
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber:
|
|
1171
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 20 }); })();
|
|
1055
1172
|
//# sourceMappingURL=conversation-chat-area.component.js.map
|