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