@memberjunction/ng-tasks 2.105.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 (46) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +233 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/lib/components/gantt-task-viewer.component.d.ts +44 -0
  9. package/dist/lib/components/gantt-task-viewer.component.d.ts.map +1 -0
  10. package/dist/lib/components/gantt-task-viewer.component.js +461 -0
  11. package/dist/lib/components/gantt-task-viewer.component.js.map +1 -0
  12. package/dist/lib/components/simple-task-viewer.component.d.ts +36 -0
  13. package/dist/lib/components/simple-task-viewer.component.d.ts.map +1 -0
  14. package/dist/lib/components/simple-task-viewer.component.js +275 -0
  15. package/dist/lib/components/simple-task-viewer.component.js.map +1 -0
  16. package/dist/lib/components/task-detail-panel.component.d.ts +26 -0
  17. package/dist/lib/components/task-detail-panel.component.d.ts.map +1 -0
  18. package/dist/lib/components/task-detail-panel.component.js +294 -0
  19. package/dist/lib/components/task-detail-panel.component.js.map +1 -0
  20. package/dist/lib/components/task.component.d.ts +34 -0
  21. package/dist/lib/components/task.component.d.ts.map +1 -0
  22. package/dist/lib/components/task.component.js +201 -0
  23. package/dist/lib/components/task.component.js.map +1 -0
  24. package/dist/lib/models/task-view.models.d.ts +17 -0
  25. package/dist/lib/models/task-view.models.d.ts.map +1 -0
  26. package/dist/lib/models/task-view.models.js +2 -0
  27. package/dist/lib/models/task-view.models.js.map +1 -0
  28. package/dist/lib/ng-tasks.module.d.ts +14 -0
  29. package/dist/lib/ng-tasks.module.d.ts.map +1 -0
  30. package/dist/lib/ng-tasks.module.js +37 -0
  31. package/dist/lib/ng-tasks.module.js.map +1 -0
  32. package/dist/public-api.d.ts +9 -0
  33. package/dist/public-api.d.ts.map +1 -0
  34. package/dist/public-api.js +12 -0
  35. package/dist/public-api.js.map +1 -0
  36. package/package.json +31 -0
  37. package/src/index.ts +1 -0
  38. package/src/lib/components/gantt-task-viewer.component.ts +524 -0
  39. package/src/lib/components/simple-task-viewer.component.ts +356 -0
  40. package/src/lib/components/task-detail-panel.component.ts +304 -0
  41. package/src/lib/components/task.component.ts +175 -0
  42. package/src/lib/models/task-view.models.ts +19 -0
  43. package/src/lib/ng-tasks.module.ts +22 -0
  44. package/src/lib/types/frappe-gantt.d.ts +32 -0
  45. package/src/public-api.ts +14 -0
  46. package/tsconfig.json +24 -0
