@memberjunction/ng-conversations 2.104.0 → 2.106.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.
Files changed (106) hide show
  1. package/dist/lib/components/collection/collection-view.component.d.ts +5 -1
  2. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  3. package/dist/lib/components/collection/collection-view.component.js +53 -11
  4. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  5. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +53 -13
  6. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  7. package/dist/lib/components/conversation/conversation-chat-area.component.js +455 -289
  8. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-list.component.d.ts +9 -1
  10. package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-list.component.js +258 -71
  12. package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
  13. package/dist/lib/components/mention/mention-dropdown.component.d.ts +6 -0
  14. package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +1 -1
  15. package/dist/lib/components/mention/mention-dropdown.component.js +35 -13
  16. package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
  17. package/dist/lib/components/message/message-input.component.d.ts +49 -12
  18. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  19. package/dist/lib/components/message/message-input.component.js +579 -221
  20. package/dist/lib/components/message/message-input.component.js.map +1 -1
  21. package/dist/lib/components/message/message-item.component.d.ts +16 -5
  22. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  23. package/dist/lib/components/message/message-item.component.js +136 -64
  24. package/dist/lib/components/message/message-item.component.js.map +1 -1
  25. package/dist/lib/components/message/message-list.component.d.ts +11 -5
  26. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  27. package/dist/lib/components/message/message-list.component.js +48 -9
  28. package/dist/lib/components/message/message-list.component.js.map +1 -1
  29. package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -1
  30. package/dist/lib/components/navigation/conversation-navigation.component.js +24 -9
  31. package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -1
  32. package/dist/lib/components/task/tasks-full-view.component.d.ts +47 -0
  33. package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -0
  34. package/dist/lib/components/task/tasks-full-view.component.js +368 -0
  35. package/dist/lib/components/task/tasks-full-view.component.js.map +1 -0
  36. package/dist/lib/components/tasks/task-widget.component.d.ts +29 -0
  37. package/dist/lib/components/tasks/task-widget.component.d.ts.map +1 -0
  38. package/dist/lib/components/tasks/task-widget.component.js +385 -0
  39. package/dist/lib/components/tasks/task-widget.component.js.map +1 -0
  40. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +22 -8
  41. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  42. package/dist/lib/components/tasks/tasks-dropdown.component.js +195 -99
  43. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  44. package/dist/lib/components/thread/thread-panel.component.d.ts +3 -1
  45. package/dist/lib/components/thread/thread-panel.component.d.ts.map +1 -1
  46. package/dist/lib/components/thread/thread-panel.component.js +14 -14
  47. package/dist/lib/components/thread/thread-panel.component.js.map +1 -1
  48. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +43 -4
  49. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  50. package/dist/lib/components/workspace/conversation-workspace.component.js +288 -46
  51. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  52. package/dist/lib/conversations.module.d.ts +40 -46
  53. package/dist/lib/conversations.module.d.ts.map +1 -1
  54. package/dist/lib/conversations.module.js +28 -42
  55. package/dist/lib/conversations.module.js.map +1 -1
  56. package/dist/lib/models/conversation-state.model.d.ts +29 -1
  57. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  58. package/dist/lib/services/conversation-agent.service.d.ts +6 -5
  59. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  60. package/dist/lib/services/conversation-agent.service.js +18 -19
  61. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  62. package/dist/lib/services/data-cache.service.d.ts +96 -0
  63. package/dist/lib/services/data-cache.service.d.ts.map +1 -0
  64. package/dist/lib/services/data-cache.service.js +203 -0
  65. package/dist/lib/services/data-cache.service.js.map +1 -0
  66. package/dist/public-api.d.ts +3 -6
  67. package/dist/public-api.d.ts.map +1 -1
  68. package/dist/public-api.js +3 -6
  69. package/dist/public-api.js.map +1 -1
  70. package/package.json +12 -10
  71. package/dist/lib/components/artifact/artifact-panel.component.d.ts +0 -22
  72. package/dist/lib/components/artifact/artifact-panel.component.d.ts.map +0 -1
  73. package/dist/lib/components/artifact/artifact-panel.component.js +0 -237
  74. package/dist/lib/components/artifact/artifact-panel.component.js.map +0 -1
  75. package/dist/lib/components/artifact/artifact-upload-modal.component.d.ts +0 -39
  76. package/dist/lib/components/artifact/artifact-upload-modal.component.d.ts.map +0 -1
  77. package/dist/lib/components/artifact/artifact-upload-modal.component.js +0 -384
  78. package/dist/lib/components/artifact/artifact-upload-modal.component.js.map +0 -1
  79. package/dist/lib/components/artifact/artifact-version-history.component.d.ts +0 -28
  80. package/dist/lib/components/artifact/artifact-version-history.component.d.ts.map +0 -1
  81. package/dist/lib/components/artifact/artifact-version-history.component.js +0 -280
  82. package/dist/lib/components/artifact/artifact-version-history.component.js.map +0 -1
  83. package/dist/lib/components/artifact/artifact-viewer-panel.component.d.ts +0 -22
  84. package/dist/lib/components/artifact/artifact-viewer-panel.component.d.ts.map +0 -1
  85. package/dist/lib/components/artifact/artifact-viewer-panel.component.js +0 -182
  86. package/dist/lib/components/artifact/artifact-viewer-panel.component.js.map +0 -1
  87. package/dist/lib/components/artifact/artifact-viewer.component.d.ts +0 -27
  88. package/dist/lib/components/artifact/artifact-viewer.component.d.ts.map +0 -1
  89. package/dist/lib/components/artifact/artifact-viewer.component.js +0 -266
  90. package/dist/lib/components/artifact/artifact-viewer.component.js.map +0 -1
  91. package/dist/lib/components/artifact/inline-artifact.component.d.ts +0 -46
  92. package/dist/lib/components/artifact/inline-artifact.component.d.ts.map +0 -1
  93. package/dist/lib/components/artifact/inline-artifact.component.js +0 -447
  94. package/dist/lib/components/artifact/inline-artifact.component.js.map +0 -1
  95. package/dist/lib/components/task/task-form-modal.component.d.ts +0 -42
  96. package/dist/lib/components/task/task-form-modal.component.d.ts.map +0 -1
  97. package/dist/lib/components/task/task-form-modal.component.js +0 -329
  98. package/dist/lib/components/task/task-form-modal.component.js.map +0 -1
  99. package/dist/lib/components/task/task-item.component.d.ts +0 -22
  100. package/dist/lib/components/task/task-item.component.d.ts.map +0 -1
  101. package/dist/lib/components/task/task-item.component.js +0 -234
  102. package/dist/lib/components/task/task-item.component.js.map +0 -1
  103. package/dist/lib/components/task/task-list.component.d.ts +0 -32
  104. package/dist/lib/components/task/task-list.component.d.ts.map +0 -1
  105. package/dist/lib/components/task/task-list.component.js +0 -290
  106. package/dist/lib/components/task/task-list.component.js.map +0 -1
@@ -1,28 +1,30 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
2
  import { RunView, Metadata } from '@memberjunction/core';
3
+ import { Subject } from 'rxjs';
3
4
  import * as i0 from "@angular/core";
4
5
  import * as i1 from "../../services/conversation-state.service";
5
- import * as i2 from "../../services/agent-state.service";
6
- import * as i3 from "../../services/conversation-agent.service";
7
- import * as i4 from "../../services/active-tasks.service";
8
- import * as i5 from "@angular/common";
9
- import * as i6 from "../message/message-list.component";
10
- import * as i7 from "../message/message-input.component";
11
- import * as i8 from "../thread/thread-panel.component";
12
- import * as i9 from "../artifact/artifact-viewer-panel.component";
13
- import * as i10 from "../project/project-selector.component";
14
- import * as i11 from "../tasks/tasks-dropdown.component";
15
- import * as i12 from "../agent/active-agent-indicator.component";
16
- import * as i13 from "../active-tasks/active-tasks-panel.component";
6
+ import * as i2 from "../../services/data-cache.service";
7
+ import * as i3 from "../../services/agent-state.service";
8
+ import * as i4 from "../../services/conversation-agent.service";
9
+ import * as i5 from "../../services/active-tasks.service";
10
+ import * as i6 from "@angular/common";
11
+ import * as i7 from "@memberjunction/ng-artifacts";
12
+ import * as i8 from "../message/message-list.component";
13
+ import * as i9 from "../message/message-input.component";
14
+ import * as i10 from "../thread/thread-panel.component";
15
+ import * as i11 from "../project/project-selector.component";
16
+ import * as i12 from "../tasks/tasks-dropdown.component";
17
+ import * as i13 from "../agent/active-agent-indicator.component";
17
18
  import * as i14 from "../members/members-modal.component";
