@memberjunction/ng-conversations 5.44.0 → 5.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +3 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +16 -12
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +16 -12
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +10 -7
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +3 -1
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +10 -8
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +103 -0
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -0
- package/dist/lib/components/composer/ai-composer.component.js +263 -0
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +3 -4
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +36 -36
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +5 -6
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +35 -20
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +2 -3
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +17 -17
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +11 -3
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +34 -10
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.d.ts +73 -0
- package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -0
- package/dist/lib/components/sidebar/routines-section.component.js +211 -0
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +12 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +37 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -5
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +35 -26
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/composer-plugins/agent-mention.provider.d.ts +16 -0
- package/dist/lib/composer-plugins/agent-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/agent-mention.provider.js +28 -0
- package/dist/lib/composer-plugins/agent-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +20 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +32 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/load-composer-plugins.d.ts +9 -0
- package/dist/lib/composer-plugins/load-composer-plugins.d.ts.map +1 -0
- package/dist/lib/composer-plugins/load-composer-plugins.js +17 -0
- package/dist/lib/composer-plugins/load-composer-plugins.js.map +1 -0
- package/dist/lib/composer-plugins/record-mention.provider.d.ts +14 -0
- package/dist/lib/composer-plugins/record-mention.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/record-mention.provider.js +26 -0
- package/dist/lib/composer-plugins/record-mention.provider.js.map +1 -0
- package/dist/lib/composer-plugins/skill-command.provider.d.ts +15 -0
- package/dist/lib/composer-plugins/skill-command.provider.d.ts.map +1 -0
- package/dist/lib/composer-plugins/skill-command.provider.js +27 -0
- package/dist/lib/composer-plugins/skill-command.provider.js.map +1 -0
- package/dist/lib/conversations.module.d.ts +74 -73
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +33 -13
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +4 -1
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +7 -0
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +20 -0
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +27 -20
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +55 -16
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/public-api.d.ts +23 -3
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +38 -3
- package/dist/public-api.js.map +1 -1
- package/package.json +29 -27
- package/dist/lib/components/mention/mention-dropdown.component.d.ts +0 -53
- package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +0 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +0 -297
- package/dist/lib/components/mention/mention-dropdown.component.js.map +0 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts +0 -256
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +0 -1
- package/dist/lib/components/mention/mention-editor.component.js +0 -1247
- package/dist/lib/components/mention/mention-editor.component.js.map +0 -1
- package/dist/lib/components/message/message-input-box.component.d.ts +0 -132
- package/dist/lib/components/message/message-input-box.component.d.ts.map +0 -1
- package/dist/lib/components/message/message-input-box.component.js +0 -327
- package/dist/lib/components/message/message-input-box.component.js.map +0 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { CompositeKey } from '@memberjunction/core';
|
|
2
|
+
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import { takeUntil } from 'rxjs/operators';
|
|
5
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
6
|
+
import { UserRoutineEngine } from '@memberjunction/core-entities';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@memberjunction/ng-user-routines";
|
|
9
|
+
function RoutinesSectionComponent_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
10
|
+
i0.ɵɵelementStart(0, "span", 4);
|
|
11
|
+
i0.ɵɵtext(1);
|
|
12
|
+
i0.ɵɵelementEnd();
|
|
13
|
+
} if (rf & 2) {
|
|
14
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
15
|
+
i0.ɵɵadvance();
|
|
16
|
+
i0.ɵɵtextInterpolate(ctx_r1.ActiveCount);
|
|
17
|
+
} }
|
|
18
|
+
function RoutinesSectionComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
20
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "button", 1);
|
|
21
|
+
i0.ɵɵlistener("click", function RoutinesSectionComponent_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenRoutines()); });
|
|
22
|
+
i0.ɵɵelement(2, "i", 2);
|
|
23
|
+
i0.ɵɵelementStart(3, "span", 3);
|
|
24
|
+
i0.ɵɵtext(4, "Routines");
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
i0.ɵɵconditionalCreate(5, RoutinesSectionComponent_Conditional_0_Conditional_5_Template, 2, 1, "span", 4);
|
|
27
|
+
i0.ɵɵelement(6, "span", 5);
|
|
28
|
+
i0.ɵɵelementStart(7, "span", 6);
|
|
29
|
+
i0.ɵɵlistener("click", function RoutinesSectionComponent_Conditional_0_Template_span_click_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.NewRoutine($event)); });
|
|
30
|
+
i0.ɵɵelement(8, "i", 7);
|
|
31
|
+
i0.ɵɵelementEnd();
|
|
32
|
+
i0.ɵɵelementStart(9, "span", 8);
|
|
33
|
+
i0.ɵɵelement(10, "i", 9);
|
|
34
|
+
i0.ɵɵelementEnd()();
|
|
35
|
+
i0.ɵɵelementStart(11, "mj-user-routines-slide-in", 10);
|
|
36
|
+
i0.ɵɵtwoWayListener("VisibleChange", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_VisibleChange_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SlideInVisible, $event) || (ctx_r1.SlideInVisible = $event); return i0.ɵɵresetView($event); });
|
|
37
|
+
i0.ɵɵlistener("Closed", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_Closed_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSlideInClosed()); })("HistoryRecordOpened", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_HistoryRecordOpened_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnHistoryRecordOpened($event)); })("ConversationOpened", function RoutinesSectionComponent_Conditional_0_Template_mj_user_routines_slide_in_ConversationOpened_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnConversationOpened($event)); });
|
|
38
|
+
i0.ɵɵelementEnd()();
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
41
|
+
i0.ɵɵadvance();
|
|
42
|
+
i0.ɵɵproperty("title", ctx_r1.HeaderTitle);
|
|
43
|
+
i0.ɵɵadvance(4);
|
|
44
|
+
i0.ɵɵconditional(ctx_r1.ActiveCount > 0 ? 5 : -1);
|
|
45
|
+
i0.ɵɵadvance(6);
|
|
46
|
+
i0.ɵɵproperty("Provider", ctx_r1.Provider);
|
|
47
|
+
i0.ɵɵtwoWayProperty("Visible", ctx_r1.SlideInVisible);
|
|
48
|
+
i0.ɵɵproperty("InitialRoutineID", ctx_r1.SlideInRoutineID)("StartInNewRoutine", ctx_r1.SlideInNewRoutine);
|
|
49
|
+
} }
|
|
50
|
+
/**
|
|
51
|
+
* Compact "Routines" entry pinned at the very bottom of the conversations left
|
|
52
|
+
* sidebar: a single header row — mark, "Routines", the ACTIVE routine count, a "+"
|
|
53
|
+
* (straight into the New Routine editor) and a details chevron. No routine rows —
|
|
54
|
+
* the full command-center slide-in is one click away and owns all detail.
|
|
55
|
+
*
|
|
56
|
+
* Visibility gates (both must pass):
|
|
57
|
+
* 1. `ShowRoutines` — host opt-out input bubbled from the top-level conversations
|
|
58
|
+
* workspace (default true).
|
|
59
|
+
* 2. The current user must have Read permission on 'MJ: User Routines'
|
|
60
|
+
* (EntityInfo user-permission check) — hidden entirely otherwise.
|
|
61
|
+
*/
|
|
62
|
+
export class RoutinesSectionComponent extends BaseAngularComponent {
|
|
63
|
+
cdr = inject(ChangeDetectorRef);
|
|
64
|
+
destroy$ = new Subject();
|
|
65
|
+
_showRoutines = true;
|
|
66
|
+
/** Host opt-out (bubbled from the top-level conversations component). Default true. */
|
|
67
|
+
set ShowRoutines(value) {
|
|
68
|
+
if (value !== this._showRoutines) {
|
|
69
|
+
this._showRoutines = value;
|
|
70
|
+
if (value && !this.initialized) {
|
|
71
|
+
void this.initialize();
|
|
72
|
+
}
|
|
73
|
+
this.cdr.markForCheck();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
get ShowRoutines() {
|
|
77
|
+
return this._showRoutines;
|
|
78
|
+
}
|
|
79
|
+
/** True when the current user may read routines (permission gate). */
|
|
80
|
+
CanRead = false;
|
|
81
|
+
/** Number of Active routines — the header badge. */
|
|
82
|
+
ActiveCount = 0;
|
|
83
|
+
/** Total routines of any status (for the header tooltip). */
|
|
84
|
+
TotalCount = 0;
|
|
85
|
+
/**
|
|
86
|
+
* A run history row's linked execution record (Agent Run / Prompt Run / Action Log)
|
|
87
|
+
* was clicked. Same shape as the chat area's openEntityRecord — the host (Explorer
|
|
88
|
+
* wrapper or workspace) routes it to navigation; this package never navigates itself.
|
|
89
|
+
*/
|
|
90
|
+
openEntityRecord = new EventEmitter();
|
|
91
|
+
/**
|
|
92
|
+
* The user asked to open a routine's dedicated conversation (the hidden,
|
|
93
|
+
* Application-scoped thread its runs append to). Emits the conversation ID;
|
|
94
|
+
* the host selects it in chat — this component closes the slide-in first.
|
|
95
|
+
*/
|
|
96
|
+
openConversation = new EventEmitter();
|
|
97
|
+
/** Slide-in open state. */
|
|
98
|
+
SlideInVisible = false;
|
|
99
|
+
/** Routine to open the slide-in on (history view). */
|
|
100
|
+
SlideInRoutineID = null;
|
|
101
|
+
/** Whether the slide-in opens straight on the New Routine editor. */
|
|
102
|
+
SlideInNewRoutine = false;
|
|
103
|
+
initialized = false;
|
|
104
|
+
/** Section renders only when the opt-out AND permission gates both pass. */
|
|
105
|
+
get IsVisible() {
|
|
106
|
+
return this._showRoutines && this.CanRead;
|
|
107
|
+
}
|
|
108
|
+
/** Header tooltip: active/total breakdown. */
|
|
109
|
+
get HeaderTitle() {
|
|
110
|
+
if (this.TotalCount === 0) {
|
|
111
|
+
return 'Routines — none yet, click + to create one';
|
|
112
|
+
}
|
|
113
|
+
return `Routines — ${this.ActiveCount} active of ${this.TotalCount}. Click to open.`;
|
|
114
|
+
}
|
|
115
|
+
async ngOnInit() {
|
|
116
|
+
if (this._showRoutines) {
|
|
117
|
+
await this.initialize();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
ngOnDestroy() {
|
|
121
|
+
this.destroy$.next();
|
|
122
|
+
this.destroy$.complete();
|
|
123
|
+
}
|
|
124
|
+
/** Opens the slide-in on the routines list (header / details click). */
|
|
125
|
+
OpenRoutines() {
|
|
126
|
+
this.SlideInRoutineID = null;
|
|
127
|
+
this.SlideInNewRoutine = false;
|
|
128
|
+
this.SlideInVisible = true;
|
|
129
|
+
this.cdr.markForCheck();
|
|
130
|
+
}
|
|
131
|
+
/** Opens the slide-in straight on the New Routine editor ("+" affordance). */
|
|
132
|
+
NewRoutine(event) {
|
|
133
|
+
event.stopPropagation();
|
|
134
|
+
this.SlideInRoutineID = null;
|
|
135
|
+
this.SlideInNewRoutine = true;
|
|
136
|
+
this.SlideInVisible = true;
|
|
137
|
+
this.cdr.markForCheck();
|
|
138
|
+
}
|
|
139
|
+
/** Opens the routine's conversation in the host chat surface (closing the slide-in). */
|
|
140
|
+
OnConversationOpened(args) {
|
|
141
|
+
this.OnSlideInClosed();
|
|
142
|
+
this.openConversation.emit(args.ConversationID);
|
|
143
|
+
}
|
|
144
|
+
/** Bridges the slide-in's HistoryRecordOpened to the standard openEntityRecord chain. */
|
|
145
|
+
OnHistoryRecordOpened(args) {
|
|
146
|
+
this.openEntityRecord.emit({ entityName: args.EntityName, compositeKey: CompositeKey.FromID(args.RecordID) });
|
|
147
|
+
}
|
|
148
|
+
OnSlideInClosed() {
|
|
149
|
+
this.SlideInVisible = false;
|
|
150
|
+
this.SlideInRoutineID = null;
|
|
151
|
+
this.SlideInNewRoutine = false;
|
|
152
|
+
this.cdr.markForCheck();
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------
|
|
155
|
+
// Internals
|
|
156
|
+
// ---------------------------------------------------------------
|
|
157
|
+
async initialize() {
|
|
158
|
+
if (this.initialized) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.initialized = true;
|
|
162
|
+
const p = this.ProviderToUse;
|
|
163
|
+
// Permission gate: hide entirely when the user lacks Read on the entity
|
|
164
|
+
// (or the entity isn't present in this instance's metadata).
|
|
165
|
+
const entityInfo = p.EntityByName('MJ: User Routines');
|
|
166
|
+
const permissions = entityInfo && p.CurrentUser ? entityInfo.GetUserPermisions(p.CurrentUser) : null;
|
|
167
|
+
this.CanRead = permissions?.CanRead === true;
|
|
168
|
+
if (!this.CanRead) {
|
|
169
|
+
this.cdr.markForCheck();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const engine = UserRoutineEngine.GetProviderInstance(p, UserRoutineEngine);
|
|
174
|
+
await engine.Config(false, p.CurrentUser, p);
|
|
175
|
+
engine.Routines$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
176
|
+
this.rebuildCounts(engine);
|
|
177
|
+
});
|
|
178
|
+
this.rebuildCounts(engine);
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
console.error('[RoutinesSection] Failed to load routines:', e);
|
|
182
|
+
this.ActiveCount = 0;
|
|
183
|
+
this.TotalCount = 0;
|
|
184
|
+
}
|
|
185
|
+
this.cdr.markForCheck();
|
|
186
|
+
}
|
|
187
|
+
rebuildCounts(engine) {
|
|
188
|
+
const routines = engine.Routines;
|
|
189
|
+
this.TotalCount = routines.length;
|
|
190
|
+
this.ActiveCount = routines.filter((r) => r.Status === 'Active').length;
|
|
191
|
+
this.cdr.markForCheck();
|
|
192
|
+
}
|
|
193
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵRoutinesSectionComponent_BaseFactory; return function RoutinesSectionComponent_Factory(__ngFactoryType__) { return (ɵRoutinesSectionComponent_BaseFactory || (ɵRoutinesSectionComponent_BaseFactory = i0.ɵɵgetInheritedFactory(RoutinesSectionComponent)))(__ngFactoryType__ || RoutinesSectionComponent); }; })();
|
|
194
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RoutinesSectionComponent, selectors: [["mj-conversation-routines-section"]], inputs: { ShowRoutines: "ShowRoutines" }, outputs: { openEntityRecord: "openEntityRecord", openConversation: "openConversation" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [[1, "crs-section"], ["type", "button", 1, "crs-header", 3, "click", "title"], [1, "fa-solid", "fa-business-time", "crs-mark"], [1, "crs-title"], [1, "crs-count"], [1, "crs-spacer"], ["role", "button", "title", "New routine", 1, "crs-add", 3, "click"], [1, "fa-solid", "fa-plus"], ["role", "button", "title", "Open routines", 1, "crs-details"], [1, "fa-solid", "fa-chevron-right"], [3, "VisibleChange", "Closed", "HistoryRecordOpened", "ConversationOpened", "Provider", "Visible", "InitialRoutineID", "StartInNewRoutine"]], template: function RoutinesSectionComponent_Template(rf, ctx) { if (rf & 1) {
|
|
195
|
+
i0.ɵɵconditionalCreate(0, RoutinesSectionComponent_Conditional_0_Template, 12, 6, "div", 0);
|
|
196
|
+
} if (rf & 2) {
|
|
197
|
+
i0.ɵɵconditional(ctx.IsVisible ? 0 : -1);
|
|
198
|
+
} }, dependencies: [i1.UserRoutinesSlideInComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.crs-section[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n padding: 6px 8px;\n}\n\n.crs-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n border-radius: var(--mj-radius-md, 8px);\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.crs-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.crs-mark[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n.crs-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n}\n\n.crs-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.crs-spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n}\n\n.crs-add[_ngcontent-%COMP%], \n.crs-details[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 6px);\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.crs-add[_ngcontent-%COMP%]:hover, \n.crs-details[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.crs-details[_ngcontent-%COMP%] {\n font-size: 10px;\n}"] });
|
|
199
|
+
}
|
|
200
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RoutinesSectionComponent, [{
|
|
201
|
+
type: Component,
|
|
202
|
+
args: [{ standalone: false, selector: 'mj-conversation-routines-section', template: "@if (IsVisible) {\n <div class=\"crs-section\">\n <button type=\"button\" class=\"crs-header\" [title]=\"HeaderTitle\" (click)=\"OpenRoutines()\">\n <i class=\"fa-solid fa-business-time crs-mark\"></i>\n <span class=\"crs-title\">Routines</span>\n @if (ActiveCount > 0) {\n <span class=\"crs-count\">{{ ActiveCount }}</span>\n }\n <span class=\"crs-spacer\"></span>\n <span class=\"crs-add\" role=\"button\" title=\"New routine\" (click)=\"NewRoutine($event)\">\n <i class=\"fa-solid fa-plus\"></i>\n </span>\n <span class=\"crs-details\" role=\"button\" title=\"Open routines\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </span>\n </button>\n\n <mj-user-routines-slide-in\n [Provider]=\"Provider\"\n [(Visible)]=\"SlideInVisible\"\n [InitialRoutineID]=\"SlideInRoutineID\"\n [StartInNewRoutine]=\"SlideInNewRoutine\"\n (Closed)=\"OnSlideInClosed()\"\n (HistoryRecordOpened)=\"OnHistoryRecordOpened($event)\"\n (ConversationOpened)=\"OnConversationOpened($event)\">\n </mj-user-routines-slide-in>\n </div>\n}\n", styles: [":host {\n display: block;\n}\n\n.crs-section {\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n padding: 6px 8px;\n}\n\n.crs-header {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n background: transparent;\n border-radius: var(--mj-radius-md, 8px);\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.crs-header:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.crs-mark {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n.crs-title {\n font-size: 13px;\n font-weight: 600;\n}\n\n.crs-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.crs-spacer {\n flex: 1 1 auto;\n}\n\n.crs-add,\n.crs-details {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 6px);\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.crs-add:hover,\n.crs-details:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.crs-details {\n font-size: 10px;\n}\n"] }]
|
|
203
|
+
}], null, { ShowRoutines: [{
|
|
204
|
+
type: Input
|
|
205
|
+
}], openEntityRecord: [{
|
|
206
|
+
type: Output
|
|
207
|
+
}], openConversation: [{
|
|
208
|
+
type: Output
|
|
209
|
+
}] }); })();
|
|
210
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoutinesSectionComponent, { className: "RoutinesSectionComponent", filePath: "src/lib/components/sidebar/routines-section.component.ts", lineNumber: 27 }); })();
|
|
211
|
+
//# sourceMappingURL=routines-section.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routines-section.component.js","sourceRoot":"","sources":["../../../../src/lib/components/sidebar/routines-section.component.ts","../../../../src/lib/components/sidebar/routines-section.component.html"],"names":[],"mappings":"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","sourcesContent":["import { CompositeKey } from '@memberjunction/core';\nimport { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJUserRoutineEntity, UserRoutineEngine } from '@memberjunction/core-entities';\nimport { ConversationOpenedEventArgs, HistoryRecordOpenedEventArgs } from '@memberjunction/ng-user-routines';\n\n/**\n * Compact \"Routines\" entry pinned at the very bottom of the conversations left\n * sidebar: a single header row — mark, \"Routines\", the ACTIVE routine count, a \"+\"\n * (straight into the New Routine editor) and a details chevron. No routine rows —\n * the full command-center slide-in is one click away and owns all detail.\n *\n * Visibility gates (both must pass):\n * 1. `ShowRoutines` — host opt-out input bubbled from the top-level conversations\n * workspace (default true).\n * 2. The current user must have Read permission on 'MJ: User Routines'\n * (EntityInfo user-permission check) — hidden entirely otherwise.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-routines-section',\n templateUrl: './routines-section.component.html',\n styleUrls: ['./routines-section.component.css'],\n})\nexport class RoutinesSectionComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n\n private _showRoutines = true;\n /** Host opt-out (bubbled from the top-level conversations component). Default true. */\n @Input()\n public set ShowRoutines(value: boolean) {\n if (value !== this._showRoutines) {\n this._showRoutines = value;\n if (value && !this.initialized) {\n void this.initialize();\n }\n this.cdr.markForCheck();\n }\n }\n public get ShowRoutines(): boolean {\n return this._showRoutines;\n }\n\n /** True when the current user may read routines (permission gate). */\n public CanRead = false;\n /** Number of Active routines — the header badge. */\n public ActiveCount = 0;\n /** Total routines of any status (for the header tooltip). */\n public TotalCount = 0;\n\n /**\n * A run history row's linked execution record (Agent Run / Prompt Run / Action Log)\n * was clicked. Same shape as the chat area's openEntityRecord — the host (Explorer\n * wrapper or workspace) routes it to navigation; this package never navigates itself.\n */\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; compositeKey: CompositeKey }>();\n\n /**\n * The user asked to open a routine's dedicated conversation (the hidden,\n * Application-scoped thread its runs append to). Emits the conversation ID;\n * the host selects it in chat — this component closes the slide-in first.\n */\n @Output() openConversation = new EventEmitter<string>();\n\n /** Slide-in open state. */\n public SlideInVisible = false;\n /** Routine to open the slide-in on (history view). */\n public SlideInRoutineID: string | null = null;\n /** Whether the slide-in opens straight on the New Routine editor. */\n public SlideInNewRoutine = false;\n\n private initialized = false;\n\n /** Section renders only when the opt-out AND permission gates both pass. */\n public get IsVisible(): boolean {\n return this._showRoutines && this.CanRead;\n }\n\n /** Header tooltip: active/total breakdown. */\n public get HeaderTitle(): string {\n if (this.TotalCount === 0) {\n return 'Routines — none yet, click + to create one';\n }\n return `Routines — ${this.ActiveCount} active of ${this.TotalCount}. Click to open.`;\n }\n\n async ngOnInit(): Promise<void> {\n if (this._showRoutines) {\n await this.initialize();\n }\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /** Opens the slide-in on the routines list (header / details click). */\n public OpenRoutines(): void {\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = false;\n this.SlideInVisible = true;\n this.cdr.markForCheck();\n }\n\n /** Opens the slide-in straight on the New Routine editor (\"+\" affordance). */\n public NewRoutine(event: Event): void {\n event.stopPropagation();\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = true;\n this.SlideInVisible = true;\n this.cdr.markForCheck();\n }\n\n /** Opens the routine's conversation in the host chat surface (closing the slide-in). */\n public OnConversationOpened(args: ConversationOpenedEventArgs): void {\n this.OnSlideInClosed();\n this.openConversation.emit(args.ConversationID);\n }\n\n /** Bridges the slide-in's HistoryRecordOpened to the standard openEntityRecord chain. */\n public OnHistoryRecordOpened(args: HistoryRecordOpenedEventArgs): void {\n this.openEntityRecord.emit({ entityName: args.EntityName, compositeKey: CompositeKey.FromID(args.RecordID) });\n }\n\n public OnSlideInClosed(): void {\n this.SlideInVisible = false;\n this.SlideInRoutineID = null;\n this.SlideInNewRoutine = false;\n this.cdr.markForCheck();\n }\n\n // ---------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------\n private async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n this.initialized = true;\n const p = this.ProviderToUse;\n\n // Permission gate: hide entirely when the user lacks Read on the entity\n // (or the entity isn't present in this instance's metadata).\n const entityInfo = p.EntityByName('MJ: User Routines');\n const permissions = entityInfo && p.CurrentUser ? entityInfo.GetUserPermisions(p.CurrentUser) : null;\n this.CanRead = permissions?.CanRead === true;\n if (!this.CanRead) {\n this.cdr.markForCheck();\n return;\n }\n\n try {\n const engine = UserRoutineEngine.GetProviderInstance<UserRoutineEngine>(p, UserRoutineEngine) as UserRoutineEngine;\n await engine.Config(false, p.CurrentUser, p);\n engine.Routines$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.rebuildCounts(engine);\n });\n this.rebuildCounts(engine);\n } catch (e) {\n console.error('[RoutinesSection] Failed to load routines:', e);\n this.ActiveCount = 0;\n this.TotalCount = 0;\n }\n this.cdr.markForCheck();\n }\n\n private rebuildCounts(engine: UserRoutineEngine): void {\n const routines = engine.Routines;\n this.TotalCount = routines.length;\n this.ActiveCount = routines.filter((r: MJUserRoutineEntity) => r.Status === 'Active').length;\n this.cdr.markForCheck();\n }\n}\n","@if (IsVisible) {\n <div class=\"crs-section\">\n <button type=\"button\" class=\"crs-header\" [title]=\"HeaderTitle\" (click)=\"OpenRoutines()\">\n <i class=\"fa-solid fa-business-time crs-mark\"></i>\n <span class=\"crs-title\">Routines</span>\n @if (ActiveCount > 0) {\n <span class=\"crs-count\">{{ ActiveCount }}</span>\n }\n <span class=\"crs-spacer\"></span>\n <span class=\"crs-add\" role=\"button\" title=\"New routine\" (click)=\"NewRoutine($event)\">\n <i class=\"fa-solid fa-plus\"></i>\n </span>\n <span class=\"crs-details\" role=\"button\" title=\"Open routines\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </span>\n </button>\n\n <mj-user-routines-slide-in\n [Provider]=\"Provider\"\n [(Visible)]=\"SlideInVisible\"\n [InitialRoutineID]=\"SlideInRoutineID\"\n [StartInNewRoutine]=\"SlideInNewRoutine\"\n (Closed)=\"OnSlideInClosed()\"\n (HistoryRecordOpened)=\"OnHistoryRecordOpened($event)\"\n (ConversationOpened)=\"OnConversationOpened($event)\">\n </mj-user-routines-slide-in>\n </div>\n}\n"]}
|
|
@@ -20,12 +20,24 @@ export declare class TasksDropdownComponent implements OnInit, OnDestroy {
|
|
|
20
20
|
currentConversationTasks: ActiveTask[];
|
|
21
21
|
otherConversationTasks: ActiveTask[];
|
|
22
22
|
private destroy$;
|
|
23
|
+
/**
|
|
24
|
+
* Wall-clock snapshot the elapsed-time template bindings read from. The template
|
|
25
|
+
* must NOT call Date.now() (directly or via getElapsedTime) — a change-detection
|
|
26
|
+
* pass that straddles a second boundary would then see two different values for
|
|
27
|
+
* the same binding and throw NG0100 in dev mode. Instead this snapshot is stable
|
|
28
|
+
* within a CD pass and advances via a 1s interval that runs only while the
|
|
29
|
+
* dropdown is open (the only time elapsed text is rendered).
|
|
30
|
+
*/
|
|
31
|
+
private _now;
|
|
32
|
+
private elapsedTimer;
|
|
23
33
|
constructor(activeTasksService: ActiveTasksService);
|
|
24
34
|
ngOnInit(): void;
|
|
25
35
|
ngOnDestroy(): void;
|
|
26
36
|
private groupTasks;
|
|
27
37
|
toggleDropdown(): void;
|
|
28
38
|
closeDropdown(): void;
|
|
39
|
+
private startElapsedTimer;
|
|
40
|
+
private stopElapsedTimer;
|
|
29
41
|
onTaskClick(task: ActiveTask): void;
|
|
30
42
|
getElapsedTime(task: ActiveTask): string;
|
|
31
43
|
getTrimmedStatus(status: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks-dropdown.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/tasks/tasks-dropdown.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;;AAKrF;;;GAGG;AACH,qBAifa,sBAAuB,YAAW,MAAM,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"tasks-dropdown.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/tasks/tasks-dropdown.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;;AAKrF;;;GAGG;AACH,qBAifa,sBAAuB,YAAW,MAAM,EAAE,SAAS;IAyB5D,OAAO,CAAC,kBAAkB;IAxBnB,WAAW,EAAG,QAAQ,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,WAAW,2BAAkC;IAC7C,sBAAsB;wBAAqC,MAAM;gBAAU,MAAM;OAAK;IAEzF,MAAM,EAAE,OAAO,CAAS;IACxB,QAAQ,EAAE,UAAU,EAAE,CAAM;IAC5B,wBAAwB,EAAE,UAAU,EAAE,CAAM;IAC5C,sBAAsB,EAAE,UAAU,EAAE,CAAM;IAEjD,OAAO,CAAC,QAAQ,CAAuB;IAEvC;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,YAAY,CAA+C;gBAGzD,kBAAkB,EAAE,kBAAkB;IAGhD,QAAQ;IAgBR,WAAW;IAMX,OAAO,CAAC,UAAU;IAUlB,cAAc,IAAI,IAAI;IAStB,aAAa,IAAI,IAAI;IAKrB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,gBAAgB;IAOxB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAanC,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAcxC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQxC;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAa5C;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;yCArJtC,sBAAsB;2CAAtB,sBAAsB;CAgKlC"}
|
|
@@ -206,6 +206,16 @@ export class TasksDropdownComponent {
|
|
|
206
206
|
currentConversationTasks = [];
|
|
207
207
|
otherConversationTasks = [];
|
|
208
208
|
destroy$ = new Subject();
|
|
209
|
+
/**
|
|
210
|
+
* Wall-clock snapshot the elapsed-time template bindings read from. The template
|
|
211
|
+
* must NOT call Date.now() (directly or via getElapsedTime) — a change-detection
|
|
212
|
+
* pass that straddles a second boundary would then see two different values for
|
|
213
|
+
* the same binding and throw NG0100 in dev mode. Instead this snapshot is stable
|
|
214
|
+
* within a CD pass and advances via a 1s interval that runs only while the
|
|
215
|
+
* dropdown is open (the only time elapsed text is rendered).
|
|
216
|
+
*/
|
|
217
|
+
_now = Date.now();
|
|
218
|
+
elapsedTimer = null;
|
|
209
219
|
constructor(activeTasksService) {
|
|
210
220
|
this.activeTasksService = activeTasksService;
|
|
211
221
|
}
|
|
@@ -226,6 +236,7 @@ export class TasksDropdownComponent {
|
|
|
226
236
|
ngOnDestroy() {
|
|
227
237
|
this.destroy$.next();
|
|
228
238
|
this.destroy$.complete();
|
|
239
|
+
this.stopElapsedTimer();
|
|
229
240
|
}
|
|
230
241
|
groupTasks() {
|
|
231
242
|
this.currentConversationTasks = this.allTasks.filter(task => task.conversationId === this.conversationId);
|
|
@@ -233,9 +244,33 @@ export class TasksDropdownComponent {
|
|
|
233
244
|
}
|
|
234
245
|
toggleDropdown() {
|
|
235
246
|
this.isOpen = !this.isOpen;
|
|
247
|
+
if (this.isOpen) {
|
|
248
|
+
this.startElapsedTimer();
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
this.stopElapsedTimer();
|
|
252
|
+
}
|
|
236
253
|
}
|
|
237
254
|
closeDropdown() {
|
|
238
255
|
this.isOpen = false;
|
|
256
|
+
this.stopElapsedTimer();
|
|
257
|
+
}
|
|
258
|
+
startElapsedTimer() {
|
|
259
|
+
this._now = Date.now(); // fresh snapshot for the first render
|
|
260
|
+
if (this.elapsedTimer) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
// Zone-patched interval: each tick triggers CD, so the elapsed text advances
|
|
264
|
+
// once per second while the dropdown is open. Stopped on close/destroy.
|
|
265
|
+
this.elapsedTimer = setInterval(() => {
|
|
266
|
+
this._now = Date.now();
|
|
267
|
+
}, 1000);
|
|
268
|
+
}
|
|
269
|
+
stopElapsedTimer() {
|
|
270
|
+
if (this.elapsedTimer) {
|
|
271
|
+
clearInterval(this.elapsedTimer);
|
|
272
|
+
this.elapsedTimer = null;
|
|
273
|
+
}
|
|
239
274
|
}
|
|
240
275
|
onTaskClick(task) {
|
|
241
276
|
// If task is from another conversation, emit navigation event
|
|
@@ -249,7 +284,8 @@ export class TasksDropdownComponent {
|
|
|
249
284
|
this.closeDropdown();
|
|
250
285
|
}
|
|
251
286
|
getElapsedTime(task) {
|
|
252
|
-
|
|
287
|
+
// Reads the CD-stable snapshot, never Date.now() — see _now for why (NG0100).
|
|
288
|
+
const elapsed = Math.max(0, this._now - task.startTime);
|
|
253
289
|
const seconds = Math.floor(elapsed / 1000);
|
|
254
290
|
if (seconds < 60) {
|
|
255
291
|
return `${seconds}s`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks-dropdown.component.js","sourceRoot":"","sources":["../../../../src/lib/components/tasks/tasks-dropdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { ActiveTasksService, ActiveTask } from '../../services/active-tasks.service';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n/**\n * Enhanced tasks dropdown component for chat header.\n * Shows ALL active tasks across ALL conversations, grouped by current vs other\n */\n@Component({\n standalone: false,\n selector: 'mj-tasks-dropdown',\n template: `\n <div class=\"tasks-dropdown-container\">\n <button\n class=\"active-tasks-btn\"\n (click)=\"toggleDropdown()\"\n [class.active]=\"isOpen\"\n [class.has-tasks]=\"allTasks.length > 0\"\n [title]=\"allTasks.length > 0 ? allTasks.length + ' active task' + (allTasks.length > 1 ? 's' : '') : 'View tasks'\">\n <i class=\"fas fa-bolt\"></i>\n @if (allTasks.length > 0) {\n <span class=\"task-count-badge\">{{ allTasks.length }}</span>\n }\n </button>\n \n @if (isOpen) {\n <div class=\"active-tasks-dropdown\">\n <div class=\"dropdown-header\">\n <div class=\"header-left\">\n @if (allTasks.length > 0) {\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n }\n @if (allTasks.length === 0) {\n <i class=\"fas fa-tasks\"></i>\n }\n <span>Active Tasks ({{ allTasks.length }})</span>\n </div>\n <button class=\"close-btn\" (click)=\"closeDropdown()\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"dropdown-content\">\n <!-- Current Conversation Tasks -->\n @if (currentConversationTasks.length > 0) {\n <div class=\"section\">\n <div class=\"section-header\">\n <i class=\"fas fa-comment\"></i>\n <span>Current Conversation ({{ currentConversationTasks.length }})</span>\n </div>\n @for (task of currentConversationTasks; track task) {\n <div class=\"active-task-item\"\n (click)=\"onTaskClick(task)\">\n <div class=\"task-status-indicator active\"></div>\n <div class=\"task-content\">\n <div class=\"task-title\">\n @if (getAgentLogoUrl(task.agentName)) {\n <img\n [src]=\"getAgentLogoUrl(task.agentName)\"\n class=\"agent-logo\"\n [alt]=\"task.agentName\" />\n }\n @if (!getAgentLogoUrl(task.agentName)) {\n <i\n [class]=\"getAgentIconClass(task.agentName)\"></i>\n }\n {{ task.agentName }}\n </div>\n <div class=\"task-status-text\">{{ getTrimmedStatus(task.status) }}</div>\n <div class=\"task-elapsed\">{{ getElapsedTime(task) }}</div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Other Conversations Tasks -->\n @if (otherConversationTasks.length > 0) {\n <div class=\"section\">\n <div class=\"section-header\">\n <i class=\"fas fa-comments\"></i>\n <span>Other Conversations ({{ otherConversationTasks.length }})</span>\n </div>\n @for (task of otherConversationTasks; track task) {\n <div class=\"active-task-item clickable\"\n (click)=\"onTaskClick(task)\">\n <div class=\"task-status-indicator active\"></div>\n <div class=\"task-content\">\n <div class=\"task-title\">\n @if (getAgentLogoUrl(task.agentName)) {\n <img\n [src]=\"getAgentLogoUrl(task.agentName)\"\n class=\"agent-logo\"\n [alt]=\"task.agentName\" />\n }\n @if (!getAgentLogoUrl(task.agentName)) {\n <i\n [class]=\"getAgentIconClass(task.agentName)\"></i>\n }\n {{ task.agentName }}\n <span class=\"go-btn\">\n <i class=\"fas fa-arrow-right\"></i>\n </span>\n </div>\n @if (task.conversationName) {\n <div class=\"task-conversation\">\n <i class=\"fas fa-message\"></i>\n {{ task.conversationName }}\n </div>\n }\n <div class=\"task-status-text\">{{ getTrimmedStatus(task.status) }}</div>\n <div class=\"task-elapsed\">{{ getElapsedTime(task) }}</div>\n </div>\n </div>\n }\n </div>\n }\n <!-- No Tasks State -->\n @if (allTasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-check-circle\"></i>\n <p>No active tasks</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n `,\n styles: [`\n .tasks-dropdown-container {\n position: relative;\n }\n\n .active-tasks-btn {\n background: transparent;\n padding: 8px 12px;\n border-radius: 6px;\n border: none;\n color: rgba(255,255,255,0.7);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: all 0.2s;\n }\n\n .active-tasks-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .active-tasks-btn.active {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .task-count-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 5px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n min-width: 18px;\n text-align: center;\n line-height: 1;\n box-shadow: var(--mj-shadow-sm);\n }\n\n .active-tasks-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n min-width: 420px;\n max-width: 500px;\n }\n\n .dropdown-header {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .header-left i {\n color: var(--mj-brand-primary);\n }\n\n .close-btn {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 18px;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n }\n\n .close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .dropdown-content {\n max-height: 500px;\n overflow-y: auto;\n }\n\n .section {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .section:last-child {\n border-bottom: none;\n }\n\n .section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n padding: 0 4px;\n }\n\n .section-header i {\n font-size: 11px;\n }\n\n .active-task-item {\n display: flex;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n transition: all 0.2s ease;\n }\n\n .active-task-item.clickable {\n cursor: pointer;\n }\n\n .active-task-item.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n transform: translateX(2px);\n }\n\n .active-task-item:last-child {\n margin-bottom: 0;\n }\n\n .task-status-indicator {\n width: 4px;\n border-radius: 2px;\n flex-shrink: 0;\n }\n\n .task-status-indicator.active {\n background: var(--mj-brand-primary);\n animation: pulse 2s ease-in-out infinite;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .task-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n }\n\n .task-title .agent-logo {\n width: 14px;\n height: 14px;\n object-fit: contain;\n flex-shrink: 0;\n }\n\n .go-btn {\n margin-left: auto;\n color: var(--mj-brand-primary);\n font-size: 10px;\n opacity: 0.7;\n }\n\n .active-task-item.clickable:hover .go-btn {\n opacity: 1;\n }\n\n .task-conversation {\n font-size: 11px;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .task-conversation i {\n font-size: 10px;\n }\n\n .task-status-text {\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .task-elapsed {\n font-size: 11px;\n color: var(--mj-brand-primary);\n font-weight: 600;\n }\n\n .no-tasks {\n padding: 40px 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 32px;\n margin-bottom: 8px;\n opacity: 0.5;\n color: var(--mj-status-success);\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n\n mj-task-widget {\n display: block;\n margin-bottom: 8px;\n }\n\n mj-task-widget:last-child {\n margin-bottom: 0;\n }\n\n /* Mobile adjustments: 481px - 768px */\n @media (max-width: 768px) {\n .active-tasks-btn {\n padding: 6px 10px;\n font-size: 12px;\n }\n\n .active-tasks-dropdown {\n position: fixed;\n top: auto;\n right: 8px;\n left: 8px;\n bottom: 8px;\n min-width: unset;\n max-width: unset;\n max-height: 60vh;\n }\n\n .dropdown-header {\n padding: 10px 12px;\n }\n\n .dropdown-content {\n max-height: calc(60vh - 48px);\n }\n\n .section {\n padding: 10px;\n }\n\n .section-header {\n font-size: 11px;\n margin-bottom: 10px;\n }\n\n .active-task-item {\n padding: 8px 10px;\n }\n\n .task-title {\n font-size: 13px;\n }\n\n .task-status-text {\n font-size: 11px;\n }\n\n .task-elapsed {\n font-size: 10px;\n }\n }\n\n /* Small Phone adjustments: <= 480px */\n @media (max-width: 480px) {\n .active-tasks-btn {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .active-tasks-dropdown {\n right: 4px;\n left: 4px;\n bottom: 4px;\n max-height: 70vh;\n }\n\n .dropdown-header {\n padding: 8px 10px;\n }\n\n .header-left {\n font-size: 13px;\n }\n\n .dropdown-content {\n max-height: calc(70vh - 44px);\n }\n\n .section {\n padding: 8px;\n }\n\n .section-header {\n font-size: 10px;\n margin-bottom: 8px;\n }\n\n .active-task-item {\n padding: 6px 8px;\n gap: 8px;\n }\n\n .task-title {\n font-size: 12px;\n }\n\n .task-status-text {\n font-size: 10px;\n }\n\n .task-elapsed {\n font-size: 9px;\n }\n\n .no-tasks {\n padding: 30px 12px;\n }\n\n .no-tasks i {\n font-size: 28px;\n }\n\n .no-tasks p {\n font-size: 13px;\n }\n }\n `]\n})\nexport class TasksDropdownComponent implements OnInit, OnDestroy {\n @Input() currentUser!: UserInfo;\n @Input() conversationId: string | null = null;\n @Output() taskClicked = new EventEmitter<ActiveTask>();\n @Output() navigateToConversation = new EventEmitter<{conversationId: string; taskId: string}>();\n\n public isOpen: boolean = false;\n public allTasks: ActiveTask[] = [];\n public currentConversationTasks: ActiveTask[] = [];\n public otherConversationTasks: ActiveTask[] = [];\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private activeTasksService: ActiveTasksService\n ) {}\n\n ngOnInit() {\n // AIEngineBase is deferred at startup; kick off the load early so the\n // template helpers (getAgentIconClass / getAgentLogoUrl) find populated\n // .Agents data when they're called from the template. Fire-and-forget —\n // the helpers fall back to defaults until it's loaded.\n AIEngineBase.Instance.EnsureLoaded();\n\n // Subscribe to ALL active tasks across ALL conversations\n this.activeTasksService.tasks$\n .pipe(takeUntil(this.destroy$))\n .subscribe(tasks => {\n this.allTasks = tasks;\n this.groupTasks();\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private groupTasks(): void {\n this.currentConversationTasks = this.allTasks.filter(\n task => task.conversationId === this.conversationId\n );\n\n this.otherConversationTasks = this.allTasks.filter(\n task => task.conversationId && task.conversationId !== this.conversationId\n );\n }\n\n toggleDropdown(): void {\n this.isOpen = !this.isOpen;\n }\n\n closeDropdown(): void {\n this.isOpen = false;\n }\n\n onTaskClick(task: ActiveTask): void {\n // If task is from another conversation, emit navigation event\n if (task.conversationId && task.conversationId !== this.conversationId) {\n this.navigateToConversation.emit({\n conversationId: task.conversationId,\n taskId: task.id\n });\n }\n\n this.taskClicked.emit(task);\n this.closeDropdown();\n }\n\n getElapsedTime(task: ActiveTask): string {\n const elapsed = Date.now() - task.startTime;\n const seconds = Math.floor(elapsed / 1000);\n\n if (seconds < 60) {\n return `${seconds}s`;\n }\n\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;\n }\n\n getTrimmedStatus(status: string): string {\n const maxLength = 50;\n if (status.length <= maxLength) {\n return status;\n }\n return status.substring(0, maxLength) + '...';\n }\n\n /**\n * Get agent icon class by looking up agent in AIEngineBase cache\n * Similar to message-item component's aiAgentInfo getter\n */\n getAgentIconClass(agentName: string): string {\n // Look up agent from AIEngineBase cache by name\n if (AIEngineBase.Instance?.Agents) {\n const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);\n if (agent?.IconClass) {\n return agent.IconClass;\n }\n }\n\n // Default fallback icon\n return 'fas fa-robot';\n }\n\n /**\n * Get agent logo URL by looking up agent in AIEngineBase cache\n * Returns null if no logo URL is available\n */\n getAgentLogoUrl(agentName: string): string | null {\n // Look up agent from AIEngineBase cache by name\n if (AIEngineBase.Instance?.Agents) {\n const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);\n if (agent?.LogoURL) {\n return agent.LogoURL;\n }\n }\n\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tasks-dropdown.component.js","sourceRoot":"","sources":["../../../../src/lib/components/tasks/tasks-dropdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';\nimport { UserInfo } from '@memberjunction/core';\nimport { ActiveTasksService, ActiveTask } from '../../services/active-tasks.service';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n/**\n * Enhanced tasks dropdown component for chat header.\n * Shows ALL active tasks across ALL conversations, grouped by current vs other\n */\n@Component({\n standalone: false,\n selector: 'mj-tasks-dropdown',\n template: `\n <div class=\"tasks-dropdown-container\">\n <button\n class=\"active-tasks-btn\"\n (click)=\"toggleDropdown()\"\n [class.active]=\"isOpen\"\n [class.has-tasks]=\"allTasks.length > 0\"\n [title]=\"allTasks.length > 0 ? allTasks.length + ' active task' + (allTasks.length > 1 ? 's' : '') : 'View tasks'\">\n <i class=\"fas fa-bolt\"></i>\n @if (allTasks.length > 0) {\n <span class=\"task-count-badge\">{{ allTasks.length }}</span>\n }\n </button>\n \n @if (isOpen) {\n <div class=\"active-tasks-dropdown\">\n <div class=\"dropdown-header\">\n <div class=\"header-left\">\n @if (allTasks.length > 0) {\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n }\n @if (allTasks.length === 0) {\n <i class=\"fas fa-tasks\"></i>\n }\n <span>Active Tasks ({{ allTasks.length }})</span>\n </div>\n <button class=\"close-btn\" (click)=\"closeDropdown()\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"dropdown-content\">\n <!-- Current Conversation Tasks -->\n @if (currentConversationTasks.length > 0) {\n <div class=\"section\">\n <div class=\"section-header\">\n <i class=\"fas fa-comment\"></i>\n <span>Current Conversation ({{ currentConversationTasks.length }})</span>\n </div>\n @for (task of currentConversationTasks; track task) {\n <div class=\"active-task-item\"\n (click)=\"onTaskClick(task)\">\n <div class=\"task-status-indicator active\"></div>\n <div class=\"task-content\">\n <div class=\"task-title\">\n @if (getAgentLogoUrl(task.agentName)) {\n <img\n [src]=\"getAgentLogoUrl(task.agentName)\"\n class=\"agent-logo\"\n [alt]=\"task.agentName\" />\n }\n @if (!getAgentLogoUrl(task.agentName)) {\n <i\n [class]=\"getAgentIconClass(task.agentName)\"></i>\n }\n {{ task.agentName }}\n </div>\n <div class=\"task-status-text\">{{ getTrimmedStatus(task.status) }}</div>\n <div class=\"task-elapsed\">{{ getElapsedTime(task) }}</div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Other Conversations Tasks -->\n @if (otherConversationTasks.length > 0) {\n <div class=\"section\">\n <div class=\"section-header\">\n <i class=\"fas fa-comments\"></i>\n <span>Other Conversations ({{ otherConversationTasks.length }})</span>\n </div>\n @for (task of otherConversationTasks; track task) {\n <div class=\"active-task-item clickable\"\n (click)=\"onTaskClick(task)\">\n <div class=\"task-status-indicator active\"></div>\n <div class=\"task-content\">\n <div class=\"task-title\">\n @if (getAgentLogoUrl(task.agentName)) {\n <img\n [src]=\"getAgentLogoUrl(task.agentName)\"\n class=\"agent-logo\"\n [alt]=\"task.agentName\" />\n }\n @if (!getAgentLogoUrl(task.agentName)) {\n <i\n [class]=\"getAgentIconClass(task.agentName)\"></i>\n }\n {{ task.agentName }}\n <span class=\"go-btn\">\n <i class=\"fas fa-arrow-right\"></i>\n </span>\n </div>\n @if (task.conversationName) {\n <div class=\"task-conversation\">\n <i class=\"fas fa-message\"></i>\n {{ task.conversationName }}\n </div>\n }\n <div class=\"task-status-text\">{{ getTrimmedStatus(task.status) }}</div>\n <div class=\"task-elapsed\">{{ getElapsedTime(task) }}</div>\n </div>\n </div>\n }\n </div>\n }\n <!-- No Tasks State -->\n @if (allTasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-check-circle\"></i>\n <p>No active tasks</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n `,\n styles: [`\n .tasks-dropdown-container {\n position: relative;\n }\n\n .active-tasks-btn {\n background: transparent;\n padding: 8px 12px;\n border-radius: 6px;\n border: none;\n color: rgba(255,255,255,0.7);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: all 0.2s;\n }\n\n .active-tasks-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .active-tasks-btn.active {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .task-count-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 5px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n min-width: 18px;\n text-align: center;\n line-height: 1;\n box-shadow: var(--mj-shadow-sm);\n }\n\n .active-tasks-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n min-width: 420px;\n max-width: 500px;\n }\n\n .dropdown-header {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .header-left i {\n color: var(--mj-brand-primary);\n }\n\n .close-btn {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 18px;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n }\n\n .close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .dropdown-content {\n max-height: 500px;\n overflow-y: auto;\n }\n\n .section {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .section:last-child {\n border-bottom: none;\n }\n\n .section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n padding: 0 4px;\n }\n\n .section-header i {\n font-size: 11px;\n }\n\n .active-task-item {\n display: flex;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n margin-bottom: 8px;\n transition: all 0.2s ease;\n }\n\n .active-task-item.clickable {\n cursor: pointer;\n }\n\n .active-task-item.clickable:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n transform: translateX(2px);\n }\n\n .active-task-item:last-child {\n margin-bottom: 0;\n }\n\n .task-status-indicator {\n width: 4px;\n border-radius: 2px;\n flex-shrink: 0;\n }\n\n .task-status-indicator.active {\n background: var(--mj-brand-primary);\n animation: pulse 2s ease-in-out infinite;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .task-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n }\n\n .task-title .agent-logo {\n width: 14px;\n height: 14px;\n object-fit: contain;\n flex-shrink: 0;\n }\n\n .go-btn {\n margin-left: auto;\n color: var(--mj-brand-primary);\n font-size: 10px;\n opacity: 0.7;\n }\n\n .active-task-item.clickable:hover .go-btn {\n opacity: 1;\n }\n\n .task-conversation {\n font-size: 11px;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .task-conversation i {\n font-size: 10px;\n }\n\n .task-status-text {\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .task-elapsed {\n font-size: 11px;\n color: var(--mj-brand-primary);\n font-weight: 600;\n }\n\n .no-tasks {\n padding: 40px 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 32px;\n margin-bottom: 8px;\n opacity: 0.5;\n color: var(--mj-status-success);\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n\n mj-task-widget {\n display: block;\n margin-bottom: 8px;\n }\n\n mj-task-widget:last-child {\n margin-bottom: 0;\n }\n\n /* Mobile adjustments: 481px - 768px */\n @media (max-width: 768px) {\n .active-tasks-btn {\n padding: 6px 10px;\n font-size: 12px;\n }\n\n .active-tasks-dropdown {\n position: fixed;\n top: auto;\n right: 8px;\n left: 8px;\n bottom: 8px;\n min-width: unset;\n max-width: unset;\n max-height: 60vh;\n }\n\n .dropdown-header {\n padding: 10px 12px;\n }\n\n .dropdown-content {\n max-height: calc(60vh - 48px);\n }\n\n .section {\n padding: 10px;\n }\n\n .section-header {\n font-size: 11px;\n margin-bottom: 10px;\n }\n\n .active-task-item {\n padding: 8px 10px;\n }\n\n .task-title {\n font-size: 13px;\n }\n\n .task-status-text {\n font-size: 11px;\n }\n\n .task-elapsed {\n font-size: 10px;\n }\n }\n\n /* Small Phone adjustments: <= 480px */\n @media (max-width: 480px) {\n .active-tasks-btn {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .active-tasks-dropdown {\n right: 4px;\n left: 4px;\n bottom: 4px;\n max-height: 70vh;\n }\n\n .dropdown-header {\n padding: 8px 10px;\n }\n\n .header-left {\n font-size: 13px;\n }\n\n .dropdown-content {\n max-height: calc(70vh - 44px);\n }\n\n .section {\n padding: 8px;\n }\n\n .section-header {\n font-size: 10px;\n margin-bottom: 8px;\n }\n\n .active-task-item {\n padding: 6px 8px;\n gap: 8px;\n }\n\n .task-title {\n font-size: 12px;\n }\n\n .task-status-text {\n font-size: 10px;\n }\n\n .task-elapsed {\n font-size: 9px;\n }\n\n .no-tasks {\n padding: 30px 12px;\n }\n\n .no-tasks i {\n font-size: 28px;\n }\n\n .no-tasks p {\n font-size: 13px;\n }\n }\n `]\n})\nexport class TasksDropdownComponent implements OnInit, OnDestroy {\n @Input() currentUser!: UserInfo;\n @Input() conversationId: string | null = null;\n @Output() taskClicked = new EventEmitter<ActiveTask>();\n @Output() navigateToConversation = new EventEmitter<{conversationId: string; taskId: string}>();\n\n public isOpen: boolean = false;\n public allTasks: ActiveTask[] = [];\n public currentConversationTasks: ActiveTask[] = [];\n public otherConversationTasks: ActiveTask[] = [];\n\n private destroy$ = new Subject<void>();\n\n /**\n * Wall-clock snapshot the elapsed-time template bindings read from. The template\n * must NOT call Date.now() (directly or via getElapsedTime) — a change-detection\n * pass that straddles a second boundary would then see two different values for\n * the same binding and throw NG0100 in dev mode. Instead this snapshot is stable\n * within a CD pass and advances via a 1s interval that runs only while the\n * dropdown is open (the only time elapsed text is rendered).\n */\n private _now = Date.now();\n private elapsedTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(\n private activeTasksService: ActiveTasksService\n ) {}\n\n ngOnInit() {\n // AIEngineBase is deferred at startup; kick off the load early so the\n // template helpers (getAgentIconClass / getAgentLogoUrl) find populated\n // .Agents data when they're called from the template. Fire-and-forget —\n // the helpers fall back to defaults until it's loaded.\n AIEngineBase.Instance.EnsureLoaded();\n\n // Subscribe to ALL active tasks across ALL conversations\n this.activeTasksService.tasks$\n .pipe(takeUntil(this.destroy$))\n .subscribe(tasks => {\n this.allTasks = tasks;\n this.groupTasks();\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n this.stopElapsedTimer();\n }\n\n private groupTasks(): void {\n this.currentConversationTasks = this.allTasks.filter(\n task => task.conversationId === this.conversationId\n );\n\n this.otherConversationTasks = this.allTasks.filter(\n task => task.conversationId && task.conversationId !== this.conversationId\n );\n }\n\n toggleDropdown(): void {\n this.isOpen = !this.isOpen;\n if (this.isOpen) {\n this.startElapsedTimer();\n } else {\n this.stopElapsedTimer();\n }\n }\n\n closeDropdown(): void {\n this.isOpen = false;\n this.stopElapsedTimer();\n }\n\n private startElapsedTimer(): void {\n this._now = Date.now(); // fresh snapshot for the first render\n if (this.elapsedTimer) {\n return;\n }\n // Zone-patched interval: each tick triggers CD, so the elapsed text advances\n // once per second while the dropdown is open. Stopped on close/destroy.\n this.elapsedTimer = setInterval(() => {\n this._now = Date.now();\n }, 1000);\n }\n\n private stopElapsedTimer(): void {\n if (this.elapsedTimer) {\n clearInterval(this.elapsedTimer);\n this.elapsedTimer = null;\n }\n }\n\n onTaskClick(task: ActiveTask): void {\n // If task is from another conversation, emit navigation event\n if (task.conversationId && task.conversationId !== this.conversationId) {\n this.navigateToConversation.emit({\n conversationId: task.conversationId,\n taskId: task.id\n });\n }\n\n this.taskClicked.emit(task);\n this.closeDropdown();\n }\n\n getElapsedTime(task: ActiveTask): string {\n // Reads the CD-stable snapshot, never Date.now() — see _now for why (NG0100).\n const elapsed = Math.max(0, this._now - task.startTime);\n const seconds = Math.floor(elapsed / 1000);\n\n if (seconds < 60) {\n return `${seconds}s`;\n }\n\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;\n }\n\n getTrimmedStatus(status: string): string {\n const maxLength = 50;\n if (status.length <= maxLength) {\n return status;\n }\n return status.substring(0, maxLength) + '...';\n }\n\n /**\n * Get agent icon class by looking up agent in AIEngineBase cache\n * Similar to message-item component's aiAgentInfo getter\n */\n getAgentIconClass(agentName: string): string {\n // Look up agent from AIEngineBase cache by name\n if (AIEngineBase.Instance?.Agents) {\n const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);\n if (agent?.IconClass) {\n return agent.IconClass;\n }\n }\n\n // Default fallback icon\n return 'fas fa-robot';\n }\n\n /**\n * Get agent logo URL by looking up agent in AIEngineBase cache\n * Returns null if no logo URL is available\n */\n getAgentLogoUrl(agentName: string): string | null {\n // Look up agent from AIEngineBase cache by name\n if (AIEngineBase.Instance?.Agents) {\n const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);\n if (agent?.LogoURL) {\n return agent.LogoURL;\n }\n }\n\n return null;\n }\n}\n"]}
|
|
@@ -25,7 +25,7 @@ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
|
25
25
|
import { ArtifactStateService } from '../../services/artifact-state.service';
|
|
26
26
|
import { CollectionStateService } from '../../services/collection-state.service';
|
|
27
27
|
import { ArtifactPermissionService } from '../../services/artifact-permission.service';
|
|
28
|
-
import {
|
|
28
|
+
import { PendingAttachment } from '@memberjunction/ng-composer';
|
|
29
29
|
import { ConversationStreamingService } from '../../services/conversation-streaming.service';
|
|
30
30
|
import { UICommandHandlerService } from '../../services/ui-command-handler.service';
|
|
31
31
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
@@ -33,7 +33,6 @@ import { NavigationTab, WorkspaceLayout } from '../../models/conversation-state.
|
|
|
33
33
|
import { SearchResult } from '../../services/search.service';
|
|
34
34
|
import { ActionableCommand, AutomaticCommand } from '@memberjunction/ai-core-plus';
|
|
35
35
|
import { NavigationRequest } from '@memberjunction/ng-artifacts';
|
|
36
|
-
import { PendingAttachment } from '../mention/mention-editor.component';
|
|
37
36
|
import * as i0 from "@angular/core";
|
|
38
37
|
/**
|
|
39
38
|
* Top-level workspace component for conversations
|
|
@@ -48,7 +47,6 @@ export declare class ConversationWorkspaceComponent extends BaseAngularComponent
|
|
|
48
47
|
artifactState: ArtifactStateService;
|
|
49
48
|
collectionState: CollectionStateService;
|
|
50
49
|
private artifactPermissionService;
|
|
51
|
-
private mentionAutocompleteService;
|
|
52
50
|
private notificationService;
|
|
53
51
|
private streamingService;
|
|
54
52
|
private uiCommandHandler;
|
|
@@ -59,6 +57,13 @@ export declare class ConversationWorkspaceComponent extends BaseAngularComponent
|
|
|
59
57
|
currentUser: UserInfo;
|
|
60
58
|
activeContext?: 'library' | 'task';
|
|
61
59
|
contextItemId?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Show the Routines section at the very bottom of the left sidebar. Default true;
|
|
62
|
+
* hosts that don't want routines (or embed a reduced chat surface) set false.
|
|
63
|
+
* The section additionally hides itself when the current user lacks Read
|
|
64
|
+
* permission on 'MJ: User Routines'.
|
|
65
|
+
*/
|
|
66
|
+
ShowRoutines: boolean;
|
|
62
67
|
set activeTabInput(value: 'conversations' | 'collections' | 'tasks' | undefined);
|
|
63
68
|
set activeConversationInput(value: string | undefined);
|
|
64
69
|
set activeCollectionInput(value: string | undefined);
|
|
@@ -134,7 +139,8 @@ export declare class ConversationWorkspaceComponent extends BaseAngularComponent
|
|
|
134
139
|
pendingArtifactConversationId: string | null;
|
|
135
140
|
pendingArtifactVersionNumber: number | null;
|
|
136
141
|
private engine;
|
|
137
|
-
|
|
142
|
+
private mentionAutocompleteService;
|
|
143
|
+
constructor(artifactState: ArtifactStateService, collectionState: CollectionStateService, artifactPermissionService: ArtifactPermissionService, notificationService: MJNotificationService, streamingService: ConversationStreamingService, uiCommandHandler: UICommandHandlerService, cdr: ChangeDetectorRef);
|
|
138
144
|
/**
|
|
139
145
|
* Sets the active conversation for this workspace instance
|
|
140
146
|
* @param id The conversation ID to activate (or null to clear)
|
|
@@ -343,6 +349,6 @@ export declare class ConversationWorkspaceComponent extends BaseAngularComponent
|
|
|
343
349
|
*/
|
|
344
350
|
onAutomaticCommand(command: AutomaticCommand): void;
|
|
345
351
|
static ɵfac: i0.ɵɵFactoryDeclaration<ConversationWorkspaceComponent, never>;
|
|
346
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ConversationWorkspaceComponent, "mj-conversation-workspace", never, { "environmentId": { "alias": "environmentId"; "required": false; }; "initialConversationId": { "alias": "initialConversationId"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "activeContext": { "alias": "activeContext"; "required": false; }; "contextItemId": { "alias": "contextItemId"; "required": false; }; "activeTabInput": { "alias": "activeTabInput"; "required": false; }; "activeConversationInput": { "alias": "activeConversationInput"; "required": false; }; "activeCollectionInput": { "alias": "activeCollectionInput"; "required": false; }; "activeVersionIdInput": { "alias": "activeVersionIdInput"; "required": false; }; "activeTaskInput": { "alias": "activeTaskInput"; "required": false; }; }, { "conversationChanged": "conversationChanged"; "artifactOpened": "artifactOpened"; "navigationChanged": "navigationChanged"; "newConversationStarted": "newConversationStarted"; "actionableCommandExecuted": "actionableCommandExecuted"; "automaticCommandExecuted": "automaticCommandExecuted"; "navigationRequested": "navigationRequested"; }, never, never, false, never>;
|
|
352
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ConversationWorkspaceComponent, "mj-conversation-workspace", never, { "environmentId": { "alias": "environmentId"; "required": false; }; "initialConversationId": { "alias": "initialConversationId"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "activeContext": { "alias": "activeContext"; "required": false; }; "contextItemId": { "alias": "contextItemId"; "required": false; }; "ShowRoutines": { "alias": "ShowRoutines"; "required": false; }; "activeTabInput": { "alias": "activeTabInput"; "required": false; }; "activeConversationInput": { "alias": "activeConversationInput"; "required": false; }; "activeCollectionInput": { "alias": "activeCollectionInput"; "required": false; }; "activeVersionIdInput": { "alias": "activeVersionIdInput"; "required": false; }; "activeTaskInput": { "alias": "activeTaskInput"; "required": false; }; }, { "conversationChanged": "conversationChanged"; "artifactOpened": "artifactOpened"; "navigationChanged": "navigationChanged"; "newConversationStarted": "newConversationStarted"; "actionableCommandExecuted": "actionableCommandExecuted"; "automaticCommandExecuted": "automaticCommandExecuted"; "navigationRequested": "navigationRequested"; }, never, never, false, never>;
|
|
347
353
|
}
|
|
348
354
|
//# sourceMappingURL=conversation-workspace.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-workspace.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/workspace/conversation-workspace.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAIL,YAAY,EACZ,MAAM,EACN,SAAS,EACT,OAAO,EACP,iBAAiB,EAElB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAmF,MAAM,+BAA+B,CAAC;AACtL,OAAO,EAAE,QAAQ,EAAE,YAAY,EAA0B,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"conversation-workspace.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/workspace/conversation-workspace.component.ts"],"names":[],"mappings":"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"}
|