@@ -0,0 +1,275 @@
1
+ import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { TaskDetailPanelComponent } from './task-detail-panel.component';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ function SimpleTaskViewerComponent_div_3_i_8_Template(rf, ctx) { if (rf & 1) {
7
+ i0.ɵɵelement(0, "i", 19);
8
+ } }
9
+ function SimpleTaskViewerComponent_div_3_div_9_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵelementStart(0, "div", 20)(1, "div", 21);
11
+ i0.ɵɵelement(2, "div", 22);
12
+ i0.ɵɵelementEnd();
13
+ i0.ɵɵelementStart(3, "span", 23);
14
+ i0.ɵɵtext(4);
15
+ i0.ɵɵelementEnd()();
16
+ } if (rf & 2) {
17
+ const task_r2 = i0.ɵɵnextContext().$implicit;
18
+ i0.ɵɵadvance(2);
19
+ i0.ɵɵstyleProp("width", task_r2.PercentComplete, "%");
20
+ i0.ɵɵclassProp("complete", task_r2.Status === "Complete");
21
+ i0.ɵɵadvance(2);
22
+ i0.ɵɵtextInterpolate1("", task_r2.PercentComplete, "%");
23
+ } }
24
+ function SimpleTaskViewerComponent_div_3_span_11_Template(rf, ctx) { if (rf & 1) {
25
+ i0.ɵɵelementStart(0, "span", 24);
26
+ i0.ɵɵelement(1, "i", 25);
27
+ i0.ɵɵtext(2);
28
+ i0.ɵɵelementEnd();
29
+ } if (rf & 2) {
30
+ const task_r2 = i0.ɵɵnextContext().$implicit;
31
+ const ctx_r2 = i0.ɵɵnextContext();
32
+ i0.ɵɵadvance(2);
33
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.formatDate(task_r2.DueAt), " ");
34
+ } }
35
+ function SimpleTaskViewerComponent_div_3_span_12_Template(rf, ctx) { if (rf & 1) {
36
+ i0.ɵɵelementStart(0, "span", 26);
37
+ i0.ɵɵelement(1, "i", 27);
38
+ i0.ɵɵtext(2);
39
+ i0.ɵɵelementEnd();
40
+ } if (rf & 2) {
41
+ const task_r2 = i0.ɵɵnextContext().$implicit;
42
+ i0.ɵɵadvance(2);
43
+ i0.ɵɵtextInterpolate1(" ", task_r2.User, " ");
44
+ } }
45
+ function SimpleTaskViewerComponent_div_3_Template(rf, ctx) { if (rf & 1) {
46
+ const _r1 = i0.ɵɵgetCurrentView();
47
+ i0.ɵɵelementStart(0, "div", 7);
48
+ i0.ɵɵlistener("click", function SimpleTaskViewerComponent_div_3_Template_div_click_0_listener() { const task_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTaskClick(task_r2)); });
49
+ i0.ɵɵelementStart(1, "div", 8);
50
+ i0.ɵɵelement(2, "i", 9);
51
+ i0.ɵɵelementEnd();
52
+ i0.ɵɵelementStart(3, "div", 10)(4, "div", 11)(5, "div", 12)(6, "span", 13);
53
+ i0.ɵɵtext(7);
54
+ i0.ɵɵtemplate(8, SimpleTaskViewerComponent_div_3_i_8_Template, 1, 0, "i", 14);
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵtemplate(9, SimpleTaskViewerComponent_div_3_div_9_Template, 5, 5, "div", 15);
57
+ i0.ɵɵelementEnd();
58
+ i0.ɵɵelementStart(10, "span", 16);
59
+ i0.ɵɵtemplate(11, SimpleTaskViewerComponent_div_3_span_11_Template, 3, 1, "span", 17)(12, SimpleTaskViewerComponent_div_3_span_12_Template, 3, 1, "span", 18);
60
+ i0.ɵɵelementEnd()()()();
61
+ } if (rf & 2) {
62
+ const task_r2 = ctx.$implicit;
63
+ const ctx_r2 = i0.ɵɵnextContext();
64
+ i0.ɵɵclassProp("completed", task_r2.Status === "Complete")("selected", (ctx_r2.selectedTask == null ? null : ctx_r2.selectedTask.ID) === task_r2.ID);
65
+ i0.ɵɵadvance();
66
+ i0.ɵɵclassProp("complete", task_r2.Status === "Complete");
67
+ i0.ɵɵadvance();
68
+ i0.ɵɵproperty("ngClass", ctx_r2.getStatusIcon(task_r2.Status));
69
+ i0.ɵɵadvance(4);
70
+ i0.ɵɵclassProp("completed-text", task_r2.Status === "Complete");
71
+ i0.ɵɵadvance();
72
+ i0.ɵɵtextInterpolate1(" ", task_r2.Name, " ");
73
+ i0.ɵɵadvance();
74
+ i0.ɵɵproperty("ngIf", task_r2.Status === "Complete");
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵproperty("ngIf", task_r2.PercentComplete != null);
77
+ i0.ɵɵadvance(2);
78
+ i0.ɵɵproperty("ngIf", task_r2.DueAt);
79
+ i0.ɵɵadvance();
80
+ i0.ɵɵproperty("ngIf", task_r2.User);
81
+ } }
82
+ function SimpleTaskViewerComponent_div_4_Template(rf, ctx) { if (rf & 1) {
83
+ i0.ɵɵelementStart(0, "div", 28);
84
+ i0.ɵɵelement(1, "i", 29);
85
+ i0.ɵɵelementStart(2, "p");
86
+ i0.ɵɵtext(3, "No tasks to display");
87
+ i0.ɵɵelementEnd()();
88
+ } }
89
+ function SimpleTaskViewerComponent_div_5_Template(rf, ctx) { if (rf & 1) {
90
+ const _r4 = i0.ɵɵgetCurrentView();
91
+ i0.ɵɵelementStart(0, "div", 30);
92
+ i0.ɵɵlistener("mousedown", function SimpleTaskViewerComponent_div_5_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.startResize($event)); });
93
+ i0.ɵɵelementEnd();
94
+ } }
95
+ function SimpleTaskViewerComponent_div_6_Template(rf, ctx) { if (rf & 1) {
96
+ const _r5 = i0.ɵɵgetCurrentView();
97
+ i0.ɵɵelementStart(0, "div", 31)(1, "mj-task-detail-panel", 32);
98
+ i0.ɵɵlistener("closePanel", function SimpleTaskViewerComponent_div_6_Template_mj_task_detail_panel_closePanel_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDetailPanel()); })("openEntityRecord", function SimpleTaskViewerComponent_div_6_Template_mj_task_detail_panel_openEntityRecord_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
99
+ i0.ɵɵelementEnd()();
100
+ } if (rf & 2) {
101
+ const ctx_r2 = i0.ɵɵnextContext();
102
+ i0.ɵɵstyleProp("width", ctx_r2.detailPanelWidth, "px");
103
+ i0.ɵɵadvance();
104
+ i0.ɵɵproperty("task", ctx_r2.selectedTask)("agentRunId", ctx_r2.getAgentRunId(ctx_r2.selectedTask));
105
+ } }
106
+ /**
107
+ * Simple list view for tasks
108
+ */
109
+ export class SimpleTaskViewerComponent {
110
+ tasks = [];
111
+ agentRunMap; // Maps TaskID -> AgentRunID
112
+ taskClicked = new EventEmitter();
113
+ openEntityRecord = new EventEmitter();
114
+ selectedTask = null;
115
+ detailPanelWidth = 400;
116
+ isResizing = false;
117
+ resizeStartX = 0;
118
+ resizeStartWidth = 0;
119
+ ngOnChanges() {
120
+ // Tasks are already loaded
121
+ }
122
+ onTaskClick(task) {
123
+ this.selectedTask = task;
124
+ this.taskClicked.emit(task);
125
+ }
126
+ getAgentRunId(task) {
127
+ return this.agentRunMap?.get(task.ID) || null;
128
+ }
129
+ closeDetailPanel() {
130
+ this.selectedTask = null;
131
+ }
132
+ onOpenEntityRecord(event) {
133
+ this.openEntityRecord.emit(event);
134
+ }
135
+ startResize(event) {
136
+ this.isResizing = true;
137
+ this.resizeStartX = event.clientX;
138
+ this.resizeStartWidth = this.detailPanelWidth;
139
+ event.preventDefault();
140
+ }
141
+ handleResize(event) {
142
+ if (!this.isResizing)
143
+ return;
144
+ const delta = this.resizeStartX - event.clientX;
145
+ const newWidth = this.resizeStartWidth + delta;
146
+ // Constrain width between min and max
147
+ this.detailPanelWidth = Math.max(300, Math.min(600, newWidth));
148
+ }
149
+ stopResize() {
150
+ this.isResizing = false;
151
+ }
152
+ getStatusIcon(status) {
153
+ switch (status) {
154
+ case 'Complete': return 'fa-check-circle';
155
+ case 'In Progress': return 'fa-spinner';
156
+ case 'Pending': return 'fa-clock';
157
+ case 'Blocked': return 'fa-ban';
158
+ case 'Failed': return 'fa-times-circle';
159
+ default: return 'fa-circle';
160
+ }
161
+ }
162
+ formatDate(date) {
163
+ if (!date)
164
+ return '';
165
+ const d = new Date(date);
166
+ return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
167
+ }
168
+ static ɵfac = function SimpleTaskViewerComponent_Factory(t) { return new (t || SimpleTaskViewerComponent)(); };
169
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SimpleTaskViewerComponent, selectors: [["mj-simple-task-viewer"]], hostBindings: function SimpleTaskViewerComponent_HostBindings(rf, ctx) { if (rf & 1) {
170
+ i0.ɵɵlistener("mousemove", function SimpleTaskViewerComponent_mousemove_HostBindingHandler($event) { return ctx.handleResize($event); }, false, i0.ɵɵresolveDocument)("mouseup", function SimpleTaskViewerComponent_mouseup_HostBindingHandler() { return ctx.stopResize(); }, false, i0.ɵɵresolveDocument);
171
+ } }, inputs: { tasks: "tasks", agentRunMap: "agentRunMap" }, outputs: { taskClicked: "taskClicked", openEntityRecord: "openEntityRecord" }, standalone: true, features: [i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature], decls: 7, vars: 6, consts: [[1, "simple-task-viewer"], [1, "list-layout"], [1, "task-list"], ["class", "task-item", 3, "completed", "selected", "click", 4, "ngFor", "ngForOf"], ["class", "no-tasks", 4, "ngIf"], ["class", "list-resizer", 3, "mousedown", 4, "ngIf"], ["class", "task-detail-panel", 3, "width", 4, "ngIf"], [1, "task-item", 3, "click"], [1, "status-icon"], [1, "fas", 3, "ngClass"], [1, "task-content"], [1, "task-header"], [1, "task-title-row"], [1, "task-title"], ["class", "fas fa-check completed-check", 4, "ngIf"], ["class", "task-progress-compact", 4, "ngIf"], [1, "task-meta"], ["class", "due-date", 4, "ngIf"], ["class", "assigned-to", 4, "ngIf"], [1, "fas", "fa-check", "completed-check"], [1, "task-progress-compact"], [1, "progress-bar-compact"], [1, "progress-fill-compact"], [1, "progress-text-compact"], [1, "due-date"], [1, "far", "fa-calendar"], [1, "assigned-to"], [1, "far", "fa-user"], [1, "no-tasks"], [1, "fas", "fa-tasks"], [1, "list-resizer", 3, "mousedown"], [1, "task-detail-panel"], [3, "closePanel", "openEntityRecord", "task", "agentRunId"]], template: function SimpleTaskViewerComponent_Template(rf, ctx) { if (rf & 1) {
172
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
173
+ i0.ɵɵtemplate(3, SimpleTaskViewerComponent_div_3_Template, 13, 14, "div", 3)(4, SimpleTaskViewerComponent_div_4_Template, 4, 0, "div", 4);
174
+ i0.ɵɵelementEnd();
175
+ i0.ɵɵtemplate(5, SimpleTaskViewerComponent_div_5_Template, 1, 0, "div", 5)(6, SimpleTaskViewerComponent_div_6_Template, 2, 4, "div", 6);
176
+ i0.ɵɵelementEnd()();
177
+ } if (rf & 2) {
178
+ i0.ɵɵadvance(2);
179
+ i0.ɵɵclassProp("with-detail", ctx.selectedTask);
180
+ i0.ɵɵadvance();
181
+ i0.ɵɵproperty("ngForOf", ctx.tasks);
182
+ i0.ɵɵadvance();
183
+ i0.ɵɵproperty("ngIf", !ctx.tasks || ctx.tasks.length === 0);
184
+ i0.ɵɵadvance();
185
+ i0.ɵɵproperty("ngIf", ctx.selectedTask);
186
+ i0.ɵɵadvance();
187
+ i0.ɵɵproperty("ngIf", ctx.selectedTask);
188
+ } }, dependencies: [CommonModule, i1.NgClass, i1.NgForOf, i1.NgIf, TaskDetailPanelComponent], styles: [".simple-task-viewer[_ngcontent-%COMP%] {\n height: 100%;\n background: #FAFAFA;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .list-layout[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n position: relative;\n }\n\n .task-list[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 400px;\n padding: 16px;\n overflow-y: auto;\n }\n\n .task-list.with-detail[_ngcontent-%COMP%] {\n border-right: 1px solid #E5E7EB;\n }\n\n .list-resizer[_ngcontent-%COMP%] {\n width: 4px;\n background: #E5E7EB;\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .list-resizer[_ngcontent-%COMP%]:hover {\n background: #3B82F6;\n }\n\n .task-detail-panel[_ngcontent-%COMP%] {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n flex-shrink: 0;\n }\n\n .task-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n margin-bottom: 8px;\n transition: all 0.2s;\n cursor: pointer;\n }\n\n .task-item[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);\n transform: translateY(-1px);\n }\n\n .task-item.selected[_ngcontent-%COMP%] {\n border-color: #3B82F6;\n background: #EFF6FF;\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);\n }\n\n .task-item.completed[_ngcontent-%COMP%] {\n background: #F9FAFB;\n border-color: #D1D5DB;\n }\n\n .status-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #FEF3C7;\n color: #F59E0B;\n flex-shrink: 0;\n }\n\n .status-icon.complete[_ngcontent-%COMP%] {\n background: #D1FAE5;\n color: #10B981;\n }\n\n .task-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .task-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n .task-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .task-title[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #111827;\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title.completed-text[_ngcontent-%COMP%] {\n color: #6B7280;\n text-decoration: line-through;\n text-decoration-thickness: 1.5px;\n }\n\n .completed-check[_ngcontent-%COMP%] {\n color: #10B981;\n font-size: 12px;\n }\n\n .task-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #6B7280;\n white-space: nowrap;\n }\n\n .task-meta[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n }\n\n .task-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6B7280;\n margin-bottom: 8px;\n line-height: 1.5;\n }\n\n .task-progress-compact[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .progress-bar-compact[_ngcontent-%COMP%] {\n width: 80px;\n height: 4px;\n background: #E5E7EB;\n border-radius: 2px;\n overflow: hidden;\n }\n\n .progress-fill-compact[_ngcontent-%COMP%] {\n height: 100%;\n background: #3B82F6;\n transition: width 0.3s ease;\n }\n\n .progress-fill-compact.complete[_ngcontent-%COMP%] {\n background: #10B981;\n }\n\n .progress-text-compact[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 600;\n color: #6B7280;\n min-width: 30px;\n text-align: right;\n }\n\n .no-tasks[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 20px;\n color: #9CA3AF;\n }\n\n .no-tasks[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n opacity: 0.3;\n margin-bottom: 12px;\n }\n\n .no-tasks[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n }"] });
189
+ }
190
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SimpleTaskViewerComponent, [{
191
+ type: Component,
192
+ args: [{ selector: 'mj-simple-task-viewer', standalone: true, imports: [CommonModule, TaskDetailPanelComponent], template: `
193
+ <div class="simple-task-viewer">
194
+ <div class="list-layout">
195
+ <div class="task-list" [class.with-detail]="selectedTask">
196
+ <div *ngFor="let task of tasks"
197
+ class="task-item"
198
+ [class.completed]="task.Status === 'Complete'"
199
+ [class.selected]="selectedTask?.ID === task.ID"
200
+ (click)="onTaskClick(task)">
201
+
202
+ <!-- Status Icon -->
203
+ <div class="status-icon" [class.complete]="task.Status === 'Complete'">
204
+ <i class="fas" [ngClass]="getStatusIcon(task.Status)"></i>
205
+ </div>
206
+
207
+ <!-- Task Content -->
208
+ <div class="task-content">
209
+ <div class="task-header">
210
+ <div class="task-title-row">
211
+ <span class="task-title" [class.completed-text]="task.Status === 'Complete'">
212
+ {{ task.Name }}
213
+ <i *ngIf="task.Status === 'Complete'" class="fas fa-check completed-check"></i>
214
+ </span>
215
+ <!-- Compact progress indicator for all tasks -->
216
+ <div *ngIf="task.PercentComplete != null" class="task-progress-compact">
217
+ <div class="progress-bar-compact">
218
+ <div class="progress-fill-compact"
219
+ [style.width.%]="task.PercentComplete"
220
+ [class.complete]="task.Status === 'Complete'"></div>
221
+ </div>
222
+ <span class="progress-text-compact">{{ task.PercentComplete }}%</span>
223
+ </div>
224
+ </div>
225
+ <span class="task-meta">
226
+ <span *ngIf="task.DueAt" class="due-date">
227
+ <i class="far fa-calendar"></i>
228
+ {{ formatDate(task.DueAt) }}
229
+ </span>
230
+ <span *ngIf="task.User" class="assigned-to">
231
+ <i class="far fa-user"></i>
232
+ {{ task.User }}
233
+ </span>
234
+ </span>
235
+ </div>
236
+ </div>
237
+ </div>
238
+
239
+ <div *ngIf="!tasks || tasks.length === 0" class="no-tasks">
240
+ <i class="fas fa-tasks"></i>
241
+ <p>No tasks to display</p>
242
+ </div>
243
+ </div>
244
+
245
+ <div *ngIf="selectedTask" class="list-resizer"
246
+ (mousedown)="startResize($event)"></div>
247
+
248
+ <div *ngIf="selectedTask" class="task-detail-panel" [style.width.px]="detailPanelWidth">
249
+ <mj-task-detail-panel
250
+ [task]="selectedTask"
251
+ [agentRunId]="getAgentRunId(selectedTask)"
252
+ (closePanel)="closeDetailPanel()"
253
+ (openEntityRecord)="onOpenEntityRecord($event)">
254
+ </mj-task-detail-panel>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ `, styles: ["\n .simple-task-viewer {\n height: 100%;\n background: #FAFAFA;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .list-layout {\n display: flex;\n height: 100%;\n position: relative;\n }\n\n .task-list {\n flex: 1;\n min-width: 400px;\n padding: 16px;\n overflow-y: auto;\n }\n\n .task-list.with-detail {\n border-right: 1px solid #E5E7EB;\n }\n\n .list-resizer {\n width: 4px;\n background: #E5E7EB;\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .list-resizer:hover {\n background: #3B82F6;\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n flex-shrink: 0;\n }\n\n .task-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n margin-bottom: 8px;\n transition: all 0.2s;\n cursor: pointer;\n }\n\n .task-item:hover {\n border-color: #3B82F6;\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);\n transform: translateY(-1px);\n }\n\n .task-item.selected {\n border-color: #3B82F6;\n background: #EFF6FF;\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);\n }\n\n .task-item.completed {\n background: #F9FAFB;\n border-color: #D1D5DB;\n }\n\n .status-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #FEF3C7;\n color: #F59E0B;\n flex-shrink: 0;\n }\n\n .status-icon.complete {\n background: #D1FAE5;\n color: #10B981;\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n .task-title-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n font-weight: 600;\n color: #111827;\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title.completed-text {\n color: #6B7280;\n text-decoration: line-through;\n text-decoration-thickness: 1.5px;\n }\n\n .completed-check {\n color: #10B981;\n font-size: 12px;\n }\n\n .task-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #6B7280;\n white-space: nowrap;\n }\n\n .task-meta i {\n margin-right: 4px;\n }\n\n .task-description {\n font-size: 13px;\n color: #6B7280;\n margin-bottom: 8px;\n line-height: 1.5;\n }\n\n .task-progress-compact {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .progress-bar-compact {\n width: 80px;\n height: 4px;\n background: #E5E7EB;\n border-radius: 2px;\n overflow: hidden;\n }\n\n .progress-fill-compact {\n height: 100%;\n background: #3B82F6;\n transition: width 0.3s ease;\n }\n\n .progress-fill-compact.complete {\n background: #10B981;\n }\n\n .progress-text-compact {\n font-size: 10px;\n font-weight: 600;\n color: #6B7280;\n min-width: 30px;\n text-align: right;\n }\n\n .no-tasks {\n text-align: center;\n padding: 60px 20px;\n color: #9CA3AF;\n }\n\n .no-tasks i {\n font-size: 48px;\n opacity: 0.3;\n margin-bottom: 12px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n "] }]
259
+ }], null, { tasks: [{
260
+ type: Input
261
+ }], agentRunMap: [{
262
+ type: Input
263
+ }], taskClicked: [{
264
+ type: Output
265
+ }], openEntityRecord: [{
266
+ type: Output
267
+ }], handleResize: [{
268
+ type: HostListener,
269
+ args: ['document:mousemove', ['$event']]
270
+ }], stopResize: [{
271
+ type: HostListener,
272
+ args: ['document:mouseup']
273
+ }] }); })();
274
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SimpleTaskViewerComponent, { className: "SimpleTaskViewerComponent", filePath: "src/lib/components/simple-task-viewer.component.ts", lineNumber: 283 }); })();
275
+ //# sourceMappingURL=simple-task-viewer.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-task-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/components/simple-task-viewer.component.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { EventEmitter, OnInit, OnChanges } from '@angular/core';
2
+ import { TaskEntity, AIAgentEntityExtended } from '@memberjunction/core-entities';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Task detail panel showing task information, agent details, and agent run
6
+ * Reusable across list and Gantt views
7
+ */
8
+ export declare class TaskDetailPanelComponent implements OnInit, OnChanges {
9
+ task: TaskEntity;
10
+ agentRunId: string | null;
11
+ closePanel: EventEmitter<void>;
12
+ openEntityRecord: EventEmitter<{
13
+ entityName: string;
14
+ recordId: string;
15
+ }>;
16
+ agent: AIAgentEntityExtended | null;
17
+ ngOnInit(): void;
18
+ ngOnChanges(): void;
19
+ private loadAgentInfo;
20
+ formatDateTime(date: Date | null): string;
21
+ openAgent(): void;
22
+ openAgentRun(): void;
23
+ static ɵfac: i0.ɵɵFactoryDeclaration<TaskDetailPanelComponent, never>;
24
+ static ɵcmp: i0.ɵɵComponentDeclaration<TaskDetailPanelComponent, "mj-task-detail-panel", never, { "task": { "alias": "task"; "required": false; }; "agentRunId": { "alias": "agentRunId"; "required": false; }; }, { "closePanel": "closePanel"; "openEntityRecord": "openEntityRecord"; }, never, never, true, never>;
25
+ }
26
+ //# sourceMappingURL=task-detail-panel.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-detail-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/task-detail-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1F,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;;AAGlF;;;GAGG;AACH,qBA8Oa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IACvD,IAAI,EAAG,UAAU,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,qBAA4B;IACtC,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAEnF,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAAQ;IAElD,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAInB,OAAO,CAAC,aAAa;IAWd,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;IAYzC,SAAS,IAAI,IAAI;IASjB,YAAY,IAAI,IAAI;yCAhDhB,wBAAwB;2CAAxB,wBAAwB;CAwDpC"}
@@ -0,0 +1,294 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ function TaskDetailPanelComponent_div_7_Template(rf, ctx) { if (rf & 1) {
7
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
8
+ i0.ɵɵtext(2, "Description");
9
+ i0.ɵɵelementEnd();
10
+ i0.ɵɵelementStart(3, "p");
11
+ i0.ɵɵtext(4);
12
+ i0.ɵɵelementEnd()();
13
+ } if (rf & 2) {
14
+ const ctx_r0 = i0.ɵɵnextContext();
15
+ i0.ɵɵadvance(4);
16
+ i0.ɵɵtextInterpolate(ctx_r0.task.Description);
17
+ } }
18
+ function TaskDetailPanelComponent_div_13_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
20
+ i0.ɵɵtext(2, "Progress");
21
+ i0.ɵɵelementEnd();
22
+ i0.ɵɵelementStart(3, "div", 7)(4, "div", 8);
23
+ i0.ɵɵelement(5, "div", 9);
24
+ i0.ɵɵelementEnd();
25
+ i0.ɵɵelementStart(6, "span");
26
+ i0.ɵɵtext(7);
27
+ i0.ɵɵelementEnd()()();
28
+ } if (rf & 2) {
29
+ const ctx_r0 = i0.ɵɵnextContext();
30
+ i0.ɵɵadvance(5);
31
+ i0.ɵɵstyleProp("width", ctx_r0.task.PercentComplete, "%");
32
+ i0.ɵɵadvance(2);
33
+ i0.ɵɵtextInterpolate1("", ctx_r0.task.PercentComplete, "%");
34
+ } }
35
+ function TaskDetailPanelComponent_div_14_Template(rf, ctx) { if (rf & 1) {
36
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
37
+ i0.ɵɵtext(2, "Started");
38
+ i0.ɵɵelementEnd();
39
+ i0.ɵɵelementStart(3, "p");
40
+ i0.ɵɵtext(4);
41
+ i0.ɵɵelementEnd()();
42
+ } if (rf & 2) {
43
+ const ctx_r0 = i0.ɵɵnextContext();
44
+ i0.ɵɵadvance(4);
45
+ i0.ɵɵtextInterpolate(ctx_r0.formatDateTime(ctx_r0.task.StartedAt));
46
+ } }
47
+ function TaskDetailPanelComponent_div_15_Template(rf, ctx) { if (rf & 1) {
48
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
49
+ i0.ɵɵtext(2, "Due");
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(3, "p");
52
+ i0.ɵɵtext(4);
53
+ i0.ɵɵelementEnd()();
54
+ } if (rf & 2) {
55
+ const ctx_r0 = i0.ɵɵnextContext();
56
+ i0.ɵɵadvance(4);
57
+ i0.ɵɵtextInterpolate(ctx_r0.formatDateTime(ctx_r0.task.DueAt));
58
+ } }
59
+ function TaskDetailPanelComponent_div_16_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
61
+ i0.ɵɵtext(2, "Completed");
62
+ i0.ɵɵelementEnd();
63
+ i0.ɵɵelementStart(3, "p");
64
+ i0.ɵɵtext(4);
65
+ i0.ɵɵelementEnd()();
66
+ } if (rf & 2) {
67
+ const ctx_r0 = i0.ɵɵnextContext();
68
+ i0.ɵɵadvance(4);
69
+ i0.ɵɵtextInterpolate(ctx_r0.formatDateTime(ctx_r0.task.CompletedAt));
70
+ } }
71
+ function TaskDetailPanelComponent_div_17_Template(rf, ctx) { if (rf & 1) {
72
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
73
+ i0.ɵɵtext(2, "Assigned User");
74
+ i0.ɵɵelementEnd();
75
+ i0.ɵɵelementStart(3, "p");
76
+ i0.ɵɵtext(4);
77
+ i0.ɵɵelementEnd()();
78
+ } if (rf & 2) {
79
+ const ctx_r0 = i0.ɵɵnextContext();
80
+ i0.ɵɵadvance(4);
81
+ i0.ɵɵtextInterpolate(ctx_r0.task.User);
82
+ } }
83
+ function TaskDetailPanelComponent_div_18_Template(rf, ctx) { if (rf & 1) {
84
+ const _r2 = i0.ɵɵgetCurrentView();
85
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
86
+ i0.ɵɵtext(2, "Agent");
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵelementStart(3, "div", 10);
89
+ i0.ɵɵlistener("click", function TaskDetailPanelComponent_div_18_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAgent()); });
90
+ i0.ɵɵelement(4, "i", 11);
91
+ i0.ɵɵelementStart(5, "span", 12);
92
+ i0.ɵɵtext(6);
93
+ i0.ɵɵelementEnd();
94
+ i0.ɵɵelement(7, "i", 13);
95
+ i0.ɵɵelementEnd()();
96
+ } if (rf & 2) {
97
+ const ctx_r0 = i0.ɵɵnextContext();
98
+ i0.ɵɵadvance(4);
99
+ i0.ɵɵclassMap("fas fa-" + "robot");
100
+ i0.ɵɵadvance(2);
101
+ i0.ɵɵtextInterpolate(ctx_r0.agent.Name);
102
+ } }
103
+ function TaskDetailPanelComponent_div_19_Template(rf, ctx) { if (rf & 1) {
104
+ const _r3 = i0.ɵɵgetCurrentView();
105
+ i0.ɵɵelementStart(0, "div", 6)(1, "label");
106
+ i0.ɵɵtext(2, "Agent Run");
107
+ i0.ɵɵelementEnd();
108
+ i0.ɵɵelementStart(3, "div", 14);
109
+ i0.ɵɵlistener("click", function TaskDetailPanelComponent_div_19_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAgentRun()); });
110
+ i0.ɵɵelementStart(4, "span");
111
+ i0.ɵɵtext(5, "View Run Details");
112
+ i0.ɵɵelementEnd();
113
+ i0.ɵɵelement(6, "i", 13);
114
+ i0.ɵɵelementEnd()();
115
+ } }
116
+ /**
117
+ * Task detail panel showing task information, agent details, and agent run
118
+ * Reusable across list and Gantt views
119
+ */
120
+ export class TaskDetailPanelComponent {
121
+ task;
122
+ agentRunId = null;
123
+ closePanel = new EventEmitter();
124
+ openEntityRecord = new EventEmitter();
125
+ agent = null;
126
+ ngOnInit() {
127
+ this.loadAgentInfo();
128
+ }
129
+ ngOnChanges() {
130
+ this.loadAgentInfo();
131
+ }
132
+ loadAgentInfo() {
133
+ if (!this.task?.AgentID) {
134
+ this.agent = null;
135
+ return;
136
+ }
137
+ // Get agent from AIEngineBase
138
+ const agents = AIEngineBase.Instance.Agents;
139
+ this.agent = agents.find((a) => a.ID === this.task.AgentID) || null;
140
+ }
141
+ formatDateTime(date) {
142
+ if (!date)
143
+ return '';
144
+ const d = new Date(date);
145
+ return d.toLocaleDateString('en-US', {
146
+ month: 'short',
147
+ day: 'numeric',
148
+ year: 'numeric',
149
+ hour: '2-digit',
150
+ minute: '2-digit'
151
+ });
152
+ }
153
+ openAgent() {
154
+ if (this.task.AgentID) {
155
+ this.openEntityRecord.emit({
156
+ entityName: 'AI Agents',
157
+ recordId: this.task.AgentID
158
+ });
159
+ }
160
+ }
161
+ openAgentRun() {
162
+ if (this.agentRunId) {
163
+ this.openEntityRecord.emit({
164
+ entityName: 'MJ: AI Agent Runs',
165
+ recordId: this.agentRunId
166
+ });
167
+ }
168
+ }
169
+ static ɵfac = function TaskDetailPanelComponent_Factory(t) { return new (t || TaskDetailPanelComponent)(); };
170
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TaskDetailPanelComponent, selectors: [["mj-task-detail-panel"]], inputs: { task: "task", agentRunId: "agentRunId" }, outputs: { closePanel: "closePanel", openEntityRecord: "openEntityRecord" }, standalone: true, features: [i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature], decls: 20, vars: 10, consts: [[1, "task-detail-panel"], [1, "detail-header"], [1, "close-detail-btn", 3, "click"], [1, "fas", "fa-times"], [1, "detail-content"], ["class", "detail-field", 4, "ngIf"], [1, "detail-field"], [1, "detail-progress"], [1, "progress-bar-detail"], [1, "progress-fill-detail"], [1, "agent-info", 3, "click"], [1, "agent-icon"], [1, "agent-name"], [1, "fas", "fa-external-link-alt", "link-icon"], [1, "agent-run-link", 3, "click"]], template: function TaskDetailPanelComponent_Template(rf, ctx) { if (rf & 1) {
171
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "h3");
172
+ i0.ɵɵtext(3);
173
+ i0.ɵɵelementEnd();
174
+ i0.ɵɵelementStart(4, "button", 2);
175
+ i0.ɵɵlistener("click", function TaskDetailPanelComponent_Template_button_click_4_listener() { return ctx.closePanel.emit(); });
176
+ i0.ɵɵelement(5, "i", 3);
177
+ i0.ɵɵelementEnd()();
178
+ i0.ɵɵelementStart(6, "div", 4);
179
+ i0.ɵɵtemplate(7, TaskDetailPanelComponent_div_7_Template, 5, 1, "div", 5);
180
+ i0.ɵɵelementStart(8, "div", 6)(9, "label");
181
+ i0.ɵɵtext(10, "Status");
182
+ i0.ɵɵelementEnd();
183
+ i0.ɵɵelementStart(11, "p");
184
+ i0.ɵɵtext(12);
185
+ i0.ɵɵelementEnd()();
186
+ i0.ɵɵtemplate(13, TaskDetailPanelComponent_div_13_Template, 8, 3, "div", 5)(14, TaskDetailPanelComponent_div_14_Template, 5, 1, "div", 5)(15, TaskDetailPanelComponent_div_15_Template, 5, 1, "div", 5)(16, TaskDetailPanelComponent_div_16_Template, 5, 1, "div", 5)(17, TaskDetailPanelComponent_div_17_Template, 5, 1, "div", 5)(18, TaskDetailPanelComponent_div_18_Template, 8, 3, "div", 5)(19, TaskDetailPanelComponent_div_19_Template, 7, 0, "div", 5);
187
+ i0.ɵɵelementEnd()();
188
+ } if (rf & 2) {
189
+ i0.ɵɵadvance(3);
190
+ i0.ɵɵtextInterpolate(ctx.task.Name);
191
+ i0.ɵɵadvance(4);
192
+ i0.ɵɵproperty("ngIf", ctx.task.Description);
193
+ i0.ɵɵadvance(5);
194
+ i0.ɵɵtextInterpolate(ctx.task.Status);
195
+ i0.ɵɵadvance();
196
+ i0.ɵɵproperty("ngIf", ctx.task.PercentComplete != null);
197
+ i0.ɵɵadvance();
198
+ i0.ɵɵproperty("ngIf", ctx.task.StartedAt);
199
+ i0.ɵɵadvance();
200
+ i0.ɵɵproperty("ngIf", ctx.task.DueAt);
201
+ i0.ɵɵadvance();
202
+ i0.ɵɵproperty("ngIf", ctx.task.CompletedAt);
203
+ i0.ɵɵadvance();
204
+ i0.ɵɵproperty("ngIf", ctx.task.User);
205
+ i0.ɵɵadvance();
206
+ i0.ɵɵproperty("ngIf", ctx.agent);
207
+ i0.ɵɵadvance();
208
+ i0.ɵɵproperty("ngIf", ctx.agentRunId);
209
+ } }, dependencies: [CommonModule, i1.NgIf], styles: [".task-detail-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: calc(100% - 45px);\n background: white;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .detail-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid #E5E7EB;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n background: #F9FAFB;\n flex-shrink: 0;\n }\n\n .detail-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #111827;\n flex: 1;\n padding-right: 12px;\n }\n\n .close-detail-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: #6B7280;\n cursor: pointer;\n padding: 4px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .close-detail-btn[_ngcontent-%COMP%]:hover {\n background: #E5E7EB;\n color: #111827;\n }\n\n .detail-content[_ngcontent-%COMP%] {\n padding: 20px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n }\n\n .detail-field[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n }\n\n .detail-field[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n }\n\n .detail-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n }\n\n .detail-field[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: #111827;\n line-height: 1.5;\n }\n\n .detail-progress[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .progress-bar-detail[_ngcontent-%COMP%] {\n flex: 1;\n height: 8px;\n background: #E5E7EB;\n border-radius: 4px;\n overflow: hidden;\n }\n\n .progress-fill-detail[_ngcontent-%COMP%] {\n height: calc(100% - 69px);\n background: #3B82F6;\n transition: width 0.3s ease;\n }\n\n .detail-progress[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #6B7280;\n min-width: 40px;\n }\n\n .agent-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: #F3F4F6;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .agent-info[_ngcontent-%COMP%]:hover {\n background: #E5E7EB;\n }\n\n .agent-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #3B82F6;\n }\n\n .agent-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n }\n\n .link-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n }\n\n .agent-run-link[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n background: #F3F4F6;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .agent-run-link[_ngcontent-%COMP%]:hover {\n background: #E5E7EB;\n }\n\n .agent-run-link[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n }"] });
210
+ }
211
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TaskDetailPanelComponent, [{
212
+ type: Component,
213
+ args: [{ selector: 'mj-task-detail-panel', standalone: true, imports: [CommonModule], template: `
214
+ <div class="task-detail-panel">
215
+ <div class="detail-header">
216
+ <h3>{{ task.Name }}</h3>
217
+ <button class="close-detail-btn" (click)="closePanel.emit()">
218
+ <i class="fas fa-times"></i>
219
+ </button>
220
+ </div>
221
+
222
+ <div class="detail-content">
223
+ <div class="detail-field" *ngIf="task.Description">
224
+ <label>Description</label>
225
+ <p>{{ task.Description }}</p>
226
+ </div>
227
+
228
+ <div class="detail-field">
229
+ <label>Status</label>
230
+ <p>{{ task.Status }}</p>
231
+ </div>
232
+
233
+ <div class="detail-field" *ngIf="task.PercentComplete != null">
234
+ <label>Progress</label>
235
+ <div class="detail-progress">
236
+ <div class="progress-bar-detail">
237
+ <div class="progress-fill-detail" [style.width.%]="task.PercentComplete"></div>
238
+ </div>
239
+ <span>{{ task.PercentComplete }}%</span>
240
+ </div>
241
+ </div>
242
+
243
+ <div class="detail-field" *ngIf="task.StartedAt">
244
+ <label>Started</label>
245
+ <p>{{ formatDateTime(task.StartedAt) }}</p>
246
+ </div>
247
+
248
+ <div class="detail-field" *ngIf="task.DueAt">
249
+ <label>Due</label>
250
+ <p>{{ formatDateTime(task.DueAt) }}</p>
251
+ </div>
252
+
253
+ <div class="detail-field" *ngIf="task.CompletedAt">
254
+ <label>Completed</label>
255
+ <p>{{ formatDateTime(task.CompletedAt) }}</p>
256
+ </div>
257
+
258
+ <div class="detail-field" *ngIf="task.User">
259
+ <label>Assigned User</label>
260
+ <p>{{ task.User }}</p>
261
+ </div>
262
+
263
+ <!-- Agent Information -->
264
+ <div class="detail-field" *ngIf="agent">
265
+ <label>Agent</label>
266
+ <div class="agent-info" (click)="openAgent()">
267
+ <i [class]="'fas fa-' + ('robot')" class="agent-icon"></i>
268
+ <span class="agent-name">{{ agent.Name }}</span>
269
+ <i class="fas fa-external-link-alt link-icon"></i>
270
+ </div>
271
+ </div>
272
+
273
+ <!-- Agent Run Information -->
274
+ <div class="detail-field" *ngIf="agentRunId">
275
+ <label>Agent Run</label>
276
+ <div class="agent-run-link" (click)="openAgentRun()">
277
+ <span>View Run Details</span>
278
+ <i class="fas fa-external-link-alt link-icon"></i>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ `, styles: ["\n .task-detail-panel {\n width: 100%;\n height: calc(100% - 45px);\n background: white;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .detail-header {\n padding: 20px;\n border-bottom: 1px solid #E5E7EB;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n background: #F9FAFB;\n flex-shrink: 0;\n }\n\n .detail-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #111827;\n flex: 1;\n padding-right: 12px;\n }\n\n .close-detail-btn {\n background: none;\n border: none;\n color: #6B7280;\n cursor: pointer;\n padding: 4px;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .close-detail-btn:hover {\n background: #E5E7EB;\n color: #111827;\n }\n\n .detail-content {\n padding: 20px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n }\n\n .detail-field {\n margin-bottom: 20px;\n }\n\n .detail-field:last-child {\n margin-bottom: 0;\n }\n\n .detail-field label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #6B7280;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n }\n\n .detail-field p {\n margin: 0;\n font-size: 14px;\n color: #111827;\n line-height: 1.5;\n }\n\n .detail-progress {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .progress-bar-detail {\n flex: 1;\n height: 8px;\n background: #E5E7EB;\n border-radius: 4px;\n overflow: hidden;\n }\n\n .progress-fill-detail {\n height: calc(100% - 69px);\n background: #3B82F6;\n transition: width 0.3s ease;\n }\n\n .detail-progress span {\n font-size: 13px;\n font-weight: 600;\n color: #6B7280;\n min-width: 40px;\n }\n\n .agent-info {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: #F3F4F6;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .agent-info:hover {\n background: #E5E7EB;\n }\n\n .agent-icon {\n font-size: 18px;\n color: #3B82F6;\n }\n\n .agent-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n }\n\n .link-icon {\n font-size: 12px;\n color: #6B7280;\n }\n\n .agent-run-link {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n background: #F3F4F6;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .agent-run-link:hover {\n background: #E5E7EB;\n }\n\n .agent-run-link span {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n }\n "] }]
284
+ }], null, { task: [{
285
+ type: Input
286
+ }], agentRunId: [{
287
+ type: Input
288
+ }], closePanel: [{
289
+ type: Output
290
+ }], openEntityRecord: [{
291
+ type: Output
292
+ }] }); })();
293
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TaskDetailPanelComponent, { className: "TaskDetailPanelComponent", filePath: "src/lib/components/task-detail-panel.component.ts", lineNumber: 248 }); })();
294
+ //# sourceMappingURL=task-detail-panel.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-detail-panel.component.js","sourceRoot":"","sources":["../../../src/lib/components/task-detail-panel.component.ts"],"names":[],"mappings":"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"}