18
19
  import * as i15 from "../export/export-modal.component";
19
20
  const _c0 = ["scrollContainer"];
20
21
  const _forTrack0 = ($index, $item) => $item.artifactId;
22
+ const _forTrack1 = ($index, $item) => $item.versionId;
21
23
  function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf & 1) {
22
24
  const _r3 = i0.ɵɵgetCurrentView();
23
- i0.ɵɵelementStart(0, "button", 29);
25
+ i0.ɵɵelementStart(0, "button", 30);
24
26
  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()); });
25
- i0.ɵɵelement(1, "i", 30);
27
+ i0.ɵɵelement(1, "i", 31);
26
28
  i0.ɵɵelementStart(2, "span");
27
29
  i0.ɵɵtext(3);
28
30
  i0.ɵɵelementEnd()();
@@ -33,9 +35,9 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
33
35
  } }
34
36
  function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf & 1) {
35
37
  const _r6 = i0.ɵɵgetCurrentView();
36
- i0.ɵɵelementStart(0, "button", 31);
38
+ i0.ɵɵelementStart(0, "button", 32);
37
39
  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()); });
38
- i0.ɵɵelement(1, "i", 32);
40
+ i0.ɵɵelement(1, "i", 33);
39
41
  i0.ɵɵelementStart(2, "span");
40
42
  i0.ɵɵtext(3);
41
43
  i0.ɵɵelementEnd()();
@@ -46,29 +48,31 @@ function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf
46
48
  } }
47
49
  function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
48
50
  const _r2 = i0.ɵɵgetCurrentView();
49
- i0.ɵɵelementStart(0, "div", 15)(1, "div", 16)(2, "div", 17);
51
+ i0.ɵɵelementStart(0, "div", 16)(1, "div", 17)(2, "div", 18);
50
52
  i0.ɵɵtext(3);
51
53
  i0.ɵɵelementEnd();
52
- i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 18);
53
- i0.ɵɵelementStart(5, "button", 19);
54
+ i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 19);
55
+ i0.ɵɵelementStart(5, "button", 20);
54
56
  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()); });
55
- i0.ɵɵelement(6, "i", 20);
57
+ i0.ɵɵelement(6, "i", 21);
56
58
  i0.ɵɵelementStart(7, "span");
57
59
  i0.ɵɵtext(8);
58
60
  i0.ɵɵelementEnd()();
59
- i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button", 21);
60
- i0.ɵɵelement(10, "mj-tasks-dropdown", 22);
61
- i0.ɵɵelementStart(11, "mj-active-agent-indicator", 23);
62
- i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_11_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_11_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAgentSelected($event)); });
61
+ i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 2, "button", 22);
62
+ i0.ɵɵelementStart(10, "mj-active-agent-indicator", 23);
63
+ 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)); });
63
64
  i0.ɵɵelementEnd()();
64
- i0.ɵɵelementStart(12, "div", 24)(13, "button", 25);
65
+ i0.ɵɵelementStart(11, "div", 24)(12, "mj-tasks-dropdown", 25);
66
+ 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)); });
67
+ i0.ɵɵelementEnd();
68
+ i0.ɵɵelementStart(13, "button", 26);
65
69
  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()); });
66
- i0.ɵɵelement(14, "i", 26);
70
+ i0.ɵɵelement(14, "i", 27);
67
71
  i0.ɵɵtext(15, " Export ");
68
72
  i0.ɵɵelementEnd();
69
- i0.ɵɵelementStart(16, "button", 27);
73
+ i0.ɵɵelementStart(16, "button", 28);
70
74
  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()); });
71
- i0.ɵɵelement(17, "i", 28);
75
+ i0.ɵɵelement(17, "i", 29);
72
76
  i0.ɵɵtext(18, " Share ");
73
77
  i0.ɵɵelementEnd()()();
74
78
  } if (rf & 2) {
@@ -83,71 +87,81 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
83
87
  i0.ɵɵadvance();
84
88
  i0.ɵɵproperty("ngIf", ctx_r3.artifactCount > 0);
85
89
  i0.ɵɵadvance();
86
- i0.ɵɵproperty("currentUser", ctx_r3.currentUser);
87
- i0.ɵɵadvance();
88
90
  i0.ɵɵproperty("conversationId", ctx_r3.conversationState.activeConversation.ID)("currentUser", ctx_r3.currentUser);
89
- i0.ɵɵadvance(5);
91
+ i0.ɵɵadvance(2);
92
+ i0.ɵɵproperty("currentUser", ctx_r3.currentUser);
93
+ i0.ɵɵadvance(4);
90
94
  i0.ɵɵclassProp("shared", ctx_r3.isShared);
91
95
  i0.ɵɵproperty("title", ctx_r3.isShared ? "Manage sharing" : "Share conversation");
92
96
  } }
93
97
  function ConversationChatAreaComponent_span_8_Template(rf, ctx) { if (rf & 1) {
94
98
  const _r7 = i0.ɵɵgetCurrentView();
95
- i0.ɵɵelementStart(0, "span", 33);
99
+ i0.ɵɵelementStart(0, "span", 34);
96
100
  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()); });
97
- i0.ɵɵelement(1, "i", 34);
101
+ i0.ɵɵelement(1, "i", 35);
98
102
  i0.ɵɵelementEnd();
99
- } if (rf & 2) {
100
- const ctx_r3 = i0.ɵɵnextContext();
101
- i0.ɵɵstyleProp("left", ctx_r3.getScrollToBottomIconPosition(), "px");
102
103
  } }
103
- function ConversationChatAreaComponent_mj_message_input_10_Template(rf, ctx) { if (rf & 1) {
104
+ function ConversationChatAreaComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
105
+ i0.ɵɵelementStart(0, "div", 10)(1, "div", 36);
106
+ i0.ɵɵelement(2, "i", 37);
107
+ i0.ɵɵelementStart(3, "span");
108
+ i0.ɵɵtext(4, "Loading conversation data...");
109
+ i0.ɵɵelementEnd()()();
110
+ } }
111
+ function ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template(rf, ctx) { if (rf & 1) {
104
112
  const _r8 = i0.ɵɵgetCurrentView();
105
- i0.ɵɵelementStart(0, "mj-message-input", 35);
106
- i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_mj_message_input_10_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_mj_message_input_10_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_mj_message_input_10_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAgentRunDetected($event)); })("artifactCreated", function ConversationChatAreaComponent_mj_message_input_10_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_mj_message_input_10_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onConversationRenamed($event)); });
113
+ i0.ɵɵelementStart(0, "mj-message-input", 39);
114
+ 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)); });
107
115
  i0.ɵɵelementEnd();
108
116
  } if (rf & 2) {
109
- const ctx_r3 = i0.ɵɵnextContext();
117
+ const ctx_r3 = i0.ɵɵnextContext(2);
110
118
  i0.ɵɵproperty("conversationId", ctx_r3.conversationState.activeConversation.ID)("currentUser", ctx_r3.currentUser)("conversationHistory", ctx_r3.messages)("disabled", ctx_r3.isProcessing);
111
119
  } }
112
120
  function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
121
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_11_mj_message_input_0_Template, 1, 4, "mj-message-input", 38);
122
+ } if (rf & 2) {
123
+ const ctx_r3 = i0.ɵɵnextContext();
124
+ i0.ɵɵproperty("ngIf", ctx_r3.conversationState.activeConversation);
125
+ } }
126
+ function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
113
127
  const _r9 = i0.ɵɵgetCurrentView();
114
- i0.ɵɵelementStart(0, "div", 36);
115
- i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_11_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onResizeStart($event)); });
128
+ i0.ɵɵelementStart(0, "div", 40);
129
+ 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)); });
116
130
  i0.ɵɵelementEnd();
117
- i0.ɵɵelementStart(1, "div", 37)(2, "mj-artifact-viewer-panel", 38);
118
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_11_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onCloseArtifactPanel()); });
131
+ i0.ɵɵelementStart(1, "div", 41)(2, "mj-artifact-viewer-panel", 42);
132
+ 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()); });
119
133
  i0.ɵɵelementEnd()();
120
134
  } if (rf & 2) {
121
135
  const ctx_r3 = i0.ɵɵnextContext();
122
136
  i0.ɵɵadvance();
123
137
  i0.ɵɵstyleProp("width", ctx_r3.artifactPaneWidth, "%");
124
138
  i0.ɵɵadvance();
125
- i0.ɵɵproperty("artifactId", ctx_r3.selectedArtifactId)("currentUser", ctx_r3.currentUser);
139
+ i0.ɵɵproperty("artifactId", ctx_r3.selectedArtifactId)("currentUser", ctx_r3.currentUser)("environmentId", ctx_r3.environmentId)("versionNumber", ctx_r3.selectedVersionNumber)("refreshTrigger", ctx_r3.artifactViewerRefresh$);
126
140
  } }
127
- function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
141
+ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
128
142
  const _r10 = i0.ɵɵgetCurrentView();
129
- i0.ɵɵelementStart(0, "mj-thread-panel", 39);
130
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_12_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_12_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onThreadReplyAdded($event)); });
143
+ i0.ɵɵelementStart(0, "mj-thread-panel", 43);
144
+ 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)); });
131
145
  i0.ɵɵelementEnd();
132
146
  } if (rf & 2) {
133
147
  const ctx_r3 = i0.ɵɵnextContext();
134
148
  i0.ɵɵproperty("parentMessageId", ctx_r3.conversationState.activeThreadId)("conversationId", (ctx_r3.conversationState.activeConversation == null ? null : ctx_r3.conversationState.activeConversation.ID) || "")("currentUser", ctx_r3.currentUser);
135
149
  } }
136
- function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
150
+ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
137
151
  const _r11 = i0.ɵɵgetCurrentView();
138
- i0.ɵɵelementStart(0, "div", 40);
139
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_15_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
140
- i0.ɵɵelementStart(1, "div", 41);
141
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_15_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
142
- i0.ɵɵelementStart(2, "div", 42)(3, "h3");
152
+ i0.ɵɵelementStart(0, "div", 44);
153
+ 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); });
154
+ i0.ɵɵelementStart(1, "div", 45);
155
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
156
+ i0.ɵɵelementStart(2, "div", 46)(3, "h3");
143
157
  i0.ɵɵtext(4, "Assign Project");
144
158
  i0.ɵɵelementEnd();
145
- i0.ɵɵelementStart(5, "button", 43);
146
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_15_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showProjectSelector = false); });
147
- i0.ɵɵelement(6, "i", 44);
159
+ i0.ɵɵelementStart(5, "button", 47);
160
+ 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); });
161
+ i0.ɵɵelement(6, "i", 48);
148
162
  i0.ɵɵelementEnd()();
149
- i0.ɵɵelementStart(7, "div", 45)(8, "mj-project-selector", 46);
150
- i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_15_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onProjectSelected($event)); });
163
+ i0.ɵɵelementStart(7, "div", 49)(8, "mj-project-selector", 50);
164
+ 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)); });
151
165
  i0.ɵɵelementEnd()()()();
152
166
  } if (rf & 2) {
153
167
  const ctx_r3 = i0.ɵɵnextContext();
@@ -155,51 +169,107 @@ function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf
155
169
  i0.ɵɵproperty("environmentId", ctx_r3.environmentId)("currentUser", ctx_r3.currentUser)("selectedProjectId", ctx_r3.conversationState.activeConversation.ProjectID);
156
170
  } }
157
171
  function ConversationChatAreaComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
158
- i0.ɵɵelementStart(0, "div", 49);
159
- i0.ɵɵelement(1, "i", 51);
160
- i0.ɵɵelementStart(2, "p", 52);
172
+ i0.ɵɵelementStart(0, "div", 53);
173
+ i0.ɵɵelement(1, "i", 55);
174
+ i0.ɵɵelementStart(2, "p", 56);
161
175
  i0.ɵɵtext(3, "No artifacts in this conversation yet");
162
176
  i0.ɵɵelementEnd()();
163
177
  } }
178
+ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_8_Template(rf, ctx) { if (rf & 1) {
179
+ i0.ɵɵtext(0);
180
+ } if (rf & 2) {
181
+ const artifact_r14 = i0.ɵɵnextContext().$implicit;
182
+ i0.ɵɵtextInterpolate1(" ", artifact_r14.versionCount, " versions ");
183
+ } }
184
+ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Template(rf, ctx) { if (rf & 1) {
185
+ i0.ɵɵtext(0, " 1 version ");
186
+ } }
187
+ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template(rf, ctx) { if (rf & 1) {
188
+ const _r15 = i0.ɵɵgetCurrentView();
189
+ i0.ɵɵelementStart(0, "button", 68);
190
+ 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)); });
191
+ i0.ɵɵelement(1, "i", 69);
192
+ i0.ɵɵelementEnd();
193
+ } if (rf & 2) {
194
+ const artifact_r14 = i0.ɵɵnextContext().$implicit;
195
+ const ctx_r3 = i0.ɵɵnextContext(2);
196
+ i0.ɵɵadvance();
197
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r3.expandedArtifactId !== artifact_r14.artifactId)("fa-chevron-up", ctx_r3.expandedArtifactId === artifact_r14.artifactId);
198
+ } }
199
+ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
200
+ const _r16 = i0.ɵɵgetCurrentView();
201
+ i0.ɵɵelementStart(0, "div", 71);
202
+ 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()); });
203
+ i0.ɵɵelementStart(1, "span", 72);
204
+ i0.ɵɵtext(2);
205
+ i0.ɵɵelementEnd();
206
+ i0.ɵɵelementStart(3, "span", 73);
207
+ i0.ɵɵtext(4, "Open this version");
208
+ i0.ɵɵelementEnd();
209
+ i0.ɵɵelement(5, "i", 74);
210
+ i0.ɵɵelementEnd();
211
+ } if (rf & 2) {
212
+ const version_r17 = ctx.$implicit;
213
+ i0.ɵɵadvance(2);
214
+ i0.ɵɵtextInterpolate1("v", version_r17.versionNumber, "");
215
+ } }
216
+ function ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
217
+ i0.ɵɵelementStart(0, "div", 67);
218
+ i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_For_2_Template, 6, 1, "div", 70, _forTrack1);
219
+ i0.ɵɵelementEnd();
220
+ } if (rf & 2) {
221
+ const artifact_r14 = i0.ɵɵnextContext().$implicit;
222
+ i0.ɵɵadvance();
223
+ i0.ɵɵrepeater(artifact_r14.versions);
224
+ } }
164
225
  function ConversationChatAreaComponent_Conditional_17_For_10_Template(rf, ctx) { if (rf & 1) {
165
226
  const _r13 = i0.ɵɵgetCurrentView();
166
- i0.ɵɵelementStart(0, "div", 53);
167
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_For_10_Template_div_click_0_listener() { const artifact_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.openArtifactFromModal(artifact_r14.artifactId)); });
168
- i0.ɵɵelementStart(1, "div", 54);
169
- i0.ɵɵelement(2, "i", 55);
227
+ i0.ɵɵelementStart(0, "div", 57)(1, "div", 58);
228
+ 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)); });
229
+ i0.ɵɵelementStart(2, "div", 59);
230
+ i0.ɵɵelement(3, "i", 60);
170
231
  i0.ɵɵelementEnd();
171
- i0.ɵɵelementStart(3, "div", 56)(4, "div", 57);
172
- i0.ɵɵtext(5);
232
+ i0.ɵɵelementStart(4, "div", 61)(5, "div", 62);
233
+ i0.ɵɵtext(6);
173
234
  i0.ɵɵelementEnd();
174
- i0.ɵɵelementStart(6, "div", 58);
175
- i0.ɵɵtext(7);
235
+ i0.ɵɵelementStart(7, "div", 63);
236
+ i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_9_Template, 1, 0);
176
237
  i0.ɵɵelementEnd()();
177
- i0.ɵɵelementStart(8, "div", 59);
178
- i0.ɵɵelement(9, "i", 60);
238
+ i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_10_Template, 2, 4, "button", 64);
239
+ i0.ɵɵelementStart(11, "div", 65);
240
+ i0.ɵɵelement(12, "i", 66);
179
241
  i0.ɵɵelementEnd()();
242
+ i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_17_For_10_Conditional_13_Template, 3, 0, "div", 67);
243
+ i0.ɵɵelementEnd();
180
244
  } if (rf & 2) {
181
245
  const artifact_r14 = ctx.$implicit;
182
- i0.ɵɵadvance(5);
246
+ const ctx_r3 = i0.ɵɵnextContext(2);
247
+ i0.ɵɵclassProp("expanded", ctx_r3.expandedArtifactId === artifact_r14.artifactId);
248
+ i0.ɵɵadvance(6);
183
249
  i0.ɵɵtextInterpolate(artifact_r14.name);
184
250
  i0.ɵɵadvance(2);
185
- i0.ɵɵtextInterpolate1("Version ", artifact_r14.versionId.substring(0, 8), "");
251
+ i0.ɵɵconditional(artifact_r14.versionCount > 1 ? 8 : 9);
252
+ i0.ɵɵadvance(2);
253
+ i0.ɵɵconditional(artifact_r14.versionCount > 1 ? 10 : -1);
254
+ i0.ɵɵadvance(3);
255
+ i0.ɵɵconditional(ctx_r3.expandedArtifactId === artifact_r14.artifactId && artifact_r14.versionCount > 1 ? 13 : -1);
186
256
  } }
187
257
  function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
188
258
  const _r12 = i0.ɵɵgetCurrentView();
189
- i0.ɵɵelementStart(0, "div", 40);
259
+ i0.ɵɵelementStart(0, "div", 44);
190
260
  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); });
191
- i0.ɵɵelementStart(1, "div", 47);
261
+ i0.ɵɵelementStart(1, "div", 51);
192
262
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
193
- i0.ɵɵelementStart(2, "div", 42)(3, "h3");
263
+ i0.ɵɵelementStart(2, "div", 46)(3, "h3");
194
264
  i0.ɵɵtext(4, "Conversation Artifacts");
195
265
  i0.ɵɵelementEnd();
196
- i0.ɵɵelementStart(5, "button", 43);
266
+ i0.ɵɵelementStart(5, "button", 47);
197
267
  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); });
198
- i0.ɵɵelement(6, "i", 44);
268
+ i0.ɵɵelement(6, "i", 48);
199
269
  i0.ɵɵelementEnd()();
200
- i0.ɵɵelementStart(7, "div", 48);
201
- i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div", 49);
202
- i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 10, 2, "div", 50, _forTrack0);
270
+ i0.ɵɵelementStart(7, "div", 52);
271
+ i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_17_Conditional_8_Template, 4, 0, "div", 53);
272
+ i0.ɵɵrepeaterCreate(9, ConversationChatAreaComponent_Conditional_17_For_10_Template, 14, 6, "div", 54, _forTrack0);
203
273
  i0.ɵɵelementEnd()()();
204
274
  } if (rf & 2) {
205
275
  const ctx_r3 = i0.ɵɵnextContext();
@@ -210,6 +280,7 @@ function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf
210
280
  } }
211
281
  export class ConversationChatAreaComponent {
212
282
  conversationState;
283
+ dataCache;
213
284
  agentStateService;
214
285
  conversationAgentService;
215
286
  activeTasks;
@@ -218,6 +289,7 @@ export class ConversationChatAreaComponent {
218
289
  currentUser;
219
290
  conversationRenamed = new EventEmitter();
220
291
  openEntityRecord = new EventEmitter();
292
+ taskClicked = new EventEmitter();
221
293
  scrollContainer;
222
294
  messages = [];
223
295
  showScrollToBottomIcon = false;
@@ -234,20 +306,29 @@ export class ConversationChatAreaComponent {
234
306
  showArtifactPanel = false;
235
307
  showArtifactsModal = false;
236
308
  selectedArtifactId = null;
309
+ selectedVersionNumber = undefined; // Version to show in artifact viewer
237
310
  artifactPaneWidth = 40; // Default 40% width
238
- // Artifact mapping: ConversationDetailID -> {artifactId, versionId, name}
311
+ expandedArtifactId = null; // Track which artifact card is expanded in modal
312
+ // Artifact mapping: ConversationDetailID -> Array of {artifact, version}
313
+ // Full entities loaded once and reused across all message components
314
+ // Supports multiple artifacts per conversation detail (0-N relationship)
239
315
  artifactsByDetailId = new Map();
240
316
  // Agent run mapping: ConversationDetailID -> AIAgentRunEntityExtended
241
317
  // Loaded once per conversation and kept in sync as new runs are created
242
318
  agentRunsByDetailId = new Map();
319
+ // Loading state for peripheral data
320
+ isLoadingPeripheralData = false;
321
+ // Subject to trigger artifact viewer refresh when new version is created
322
+ artifactViewerRefresh$ = new Subject();
243
323
  // Resize state
244
324
  isResizing = false;
245
325
  startX = 0;
246
326
  startWidth = 0;
247
327
  // LocalStorage key
248
328
  ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
249
- constructor(conversationState, agentStateService, conversationAgentService, activeTasks, cdr) {
329
+ constructor(conversationState, dataCache, agentStateService, conversationAgentService, activeTasks, cdr) {
250
330
  this.conversationState = conversationState;
331
+ this.dataCache = dataCache;
251
332
  this.agentStateService = agentStateService;
252
333
  this.conversationAgentService = conversationAgentService;
253
334
  this.activeTasks = activeTasks;
@@ -277,8 +358,14 @@ export class ConversationChatAreaComponent {
277
358
  this.scrollToBottom = false;
278
359
  setTimeout(() => {
279
360
  this.scrollToBottomNow();
361
+ // Check scroll state after scrolling to bottom
362
+ this.checkScroll();
280
363
  }, 100);
281
364
  }
365
+ else {
366
+ // Always check scroll state to update button visibility
367
+ this.checkScroll();
368
+ }
282
369
  }
283
370
  ngOnDestroy() {
284
371
  // Stop polling when component is destroyed
@@ -302,22 +389,42 @@ export class ConversationChatAreaComponent {
302
389
  }
303
390
  }
304
391
  async loadMessages(conversationId) {
392
+ try {
393
+ // PHASE 1: Load messages from cache (fast, shows content immediately)
394
+ // The cache will load from DB if not already cached
395
+ const loadedMessages = await this.dataCache.loadConversationDetails(conversationId, this.currentUser);
396
+ this.messages = loadedMessages;
397
+ this.scrollToBottom = true;
398
+ this.cdr.detectChanges(); // Show messages immediately
399
+ // PHASE 2: Load peripheral data in background (agent runs & artifacts)
400
+ this.isLoadingPeripheralData = true;
401
+ this.loadPeripheralData(conversationId).finally(() => {
402
+ this.isLoadingPeripheralData = false;
403
+ this.cdr.detectChanges();
404
+ });
405
+ }
406
+ catch (error) {
407
+ console.error('Error loading messages:', error);
408
+ this.messages = [];
409
+ }
410
+ }
411
+ /**
412
+ * Load peripheral data (agent runs and artifacts) in background
413
+ * This allows messages to display immediately while slower queries complete
414
+ */
415
+ async loadPeripheralData(conversationId) {
305
416
  try {
306
417
  const rv = new RunView();
307
- // Load messages and agent runs in parallel
308
418
  const md = new Metadata();
309
419
  const convoDetailEntity = md.EntityByName("Conversation Details");
310
- const [messagesResult, agentRunsResult, conversationDetailArtifacts] = await Promise.all([
311
- rv.RunView({
312
- EntityName: 'Conversation Details',
313
- ExtraFilter: `ConversationID='${conversationId}'`,
314
- OrderBy: '__mj_CreatedAt ASC',
315
- ResultType: 'entity_object'
316
- }, this.currentUser),
420
+ // Load agent runs and artifacts in parallel
421
+ const [agentRunsResult, conversationDetailArtifacts] = await Promise.all([
317
422
  rv.RunView({
318
423
  EntityName: 'MJ: AI Agent Runs',
319
424
  ExtraFilter: `ConversationDetailID IN (SELECT ID FROM [${convoDetailEntity.SchemaName}].[${convoDetailEntity.BaseView}] WHERE ConversationID='${conversationId}')`,
320
- ResultType: 'entity_object'
425
+ ResultType: 'entity_object',
426
+ // Only fetch fields we actually display to reduce payload size
427
+ Fields: ['ID', 'AgentID', 'Agent', 'Status', '__mj_CreatedAt', '__mj_UpdatedAt', 'TotalPromptTokensUsed', 'TotalCompletionTokensUsed', 'TotalCost', 'ConversationDetailID']
321
428
  }, this.currentUser),
322
429
  rv.RunView({
323
430
  EntityName: 'MJ: Conversation Detail Artifacts',
@@ -325,134 +432,109 @@ export class ConversationChatAreaComponent {
325
432
  ResultType: 'entity_object'
326
433
  }, this.currentUser)
327
434
  ]);
328
- if (messagesResult.Success) {
329
- const loadedMessages = messagesResult.Results || [];
330
- // Build agent runs map - single query loads all runs for this conversation
331
- this.agentRunsByDetailId.clear();
332
- console.log(`🔍 Agent Runs Query Result:`, {
333
- success: agentRunsResult.Success,
334
- resultCount: agentRunsResult.Results?.length || 0,
335
- errorMessage: agentRunsResult.ErrorMessage
336
- });
337
- if (agentRunsResult.Success && agentRunsResult.Results) {
338
- for (const run of agentRunsResult.Results) {
339
- console.log(` 📌 Agent Run:`, {
340
- id: run.ID,
341
- agentName: run.Agent,
342
- conversationDetailID: run.ConversationDetailID,
343
- status: run.Status
344
- });
345
- if (run.ConversationDetailID) {
346
- this.agentRunsByDetailId.set(run.ConversationDetailID, run);
347
- }
435
+ // Build agent runs map - single query loads all runs for this conversation
436
+ this.agentRunsByDetailId.clear();
437
+ if (agentRunsResult.Success && agentRunsResult.Results) {
438
+ for (const run of agentRunsResult.Results) {
439
+ if (run.ConversationDetailID) {
440
+ this.agentRunsByDetailId.set(run.ConversationDetailID, run);
348
441
  }
349
- console.log(`📊 Loaded ${this.agentRunsByDetailId.size} agent runs for conversation ${conversationId}`);
350
- console.log(`📊 Map keys:`, Array.from(this.agentRunsByDetailId.keys()));
351
442
  }
352
- else {
353
- console.error(`❌ Failed to load agent runs:`, agentRunsResult.ErrorMessage);
354
- }
355
- // Build artifact map from preloaded artifacts
356
- this.artifactsByDetailId.clear();
357
- if (conversationDetailArtifacts.Success && conversationDetailArtifacts.Results && conversationDetailArtifacts.Results.length > 0) {
358
- // Load artifact versions to get ArtifactID
359
- const versionIds = conversationDetailArtifacts.Results.map(a => `'${a.ArtifactVersionID}'`).join(',');
360
- const versionsResult = await rv.RunView({
361
- EntityName: 'MJ: Artifact Versions',
362
- ExtraFilter: `ID IN (${versionIds})`,
443
+ }
444
+ // Build artifact map from preloaded artifacts
445
+ this.artifactsByDetailId.clear();
446
+ if (conversationDetailArtifacts.Success && conversationDetailArtifacts.Results && conversationDetailArtifacts.Results.length > 0) {
447
+ // Load artifact versions to get ArtifactID
448
+ const versionIds = conversationDetailArtifacts.Results.map(a => `'${a.ArtifactVersionID}'`).join(',');
449
+ const versionsResult = await rv.RunView({
450
+ EntityName: 'MJ: Artifact Versions',
451
+ ExtraFilter: `ID IN (${versionIds})`,
452
+ ResultType: 'entity_object'
453
+ }, this.currentUser);
454
+ if (versionsResult.Success && versionsResult.Results) {
455
+ // Get all unique artifact IDs
456
+ const artifactIds = [...new Set(versionsResult.Results.map(v => v.ArtifactID))];
457
+ // Load full artifact entities
458
+ const artifactsResult = await rv.RunView({
459
+ EntityName: 'MJ: Artifacts',
460
+ ExtraFilter: `ID IN (${artifactIds.map(id => `'${id}'`).join(',')})`,
363
461
  ResultType: 'entity_object'
364
462
  }, this.currentUser);
365
- if (versionsResult.Success && versionsResult.Results) {
366
- // Create map of versionId -> {artifactId, artifactName}
367
- const versionToArtifact = new Map();
368
- // Get all unique artifact IDs
369
- const artifactIds = [...new Set(versionsResult.Results.map(v => v.ArtifactID))];
370
- // Load artifact entities to get names
371
- const artifactsResult = await rv.RunView({
372
- EntityName: 'MJ: Artifacts',
373
- ExtraFilter: `ID IN (${artifactIds.map(id => `'${id}'`).join(',')})`,
374
- ResultType: 'entity_object'
375
- }, this.currentUser);
376
- // Create map of artifactId -> name
377
- const artifactNames = new Map();
378
- if (artifactsResult.Success && artifactsResult.Results) {
379
- for (const artifact of artifactsResult.Results) {
380
- artifactNames.set(artifact.ID, artifact.Name || 'Unnamed Artifact');
381
- }
463
+ // Create maps of entities by ID for fast lookup
464
+ const artifactEntities = new Map();
465
+ const versionEntities = new Map();
466
+ if (artifactsResult.Success && artifactsResult.Results) {
467
+ for (const artifact of artifactsResult.Results) {
468
+ artifactEntities.set(artifact.ID, artifact);
382
469
  }
383
- // Build versionId to artifact info map
384
- for (const version of versionsResult.Results) {
385
- versionToArtifact.set(version.ID, {
386
- artifactId: version.ArtifactID,
387
- artifactName: artifactNames.get(version.ArtifactID) || 'Unnamed Artifact'
470
+ }
471
+ for (const version of versionsResult.Results) {
472
+ versionEntities.set(version.ID, version);
473
+ }
474
+ // Build final artifact map with FULL entities
475
+ // Group artifacts by ConversationDetailID (supports multiple artifacts per detail)
476
+ for (const junctionRecord of conversationDetailArtifacts.Results) {
477
+ const version = versionEntities.get(junctionRecord.ArtifactVersionID);
478
+ const artifact = version ? artifactEntities.get(version.ArtifactID) : undefined;
479
+ if (junctionRecord.ConversationDetailID && version && artifact) {
480
+ const existing = this.artifactsByDetailId.get(junctionRecord.ConversationDetailID) || [];
481
+ existing.push({
482
+ artifact: artifact, // Full ArtifactEntity
483
+ version: version // Full ArtifactVersionEntity
388
484
  });
485
+ this.artifactsByDetailId.set(junctionRecord.ConversationDetailID, existing);
389
486
  }
390
- // Build final artifact map with IDs and names
391
- for (const artifact of conversationDetailArtifacts.Results) {
392
- const artifactInfo = versionToArtifact.get(artifact.ArtifactVersionID);
393
- if (artifact.ConversationDetailID && artifactInfo) {
394
- this.artifactsByDetailId.set(artifact.ConversationDetailID, {
395
- artifactId: artifactInfo.artifactId,
396
- versionId: artifact.ArtifactVersionID,
397
- name: artifactInfo.artifactName
398
- });
399
- }
400
- }
401
- console.log(`📦 Preloaded ${this.artifactsByDetailId.size} artifacts for conversation ${conversationId}`);
402
487
  }
488
+ // Create new Map reference to trigger Angular change detection
489
+ this.artifactsByDetailId = new Map(this.artifactsByDetailId);
490
+ console.log(`📦 Preloaded ${this.artifactsByDetailId.size} artifacts for conversation ${conversationId}`);
403
491
  }
404
- // Update artifact count for header display
405
- this.artifactCount = conversationDetailArtifacts.Results?.length || 0;
406
- // Debug: Log all artifacts to console
407
- console.log(`📊 Artifact Count: ${this.artifactCount}`);
408
- console.log(`📦 Artifacts by Detail ID:`, Array.from(this.artifactsByDetailId.entries()).map(([detailId, info]) => ({
409
- conversationDetailId: detailId,
410
- artifactId: info.artifactId,
411
- versionId: info.versionId
412
- })));
413
- // NOW set messages to trigger rendering (after artifacts are loaded)
414
- this.messages = loadedMessages;
415
492
  }
493
+ // Update artifact count for header display (unique artifacts, not versions)
494
+ this.artifactCount = this.calculateUniqueArtifactCount();
495
+ // Debug: Log all artifacts to console
496
+ console.log(`📊 Artifact Count: ${this.artifactCount}`);
497
+ console.log(`📦 Artifacts by Detail ID:`, Array.from(this.artifactsByDetailId.entries()).flatMap(([detailId, artifactList]) => artifactList.map(info => ({
498
+ conversationDetailId: detailId,
499
+ artifactId: info.artifact.ID,
500
+ artifactName: info.artifact.Name,
501
+ versionId: info.version.ID,
502
+ versionNumber: info.version.VersionNumber
503
+ }))));
504
+ // CRITICAL: Trigger message re-render now that agent runs and artifacts are loaded
505
+ // This updates all message components with the newly loaded agent run data
506
+ this.messages = [...this.messages]; // Create new array reference to trigger change detection
507
+ this.cdr.detectChanges();
416
508
  }
417
509
  catch (error) {
418
- console.error('Failed to load messages:', error);
510
+ console.error('Failed to load peripheral data:', error);
419
511
  }
420
512
  }
421
513
  /**
422
- * Restore active tasks from the database for this conversation
423
- * Queries for messages with Status='In-Progress' and recreates the active task tracking
514
+ * REMOVED: Active tasks should only track currently-running tasks in this browser session.
515
+ * Database tasks with 'In-Progress' status are shown in the Tasks dropdown via loadDatabaseTasks().
516
+ * Restoring them here causes duplicate "Agent Processing..." entries.
424
517
  */
425
518
  async restoreActiveTasks(conversationId) {
426
- try {
427
- // Clear existing tasks for this conversation first
428
- // (We'll filter by conversation in the UI later)
429
- const rv = new RunView();
430
- const result = await rv.RunView({
431
- EntityName: 'Conversation Details',
432
- ExtraFilter: `ConversationID='${conversationId}' AND Status='In-Progress'`,
433
- OrderBy: '__mj_CreatedAt ASC',
434
- ResultType: 'entity_object'
435
- }, this.currentUser);
436
- if (result.Success && result.Results) {
437
- for (const message of result.Results) {
438
- // Restore the task to the active tasks service
439
- this.activeTasks.add({
440
- agentName: 'Agent', // We'll need to enhance this with actual agent name from AgentRunID
441
- status: 'Processing...',
442
- relatedMessageId: message.ID,
443
- conversationDetailId: message.ID
444
- });
445
- }
446
- console.log(`✅ Restored ${result.Results.length} active tasks for conversation ${conversationId}`);
447
- }
448
- }
449
- catch (error) {
450
- console.error('Failed to restore active tasks:', error);
451
- }
519
+ // Intentionally empty - ActiveTasksService only tracks in-memory running tasks
520
+ // Database tasks are loaded separately by TasksDropdownComponent
452
521
  }
453
522
  onMessageSent(message) {
454
- // Add the new message to the list
455
- this.messages = [...this.messages, message];
523
+ // Check if message already exists in the array (by ID) to prevent duplicates
524
+ // Messages can be emitted multiple times as they're updated (e.g., status changes)
525
+ const existingIndex = this.messages.findIndex(m => m.ID === message.ID);
526
+ if (existingIndex >= 0) {
527
+ // Update existing message in place (replace with updated version)
528
+ this.messages = [
529
+ ...this.messages.slice(0, existingIndex),
530
+ message,
531
+ ...this.messages.slice(existingIndex + 1)
532
+ ];
533
+ }
534
+ else {
535
+ // Add new message to the list
536
+ this.messages = [...this.messages, message];
537
+ }
456
538
  // Scroll to bottom when new message is sent
457
539
  this.scrollToBottom = true;
458
540
  }
@@ -461,7 +543,6 @@ export class ConversationChatAreaComponent {
461
543
  * This is called when the first progress update arrives with an agent run ID
462
544
  */
463
545
  async onAgentRunDetected(event) {
464
- console.log('🎯 Agent run detected from progress update:', event);
465
546
  await this.addAgentRunToMap(event.conversationDetailId, event.agentRunId);
466
547
  }
467
548
  async onAgentResponse(event) {
@@ -469,33 +550,22 @@ export class ConversationChatAreaComponent {
469
550
  this.messages = [...this.messages, event.message];
470
551
  // Scroll to bottom when agent responds
471
552
  this.scrollToBottom = true;
472
- console.log('Agent responded:', event.agentResult);
473
553
  // Add agent run to the map if present (fallback if not already loaded from progress)
474
554
  // agentResult is ExecuteAgentResult which contains agentRun property
475
555
  if (event.agentResult?.agentRun?.ID) {
476
556
  // Only load if not already in map (progress update may have already loaded it)
477
557
  if (!this.agentRunsByDetailId.has(event.message.ID)) {
478
- console.log('🔄 Loading agent run after execution:', {
479
- agentRunId: event.agentResult.agentRun.ID,
480
- conversationDetailId: event.message.ID,
481
- agentName: event.agentResult.agentRun.Agent
482
- });
483
558
  await this.addAgentRunToMap(event.message.ID, event.agentResult.agentRun.ID);
484
559
  }
485
- else {
486
- console.log('✅ Agent run already in map from progress update');
487
- }
488
- }
489
- else {
490
- console.warn('⚠️ No agent run ID in agent response:', event.agentResult);
491
560
  }
492
561
  // Reload artifact mapping for this message to pick up newly created artifacts
493
562
  await this.reloadArtifactsForMessage(event.message.ID);
494
- // Auto-open artifact panel if this message has an artifact and no artifact is currently shown
563
+ // Auto-open artifact panel if this message has artifacts and no artifact is currently shown
495
564
  if (this.artifactsByDetailId.has(event.message.ID) && !this.showArtifactPanel) {
496
- const artifactInfo = this.artifactsByDetailId.get(event.message.ID);
497
- if (artifactInfo) {
498
- this.selectedArtifactId = artifactInfo.artifactId;
565
+ const artifactList = this.artifactsByDetailId.get(event.message.ID);
566
+ if (artifactList && artifactList.length > 0) {
567
+ // Show the first (or most recent) artifact
568
+ this.selectedArtifactId = artifactList[0].artifact.ID;
499
569
  this.showArtifactPanel = true;
500
570
  }
501
571
  }
@@ -508,25 +578,14 @@ export class ConversationChatAreaComponent {
508
578
  */
509
579
  async addAgentRunToMap(conversationDetailId, agentRunId) {
510
580
  try {
511
- console.log(`🔄 Adding agent run to map:`, { conversationDetailId, agentRunId });
512
581
  const md = new Metadata();
513
582
  const agentRun = await md.GetEntityObject('MJ: AI Agent Runs', this.currentUser);
514
583
  if (await agentRun.Load(agentRunId)) {
515
584
  this.agentRunsByDetailId.set(conversationDetailId, agentRun);
516
- console.log(`✅ Added agent run to map:`, {
517
- agentRunId,
518
- conversationDetailId,
519
- agentName: agentRun.Agent,
520
- status: agentRun.Status,
521
- mapSize: this.agentRunsByDetailId.size
522
- });
523
- }
524
- else {
525
- console.warn(`⚠️ Failed to load agent run ${agentRunId}`);
526
585
  }
527
586
  }
528
587
  catch (error) {
529
- console.error('Failed to load agent run for map:', error);
588
+ console.error('Failed to load agent run for map:', error);
530
589
  }
531
590
  }
532
591
  /**
@@ -534,6 +593,7 @@ export class ConversationChatAreaComponent {
534
593
  * Called after an artifact is created to update the UI immediately
535
594
  */
536
595
  async reloadArtifactsForMessage(conversationDetailId) {
596
+ console.log(`🔄 Reloading artifacts for message ${conversationDetailId}`);
537
597
  try {
538
598
  const rv = new RunView();
539
599
  const artifactsResult = await rv.RunView({
@@ -541,8 +601,13 @@ export class ConversationChatAreaComponent {
541
601
  ExtraFilter: `ConversationDetailID='${conversationDetailId}' AND Direction='Output'`,
542
602
  ResultType: 'entity_object'
543
603
  }, this.currentUser);
604
+ console.log(`📊 Junction query result:`, {
605
+ success: artifactsResult.Success,
606
+ count: artifactsResult.Results?.length || 0,
607
+ error: artifactsResult.ErrorMessage
608
+ });
544
609
  if (artifactsResult.Success && artifactsResult.Results && artifactsResult.Results.length > 0) {
545
- // Load artifact versions to get ArtifactID
610
+ // Load full artifact versions and artifacts
546
611
  const versionIds = artifactsResult.Results.map(a => `'${a.ArtifactVersionID}'`).join(',');
547
612
  const versionsResult = await rv.RunView({
548
613
  EntityName: 'MJ: Artifact Versions',
@@ -550,24 +615,44 @@ export class ConversationChatAreaComponent {
550
615
  ResultType: 'entity_object'
551
616
  }, this.currentUser);
552
617
  if (versionsResult.Success && versionsResult.Results) {
553
- const versionToArtifact = new Map();
554
- for (const version of versionsResult.Results) {
555
- versionToArtifact.set(version.ID, version.ArtifactID);
556
- }
557
- // Update artifact map
558
- for (const artifact of artifactsResult.Results) {
559
- const artifactId = versionToArtifact.get(artifact.ArtifactVersionID);
560
- if (artifactId) {
561
- this.artifactsByDetailId.set(conversationDetailId, {
562
- artifactId: artifactId,
563
- versionId: artifact.ArtifactVersionID,
564
- name: 'Artifact' // Note: This method is deprecated, name should come from event
565
- });
566
- console.log(`✅ Loaded artifact ${artifactId} for message ${conversationDetailId}`);
618
+ // Load full artifact entities
619
+ const artifactIds = versionsResult.Results.map(v => `'${v.ArtifactID}'`).join(',');
620
+ const fullArtifactsResult = await rv.RunView({
621
+ EntityName: 'MJ: Artifacts',
622
+ ExtraFilter: `ID IN (${artifactIds})`,
623
+ ResultType: 'entity_object'
624
+ }, this.currentUser);
625
+ if (fullArtifactsResult.Success && fullArtifactsResult.Results) {
626
+ // Create maps for fast lookup
627
+ const artifactEntities = new Map();
628
+ const versionEntities = new Map();
629
+ for (const artifact of fullArtifactsResult.Results) {
630
+ artifactEntities.set(artifact.ID, artifact);
631
+ }
632
+ for (const version of versionsResult.Results) {
633
+ versionEntities.set(version.ID, version);
567
634
  }
635
+ // Update artifact map with full entities (supports multiple artifacts per detail)
636
+ const artifactList = [];
637
+ for (const junctionRecord of artifactsResult.Results) {
638
+ const version = versionEntities.get(junctionRecord.ArtifactVersionID);
639
+ const artifact = version ? artifactEntities.get(version.ArtifactID) : undefined;
640
+ if (version && artifact) {
641
+ artifactList.push({
642
+ artifact: artifact,
643
+ version: version
644
+ });
645
+ console.log(`✅ Loaded artifact ${artifact.ID} v${version.VersionNumber} for message ${conversationDetailId}`);
646
+ }
647
+ }
648
+ if (artifactList.length > 0) {
649
+ this.artifactsByDetailId.set(conversationDetailId, artifactList);
650
+ }
651
+ // Create new Map reference to trigger Angular change detection
652
+ this.artifactsByDetailId = new Map(this.artifactsByDetailId);
653
+ // Update artifact count
654
+ this.artifactCount = this.calculateUniqueArtifactCount();
568
655
  }
569
- // Update artifact count
570
- this.artifactCount = this.artifactsByDetailId.size;
571
656
  }
572
657
  }
573
658
  }
@@ -584,11 +669,66 @@ export class ConversationChatAreaComponent {
584
669
  viewArtifacts() {
585
670
  this.showArtifactsModal = true;
586
671
  }
672
+ /**
673
+ * Calculate count of unique artifacts (not versions)
674
+ */
675
+ calculateUniqueArtifactCount() {
676
+ const uniqueArtifactIds = new Set();
677
+ for (const artifactList of this.artifactsByDetailId.values()) {
678
+ for (const info of artifactList) {
679
+ uniqueArtifactIds.add(info.artifact.ID);
680
+ }
681
+ }
682
+ return uniqueArtifactIds.size;
683
+ }
684
+ /**
685
+ * Get unique artifacts grouped by artifact ID (not by conversation detail)
686
+ * Returns the latest version info for each unique artifact with all versions
687
+ */
587
688
  getArtifactsArray() {
588
- return Array.from(this.artifactsByDetailId.values());
689
+ const artifactMap = new Map();
690
+ // Group by artifactId, collecting all version details
691
+ for (const artifactList of this.artifactsByDetailId.values()) {
692
+ for (const info of artifactList) {
693
+ const artifactId = info.artifact.ID;
694
+ const versionId = info.version.ID;
695
+ const versionNumber = info.version.VersionNumber || 1;
696
+ const name = info.version.Name || info.artifact.Name || 'Untitled';
697
+ if (!artifactMap.has(artifactId)) {
698
+ artifactMap.set(artifactId, {
699
+ artifactId: artifactId,
700
+ versionId: versionId, // Latest version ID
701
+ name: name,
702
+ versions: [{ versionId: versionId, versionNumber: versionNumber }]
703
+ });
704
+ }
705
+ else {
706
+ // Add version if not already present
707
+ const existing = artifactMap.get(artifactId);
708
+ if (!existing.versions.some(v => v.versionId === versionId)) {
709
+ existing.versions.push({ versionId: versionId, versionNumber: versionNumber });
710
+ // Update to latest version ID (assuming versions are added chronologically)
711
+ existing.versionId = versionId;
712
+ }
713
+ }
714
+ }
715
+ }
716
+ // Convert to array with version count, sorted by version number descending
717
+ return Array.from(artifactMap.values()).map(item => ({
718
+ artifactId: item.artifactId,
719
+ versionId: item.versionId,
720
+ name: item.name,
721
+ versionCount: item.versions.length,
722
+ versions: item.versions.sort((a, b) => b.versionNumber - a.versionNumber)
723
+ }));
589
724
  }
590
- openArtifactFromModal(artifactId) {
725
+ toggleArtifactExpansion(artifactId, event) {
726
+ event.stopPropagation(); // Prevent opening artifact when clicking expand button
727
+ this.expandedArtifactId = this.expandedArtifactId === artifactId ? null : artifactId;
728
+ }
729
+ openArtifactFromModal(artifactId, versionNumber) {
591
730
  this.selectedArtifactId = artifactId;
731
+ this.selectedVersionNumber = versionNumber;
592
732
  this.showArtifactPanel = true;
593
733
  this.showArtifactsModal = false;
594
734
  }
@@ -675,20 +815,39 @@ export class ConversationChatAreaComponent {
675
815
  }
676
816
  onArtifactClicked(data) {
677
817
  this.selectedArtifactId = data.artifactId;
818
+ // If versionId is provided, find the version number
819
+ if (data.versionId) {
820
+ for (const [detailId, artifactList] of this.artifactsByDetailId.entries()) {
821
+ for (const artifactInfo of artifactList) {
822
+ if (artifactInfo.version.ID === data.versionId) {
823
+ this.selectedVersionNumber = artifactInfo.version.VersionNumber;
824
+ console.log(`📦 Opening artifact viewer for v${this.selectedVersionNumber}`);
825
+ break;
826
+ }
827
+ }
828
+ }
829
+ }
830
+ else {
831
+ // No specific version, let viewer default to latest
832
+ this.selectedVersionNumber = undefined;
833
+ }
678
834
  this.showArtifactPanel = true;
679
835
  }
680
- onArtifactCreated(data) {
681
- this.artifactsByDetailId.set(data.conversationDetailId, {
682
- artifactId: data.artifactId,
683
- versionId: data.versionId,
684
- name: data.name
685
- });
836
+ async onArtifactCreated(data) {
837
+ // Reload artifacts to get full entities
838
+ await this.reloadArtifactsForMessage(data.conversationDetailId);
686
839
  // if we don't already have another artifact showing, let's show the newly created one
687
840
  if (!this.showArtifactPanel) {
688
841
  this.selectedArtifactId = data.artifactId;
689
842
  this.showArtifactPanel = true;
690
843
  }
691
- this.artifactCount++; // increment artifact count
844
+ // If artifact viewer is already open for this artifact, trigger refresh to show new version
845
+ if (this.showArtifactPanel && this.selectedArtifactId === data.artifactId) {
846
+ // Emit event to refresh artifact viewer with new version
847
+ this.artifactViewerRefresh$.next({ artifactId: data.artifactId, versionNumber: data.versionNumber });
848
+ }
849
+ // Force change detection to update the UI immediately
850
+ this.cdr.detectChanges();
692
851
  }
693
852
  onCloseArtifactPanel() {
694
853
  this.showArtifactPanel = false;
@@ -703,9 +862,18 @@ export class ConversationChatAreaComponent {
703
862
  }
704
863
  /**
705
864
  * Get artifact info for a conversation detail
865
+ * Returns the first artifact if multiple exist (for backward compatibility with message display)
706
866
  */
707
867
  getArtifactInfo(conversationDetailId) {
708
- return this.artifactsByDetailId.get(conversationDetailId);
868
+ const artifactList = this.artifactsByDetailId.get(conversationDetailId);
869
+ return artifactList && artifactList.length > 0 ? artifactList[0] : undefined;
870
+ }
871
+ /**
872
+ * Get ALL artifacts for a conversation detail
873
+ * Use this when you need to display all artifacts (e.g., in a list)
874
+ */
875
+ getAllArtifactsForDetail(conversationDetailId) {
876
+ return this.artifactsByDetailId.get(conversationDetailId) || [];
709
877
  }
710
878
  /**
711
879
  * Resize handle methods for artifact pane
@@ -772,6 +940,10 @@ export class ConversationChatAreaComponent {
772
940
  // Pass the event up to the parent component (workspace or explorer wrapper)
773
941
  this.openEntityRecord.emit(event);
774
942
  }
943
+ onTaskClicked(task) {
944
+ // Pass task click up to workspace to navigate to Tasks tab
945
+ this.taskClicked.emit(task);
946
+ }
775
947
  // Scroll functionality (pattern from skip-chat)
776
948
  checkScroll() {
777
949
  if (!this.scrollContainer)
@@ -809,20 +981,13 @@ export class ConversationChatAreaComponent {
809
981
  element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
810
982
  }
811
983
  }
812
- getScrollToBottomIconPosition() {
813
- if (!this.scrollContainer) {
814
- return window.innerWidth / 2;
815
- }
816
- const rect = this.scrollContainer.nativeElement.getBoundingClientRect();
817
- return rect.left + (rect.width / 2);
818
- }
819
- 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)); };
984
+ static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationStateService), i0.ɵɵdirectiveInject(i2.DataCacheService), i0.ɵɵdirectiveInject(i3.AgentStateService), i0.ɵɵdirectiveInject(i4.ConversationAgentService), i0.ɵɵdirectiveInject(i5.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
820
985
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
821
986
  i0.ɵɵviewQuery(_c0, 5);
822
987
  } if (rf & 2) {
823
988
  let _t;
824
989
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
825
- } }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord" }, decls: 18, vars: 21, 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", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap"], ["class", "scroll-to-bottom-icon", 3, "left", "click", 4, "ngIf"], [1, "chat-input-container"], [3, "conversationId", "currentUser", "conversationHistory", "disabled", "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", 4, "ngIf"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [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, "currentUser"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions"], ["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", 3, "click"], [1, "fas", "fa-arrow-down"], [3, "messageSent", "agentResponse", "agentRunDetected", "artifactCreated", "conversationRenamed", "conversationId", "currentUser", "conversationHistory", "disabled"], [1, "resize-handle", 3, "mousedown"], [1, "chat-artifact-pane"], [3, "closed", "artifactId", "currentUser"], [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"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [1, "artifact-modal-card", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
990
+ } }, inputs: { environmentId: "environmentId", currentUser: "currentUser" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked" }, decls: 18, vars: 21, 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", "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"], [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", "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"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
826
991
  const _r1 = i0.ɵɵgetCurrentView();
827
992
  i0.ɵɵelementStart(0, "div", 1);
828
993
  i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 19, 11, "div", 2);
@@ -830,23 +995,22 @@ export class ConversationChatAreaComponent {
830
995
  i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Template_div_scroll_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.checkScroll()); });
831
996
  i0.ɵɵelementStart(7, "mj-conversation-message-list", 7);
832
997
  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)); });
833
- i0.ɵɵelementEnd()();
834
- i0.ɵɵtemplate(8, ConversationChatAreaComponent_span_8_Template, 2, 2, "span", 8);
998
+ i0.ɵɵelementEnd();
999
+ i0.ɵɵtemplate(8, ConversationChatAreaComponent_span_8_Template, 2, 0, "span", 8);
1000
+ i0.ɵɵelementEnd();
835
1001
  i0.ɵɵelementStart(9, "div", 9);
836
- i0.ɵɵtemplate(10, ConversationChatAreaComponent_mj_message_input_10_Template, 1, 4, "mj-message-input", 10);
1002
+ i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_10_Template, 5, 0, "div", 10)(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1, "mj-message-input", 11);
837
1003
  i0.ɵɵelementEnd()()();
838
- i0.ɵɵtemplate(11, ConversationChatAreaComponent_Conditional_11_Template, 3, 4);
1004
+ i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 7);
839
1005
  i0.ɵɵelementEnd()();
840
- i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 1, 3, "mj-thread-panel", 11);
841
- i0.ɵɵelementStart(13, "mj-export-modal", 12);
842
- i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_export_modal_cancelled_13_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportModalCancelled()); })("exported", function ConversationChatAreaComponent_Template_mj_export_modal_exported_13_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportModalComplete()); });
1006
+ i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_Template, 1, 3, "mj-thread-panel", 12);
1007
+ i0.ɵɵelementStart(14, "mj-export-modal", 13);
1008
+ i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_export_modal_cancelled_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportModalCancelled()); })("exported", function ConversationChatAreaComponent_Template_mj_export_modal_exported_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onExportModalComplete()); });
843
1009
  i0.ɵɵelementEnd();
844
- i0.ɵɵelementStart(14, "mj-members-modal", 13);
845
- i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_14_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showMembersModal = false); });
1010
+ i0.ɵɵelementStart(15, "mj-members-modal", 14);
1011
+ 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); });
846
1012
  i0.ɵɵelementEnd();
847
- i0.ɵɵtemplate(15, ConversationChatAreaComponent_Conditional_15_Template, 9, 3, "div", 14);
848
- i0.ɵɵelement(16, "mj-active-tasks-panel");
849
- i0.ɵɵtemplate(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 14);
1013
+ i0.ɵɵtemplate(16, ConversationChatAreaComponent_Conditional_16_Template, 9, 3, "div", 15)(17, ConversationChatAreaComponent_Conditional_17_Template, 11, 1, "div", 15);
850
1014
  } if (rf & 2) {
851
1015
  i0.ɵɵadvance();
852
1016
  i0.ɵɵproperty("ngIf", ctx.conversationState.activeConversation);
@@ -857,25 +1021,25 @@ export class ConversationChatAreaComponent {
857
1021
  i0.ɵɵadvance();
858
1022
  i0.ɵɵproperty("ngIf", ctx.showScrollToBottomIcon && ctx.messages && ctx.messages.length > 0);
859
1023
  i0.ɵɵadvance(2);
860
- i0.ɵɵproperty("ngIf", ctx.conversationState.activeConversation);
861
- i0.ɵɵadvance();
862
- i0.ɵɵconditional(ctx.showArtifactPanel && ctx.selectedArtifactId ? 11 : -1);
1024
+ i0.ɵɵconditional(ctx.isLoadingPeripheralData ? 10 : 11);
1025
+ i0.ɵɵadvance(2);
1026
+ i0.ɵɵconditional(ctx.showArtifactPanel && ctx.selectedArtifactId ? 12 : -1);
863
1027
  i0.ɵɵadvance();
864
- i0.ɵɵconditional(ctx.conversationState.activeThreadId ? 12 : -1);
1028
+ i0.ɵɵconditional(ctx.conversationState.activeThreadId ? 13 : -1);
865
1029
  i0.ɵɵadvance();
866
1030
  i0.ɵɵproperty("isVisible", ctx.showExportModal)("conversation", ctx.conversationState.activeConversation || undefined)("currentUser", ctx.currentUser);
867
1031
  i0.ɵɵadvance();
868
1032
  i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.conversationState.activeConversation || undefined)("currentUser", ctx.currentUser);
869
1033
  i0.ɵɵadvance();
870
- i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversationState.activeConversation ? 15 : -1);
871
- i0.ɵɵadvance(2);
1034
+ i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversationState.activeConversation ? 16 : -1);
1035
+ i0.ɵɵadvance();
872
1036
  i0.ɵɵconditional(ctx.showArtifactsModal ? 17 : -1);
873
- } }, dependencies: [i5.NgIf, i6.MessageListComponent, i7.MessageInputComponent, i8.ThreadPanelComponent, i9.ArtifactViewerPanelComponent, i10.ProjectSelectorComponent, i11.TasksDropdownComponent, i12.ActiveAgentIndicatorComponent, i13.ActiveTasksPanelComponent, 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 position: relative;\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}\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 80px;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\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}\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.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 align-items: center;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\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}"] });
1037
+ } }, 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}"] });
874
1038
  }
875
1039
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
876
1040
  type: Component,
877
- 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-tasks-dropdown [currentUser]=\"currentUser\"></mj-tasks-dropdown>\n <mj-active-agent-indicator\n [conversationId]=\"conversationState.activeConversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n Share\n </button>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\" [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 </div>\n\n <!-- Scroll to Bottom Icon -->\n <span class=\"scroll-to-bottom-icon\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n [style.left.px]=\"getScrollToBottomIconPosition()\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\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 </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 (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<!-- Active Tasks Panel -->\n<mj-active-tasks-panel></mj-active-tasks-panel>\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\" (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\">Version {{artifact.versionId.substring(0, 8)}}</div>\n </div>\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\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 position: relative;\n}\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n}\n.scroll-to-bottom-icon {\n position: absolute;\n bottom: 80px;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\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}\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.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 align-items: center;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\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}"] }]
878
- }], () => [{ type: i1.ConversationStateService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }], { environmentId: [{
1041
+ 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}"] }]
1042
+ }], () => [{ type: i1.ConversationStateService }, { type: i2.DataCacheService }, { type: i3.AgentStateService }, { type: i4.ConversationAgentService }, { type: i5.ActiveTasksService }, { type: i0.ChangeDetectorRef }], { environmentId: [{
879
1043
  type: Input
880
1044
  }], currentUser: [{
881
1045
  type: Input
@@ -883,9 +1047,11 @@ export class ConversationChatAreaComponent {
883
1047
  type: Output
884
1048
  }], openEntityRecord: [{
885
1049
  type: Output
1050
+ }], taskClicked: [{
1051
+ type: Output
886
1052
  }], scrollContainer: [{
887
1053
  type: ViewChild,
888
1054
  args: ['scrollContainer']
889
1055
  }] }); })();
890
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 14 }); })();
1056
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 16 }); })();
891
1057
  //# sourceMappingURL=conversation-chat-area.component.js.map