@memberjunction/ng-tasks 3.4.0 → 4.0.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.
@@ -1,12 +1,10 @@
1
1
  import { Component, Input, Output, EventEmitter } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
2
  import { SimpleTaskViewerComponent } from './simple-task-viewer.component';
4
3
  import { GanttTaskViewerComponent } from './gantt-task-viewer.component';
5
4
  import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/common";
7
5
  const _c0 = () => [];
8
- function TaskComponent_div_1_h2_2_Template(rf, ctx) { if (rf & 1) {
9
- i0.ɵɵelementStart(0, "h2", 10);
6
+ function TaskComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
7
+ i0.ɵɵelementStart(0, "h2", 6);
10
8
  i0.ɵɵtext(1);
11
9
  i0.ɵɵelementEnd();
12
10
  } if (rf & 2) {
@@ -14,8 +12,8 @@ function TaskComponent_div_1_h2_2_Template(rf, ctx) { if (rf & 1) {
14
12
  i0.ɵɵadvance();
15
13
  i0.ɵɵtextInterpolate(ctx_r0.title);
16
14
  } }
17
- function TaskComponent_div_1_p_3_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "p", 11);
15
+ function TaskComponent_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
16
+ i0.ɵɵelementStart(0, "p", 7);
19
17
  i0.ɵɵtext(1);
20
18
  i0.ɵɵelementEnd();
21
19
  } if (rf & 2) {
@@ -23,17 +21,17 @@ function TaskComponent_div_1_p_3_Template(rf, ctx) { if (rf & 1) {
23
21
  i0.ɵɵadvance();
24
22
  i0.ɵɵtextInterpolate(ctx_r0.description);
25
23
  } }
26
- function TaskComponent_div_1_div_4_Template(rf, ctx) { if (rf & 1) {
24
+ function TaskComponent_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
27
25
  const _r2 = i0.ɵɵgetCurrentView();
28
- i0.ɵɵelementStart(0, "div", 12)(1, "button", 13);
29
- i0.ɵɵlistener("click", function TaskComponent_div_1_div_4_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setViewMode("gantt")); });
30
- i0.ɵɵelement(2, "i", 14);
26
+ i0.ɵɵelementStart(0, "div", 8)(1, "button", 9);
27
+ i0.ɵɵlistener("click", function TaskComponent_Conditional_1_Conditional_4_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setViewMode("gantt")); });
28
+ i0.ɵɵelement(2, "i", 10);
31
29
  i0.ɵɵelementStart(3, "span");
32
30
  i0.ɵɵtext(4, "Gantt");
33
31
  i0.ɵɵelementEnd()();
34
- i0.ɵɵelementStart(5, "button", 15);
35
- i0.ɵɵlistener("click", function TaskComponent_div_1_div_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setViewMode("simple")); });
36
- i0.ɵɵelement(6, "i", 16);
32
+ i0.ɵɵelementStart(5, "button", 11);
33
+ i0.ɵɵlistener("click", function TaskComponent_Conditional_1_Conditional_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setViewMode("simple")); });
34
+ i0.ɵɵelement(6, "i", 12);
37
35
  i0.ɵɵelementStart(7, "span");
38
36
  i0.ɵɵtext(8, "List");
39
37
  i0.ɵɵelementEnd()()();
@@ -44,34 +42,35 @@ function TaskComponent_div_1_div_4_Template(rf, ctx) { if (rf & 1) {
44
42
  i0.ɵɵadvance(4);
45
43
  i0.ɵɵclassProp("active", ctx_r0.viewMode === "simple");
46
44
  } }
47
- function TaskComponent_div_1_Template(rf, ctx) { if (rf & 1) {
48
- i0.ɵɵelementStart(0, "div", 5)(1, "div", 6);
49
- i0.ɵɵtemplate(2, TaskComponent_div_1_h2_2_Template, 2, 1, "h2", 7)(3, TaskComponent_div_1_p_3_Template, 2, 1, "p", 8);
45
+ function TaskComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
46
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 5);
47
+ i0.ɵɵconditionalCreate(2, TaskComponent_Conditional_1_Conditional_2_Template, 2, 1, "h2", 6);
48
+ i0.ɵɵconditionalCreate(3, TaskComponent_Conditional_1_Conditional_3_Template, 2, 1, "p", 7);
50
49
  i0.ɵɵelementEnd();
51
- i0.ɵɵtemplate(4, TaskComponent_div_1_div_4_Template, 9, 4, "div", 9);
50
+ i0.ɵɵconditionalCreate(4, TaskComponent_Conditional_1_Conditional_4_Template, 9, 4, "div", 8);
52
51
  i0.ɵɵelementEnd();
53
52
  } if (rf & 2) {
54
53
  const ctx_r0 = i0.ɵɵnextContext();
55
54
  i0.ɵɵadvance(2);
56
- i0.ɵɵproperty("ngIf", ctx_r0.title);
55
+ i0.ɵɵconditional(ctx_r0.title ? 2 : -1);
57
56
  i0.ɵɵadvance();
58
- i0.ɵɵproperty("ngIf", ctx_r0.description);
57
+ i0.ɵɵconditional(ctx_r0.description ? 3 : -1);
59
58
  i0.ɵɵadvance();
60
- i0.ɵɵproperty("ngIf", ctx_r0.showViewToggle);
59
+ i0.ɵɵconditional(ctx_r0.showViewToggle ? 4 : -1);
61
60
  } }
62
- function TaskComponent_mj_simple_task_viewer_3_Template(rf, ctx) { if (rf & 1) {
61
+ function TaskComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
63
62
  const _r3 = i0.ɵɵgetCurrentView();
64
- i0.ɵɵelementStart(0, "mj-simple-task-viewer", 17);
65
- i0.ɵɵlistener("taskClicked", function TaskComponent_mj_simple_task_viewer_3_Template_mj_simple_task_viewer_taskClicked_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTaskClicked($event)); })("openEntityRecord", function TaskComponent_mj_simple_task_viewer_3_Template_mj_simple_task_viewer_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); });
63
+ i0.ɵɵelementStart(0, "mj-simple-task-viewer", 13);
64
+ i0.ɵɵlistener("taskClicked", function TaskComponent_Conditional_3_Template_mj_simple_task_viewer_taskClicked_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTaskClicked($event)); })("openEntityRecord", function TaskComponent_Conditional_3_Template_mj_simple_task_viewer_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); });
66
65
  i0.ɵɵelementEnd();
67
66
  } if (rf & 2) {
68
67
  const ctx_r0 = i0.ɵɵnextContext();
69
68
  i0.ɵɵproperty("tasks", ctx_r0.tasks)("agentRunMap", ctx_r0.agentRunMap);
70
69
  } }
71
- function TaskComponent_mj_gantt_task_viewer_4_Template(rf, ctx) { if (rf & 1) {
70
+ function TaskComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
72
71
  const _r4 = i0.ɵɵgetCurrentView();
73
- i0.ɵɵelementStart(0, "mj-gantt-task-viewer", 18);
74
- i0.ɵɵlistener("taskClicked", function TaskComponent_mj_gantt_task_viewer_4_Template_mj_gantt_task_viewer_taskClicked_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTaskClicked($event)); })("openEntityRecord", function TaskComponent_mj_gantt_task_viewer_4_Template_mj_gantt_task_viewer_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); });
72
+ i0.ɵɵelementStart(0, "mj-gantt-task-viewer", 14);
73
+ i0.ɵɵlistener("taskClicked", function TaskComponent_Conditional_4_Template_mj_gantt_task_viewer_taskClicked_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTaskClicked($event)); })("openEntityRecord", function TaskComponent_Conditional_4_Template_mj_gantt_task_viewer_openEntityRecord_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); });
75
74
  i0.ɵɵelementEnd();
76
75
  } if (rf & 2) {
77
76
  const ctx_r0 = i0.ɵɵnextContext();
@@ -105,73 +104,83 @@ export class TaskComponent {
105
104
  this.openEntityRecord.emit(event);
106
105
  }
107
106
  static ɵfac = function TaskComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TaskComponent)(); };
108
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TaskComponent, selectors: [["mj-task"]], inputs: { tasks: "tasks", ganttTasks: "ganttTasks", taskDependencies: "taskDependencies", agentRunMap: "agentRunMap", title: "title", description: "description", showHeader: "showHeader", showViewToggle: "showViewToggle", viewMode: "viewMode" }, outputs: { viewModeChanged: "viewModeChanged", taskClicked: "taskClicked", openEntityRecord: "openEntityRecord" }, standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 5, vars: 3, consts: [[1, "task-component"], ["class", "task-header", 4, "ngIf"], [1, "task-viewer"], [3, "tasks", "agentRunMap", "taskClicked", "openEntityRecord", 4, "ngIf"], [3, "tasks", "taskDependencies", "agentRunMap", "taskClicked", "openEntityRecord", 4, "ngIf"], [1, "task-header"], [1, "header-left"], ["class", "task-title", 4, "ngIf"], ["class", "task-description", 4, "ngIf"], ["class", "view-toggle", 4, "ngIf"], [1, "task-title"], [1, "task-description"], [1, "view-toggle"], ["title", "Gantt Chart", 1, "toggle-btn", 3, "click"], [1, "fas", "fa-chart-gantt"], ["title", "List View", 1, "toggle-btn", 3, "click"], [1, "fas", "fa-list"], [3, "taskClicked", "openEntityRecord", "tasks", "agentRunMap"], [3, "taskClicked", "openEntityRecord", "tasks", "taskDependencies", "agentRunMap"]], template: function TaskComponent_Template(rf, ctx) { if (rf & 1) {
107
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TaskComponent, selectors: [["mj-task"]], inputs: { tasks: "tasks", ganttTasks: "ganttTasks", taskDependencies: "taskDependencies", agentRunMap: "agentRunMap", title: "title", description: "description", showHeader: "showHeader", showViewToggle: "showViewToggle", viewMode: "viewMode" }, outputs: { viewModeChanged: "viewModeChanged", taskClicked: "taskClicked", openEntityRecord: "openEntityRecord" }, decls: 5, vars: 3, consts: [[1, "task-component"], [1, "task-header"], [1, "task-viewer"], [3, "tasks", "agentRunMap"], [3, "tasks", "taskDependencies", "agentRunMap"], [1, "header-left"], [1, "task-title"], [1, "task-description"], [1, "view-toggle"], ["title", "Gantt Chart", 1, "toggle-btn", 3, "click"], [1, "fas", "fa-chart-gantt"], ["title", "List View", 1, "toggle-btn", 3, "click"], [1, "fas", "fa-list"], [3, "taskClicked", "openEntityRecord", "tasks", "agentRunMap"], [3, "taskClicked", "openEntityRecord", "tasks", "taskDependencies", "agentRunMap"]], template: function TaskComponent_Template(rf, ctx) { if (rf & 1) {
109
108
  i0.ɵɵelementStart(0, "div", 0);
110
- i0.ɵɵtemplate(1, TaskComponent_div_1_Template, 5, 3, "div", 1);
109
+ i0.ɵɵconditionalCreate(1, TaskComponent_Conditional_1_Template, 5, 3, "div", 1);
111
110
  i0.ɵɵelementStart(2, "div", 2);
112
- i0.ɵɵtemplate(3, TaskComponent_mj_simple_task_viewer_3_Template, 1, 2, "mj-simple-task-viewer", 3)(4, TaskComponent_mj_gantt_task_viewer_4_Template, 1, 4, "mj-gantt-task-viewer", 4);
111
+ i0.ɵɵconditionalCreate(3, TaskComponent_Conditional_3_Template, 1, 2, "mj-simple-task-viewer", 3);
112
+ i0.ɵɵconditionalCreate(4, TaskComponent_Conditional_4_Template, 1, 4, "mj-gantt-task-viewer", 4);
113
113
  i0.ɵɵelementEnd()();
114
114
  } if (rf & 2) {
115
115
  i0.ɵɵadvance();
116
- i0.ɵɵproperty("ngIf", ctx.showHeader);
116
+ i0.ɵɵconditional(ctx.showHeader ? 1 : -1);
117
117
  i0.ɵɵadvance(2);
118
- i0.ɵɵproperty("ngIf", ctx.viewMode === "simple");
118
+ i0.ɵɵconditional(ctx.viewMode === "simple" ? 3 : -1);
119
119
  i0.ɵɵadvance();
120
- i0.ɵɵproperty("ngIf", ctx.viewMode === "gantt");
121
- } }, dependencies: [CommonModule, i1.NgIf, SimpleTaskViewerComponent, GanttTaskViewerComponent], styles: [".task-component[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #FAFAFA;\n }\n\n .task-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n padding: 20px 24px;\n background: white;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .task-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n }\n\n .task-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: #6B7280;\n line-height: 1.5;\n }\n\n .view-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n background: #F3F4F6;\n padding: 4px;\n border-radius: 8px;\n }\n\n .toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: #6B7280;\n font-size: 13px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .toggle-btn[_ngcontent-%COMP%]:hover {\n color: #111827;\n background: rgba(255, 255, 255, 0.5);\n }\n\n .toggle-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #3B82F6;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n .toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .task-viewer[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }"] });
120
+ i0.ɵɵconditional(ctx.viewMode === "gantt" ? 4 : -1);
121
+ } }, dependencies: [SimpleTaskViewerComponent, GanttTaskViewerComponent], styles: [".task-component[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #FAFAFA;\n }\n\n .task-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n padding: 20px 24px;\n background: white;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .task-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n }\n\n .task-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: #6B7280;\n line-height: 1.5;\n }\n\n .view-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n background: #F3F4F6;\n padding: 4px;\n border-radius: 8px;\n }\n\n .toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: #6B7280;\n font-size: 13px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .toggle-btn[_ngcontent-%COMP%]:hover {\n color: #111827;\n background: rgba(255, 255, 255, 0.5);\n }\n\n .toggle-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #3B82F6;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n .toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .task-viewer[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }"] });
122
122
  }
123
123
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TaskComponent, [{
124
124
  type: Component,
125
- args: [{ selector: 'mj-task', standalone: true, imports: [CommonModule, SimpleTaskViewerComponent, GanttTaskViewerComponent], template: `
125
+ args: [{ selector: 'mj-task', standalone: true, imports: [SimpleTaskViewerComponent, GanttTaskViewerComponent], template: `
126
126
  <div class="task-component">
127
127
  <!-- Header with View Toggle -->
128
- <div class="task-header" *ngIf="showHeader">
129
- <div class="header-left">
130
- <h2 class="task-title" *ngIf="title">{{ title }}</h2>
131
- <p class="task-description" *ngIf="description">{{ description }}</p>
128
+ @if (showHeader) {
129
+ <div class="task-header">
130
+ <div class="header-left">
131
+ @if (title) {
132
+ <h2 class="task-title">{{ title }}</h2>
133
+ }
134
+ @if (description) {
135
+ <p class="task-description">{{ description }}</p>
136
+ }
137
+ </div>
138
+ @if (showViewToggle) {
139
+ <div class="view-toggle">
140
+ <button
141
+ class="toggle-btn"
142
+ [class.active]="viewMode === 'gantt'"
143
+ (click)="setViewMode('gantt')"
144
+ title="Gantt Chart">
145
+ <i class="fas fa-chart-gantt"></i>
146
+ <span>Gantt</span>
147
+ </button>
148
+ <button
149
+ class="toggle-btn"
150
+ [class.active]="viewMode === 'simple'"
151
+ (click)="setViewMode('simple')"
152
+ title="List View">
153
+ <i class="fas fa-list"></i>
154
+ <span>List</span>
155
+ </button>
156
+ </div>
157
+ }
132
158
  </div>
133
-
134
- <div class="view-toggle" *ngIf="showViewToggle">
135
- <button
136
- class="toggle-btn"
137
- [class.active]="viewMode === 'gantt'"
138
- (click)="setViewMode('gantt')"
139
- title="Gantt Chart">
140
- <i class="fas fa-chart-gantt"></i>
141
- <span>Gantt</span>
142
- </button>
143
- <button
144
- class="toggle-btn"
145
- [class.active]="viewMode === 'simple'"
146
- (click)="setViewMode('simple')"
147
- title="List View">
148
- <i class="fas fa-list"></i>
149
- <span>List</span>
150
- </button>
151
- </div>
152
- </div>
153
-
159
+ }
160
+
154
161
  <!-- Task Viewer (Simple or Gantt) -->
155
162
  <div class="task-viewer">
156
- <mj-simple-task-viewer
157
- *ngIf="viewMode === 'simple'"
158
- [tasks]="tasks"
159
- [agentRunMap]="agentRunMap"
160
- (taskClicked)="onTaskClicked($event)"
161
- (openEntityRecord)="onOpenEntityRecord($event)">
162
- </mj-simple-task-viewer>
163
-
164
- <mj-gantt-task-viewer
165
- *ngIf="viewMode === 'gantt'"
166
- [tasks]="ganttTasks || tasks"
167
- [taskDependencies]="taskDependencies || []"
168
- [agentRunMap]="agentRunMap"
169
- (taskClicked)="onTaskClicked($event)"
170
- (openEntityRecord)="onOpenEntityRecord($event)">
171
- </mj-gantt-task-viewer>
163
+ @if (viewMode === 'simple') {
164
+ <mj-simple-task-viewer
165
+ [tasks]="tasks"
166
+ [agentRunMap]="agentRunMap"
167
+ (taskClicked)="onTaskClicked($event)"
168
+ (openEntityRecord)="onOpenEntityRecord($event)">
169
+ </mj-simple-task-viewer>
170
+ }
171
+
172
+ @if (viewMode === 'gantt') {
173
+ <mj-gantt-task-viewer
174
+ [tasks]="ganttTasks || tasks"
175
+ [taskDependencies]="taskDependencies || []"
176
+ [agentRunMap]="agentRunMap"
177
+ (taskClicked)="onTaskClicked($event)"
178
+ (openEntityRecord)="onOpenEntityRecord($event)">
179
+ </mj-gantt-task-viewer>
180
+ }
172
181
  </div>
173
182
  </div>
174
- `, styles: ["\n .task-component {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #FAFAFA;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n padding: 20px 24px;\n background: white;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .header-left {\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n }\n\n .task-description {\n margin: 0;\n font-size: 14px;\n color: #6B7280;\n line-height: 1.5;\n }\n\n .view-toggle {\n display: flex;\n gap: 8px;\n background: #F3F4F6;\n padding: 4px;\n border-radius: 8px;\n }\n\n .toggle-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: #6B7280;\n font-size: 13px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .toggle-btn:hover {\n color: #111827;\n background: rgba(255, 255, 255, 0.5);\n }\n\n .toggle-btn.active {\n background: white;\n color: #3B82F6;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n .toggle-btn i {\n font-size: 14px;\n }\n\n .task-viewer {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n "] }]
183
+ `, styles: ["\n .task-component {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #FAFAFA;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 20px;\n padding: 20px 24px;\n background: white;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .header-left {\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 700;\n color: #111827;\n }\n\n .task-description {\n margin: 0;\n font-size: 14px;\n color: #6B7280;\n line-height: 1.5;\n }\n\n .view-toggle {\n display: flex;\n gap: 8px;\n background: #F3F4F6;\n padding: 4px;\n border-radius: 8px;\n }\n\n .toggle-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: #6B7280;\n font-size: 13px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .toggle-btn:hover {\n color: #111827;\n background: rgba(255, 255, 255, 0.5);\n }\n\n .toggle-btn.active {\n background: white;\n color: #3B82F6;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n .toggle-btn i {\n font-size: 14px;\n }\n\n .task-viewer {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n "] }]
175
184
  }], null, { tasks: [{
176
185
  type: Input
177
186
  }], ganttTasks: [{
@@ -197,5 +206,5 @@ export class TaskComponent {
197
206
  }], openEntityRecord: [{
198
207
  type: Output
199
208
  }] }); })();
200
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TaskComponent, { className: "TaskComponent", filePath: "src/lib/components/task.component.ts", lineNumber: 148 }); })();
209
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TaskComponent, { className: "TaskComponent", filePath: "src/lib/components/task.component.ts", lineNumber: 157 }); })();
201
210
  //# sourceMappingURL=task.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.component.js","sourceRoot":"","sources":["../../../src/lib/components/task.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task.component.js","sourceRoot":"","sources":["../../../src/lib/components/task.component.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,7 @@ export class NgTasksModule {
11
11
  static ɵfac = function NgTasksModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || NgTasksModule)(); };
12
12
  static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: NgTasksModule });
13
13
  static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [TaskComponent,
14
- SimpleTaskViewerComponent,
15
- GanttTaskViewerComponent] });
14
+ SimpleTaskViewerComponent] });
16
15
  }
17
16
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgTasksModule, [{
18
17
  type: NgModule,
@@ -1 +1 @@
1
- {"version":3,"file":"ng-tasks.module.js","sourceRoot":"","sources":["../../src/lib/ng-tasks.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;;AAEpF;;;GAGG;AAaH,MAAM,OAAO,aAAa;uGAAb,aAAa;4DAAb,aAAa;gEAVtB,aAAa;YACb,yBAAyB;YACzB,wBAAwB;;iFAQf,aAAa;cAZzB,QAAQ;eAAC;gBACR,OAAO,EAAE;oBACP,aAAa;oBACb,yBAAyB;oBACzB,wBAAwB;iBACzB;gBACD,OAAO,EAAE;oBACP,aAAa;oBACb,yBAAyB;oBACzB,wBAAwB;iBACzB;aACF;;wFACY,aAAa,cAVtB,aAAa;QACb,yBAAyB;QACzB,wBAAwB,aAGxB,aAAa;QACb,yBAAyB;QACzB,wBAAwB"}
1
+ {"version":3,"file":"ng-tasks.module.js","sourceRoot":"","sources":["../../src/lib/ng-tasks.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;;AAEpF;;;GAGG;AAaH,MAAM,OAAO,aAAa;uGAAb,aAAa;4DAAb,aAAa;gEAVtB,aAAa;YACb,yBAAyB;;iFAShB,aAAa;cAZzB,QAAQ;eAAC;gBACR,OAAO,EAAE;oBACP,aAAa;oBACb,yBAAyB;oBACzB,wBAAwB;iBACzB;gBACD,OAAO,EAAE;oBACP,aAAa;oBACb,yBAAyB;oBACzB,wBAAwB;iBACzB;aACF;;wFACY,aAAa,cAVtB,aAAa;QACb,yBAAyB;QACzB,wBAAwB,aAGxB,aAAa;QACb,yBAAyB;QACzB,wBAAwB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-tasks",
3
- "version": "3.4.0",
3
+ "version": "4.0.0",
4
4
  "description": "MemberJunction: Angular components for task visualization and management with Gantt chart support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,20 +9,20 @@
9
9
  "watch": "ngc --watch"
10
10
  },
11
11
  "dependencies": {
12
- "@angular/animations": "18.2.14",
13
- "@angular/common": "18.2.14",
14
- "@angular/core": "18.2.14",
15
- "@angular/platform-browser": "18.2.14",
16
- "@memberjunction/core": "3.4.0",
17
- "@memberjunction/core-entities": "3.4.0",
18
- "@memberjunction/ai-core-plus": "3.4.0",
19
- "@memberjunction/ai-engine-base": "3.4.0",
20
- "dhtmlx-gantt": "^8.0.10",
21
- "rxjs": "^7.8.1"
12
+ "@angular/animations": "21.1.3",
13
+ "@angular/common": "21.1.3",
14
+ "@angular/core": "21.1.3",
15
+ "@angular/platform-browser": "21.1.3",
16
+ "@memberjunction/core": "4.0.0",
17
+ "@memberjunction/core-entities": "4.0.0",
18
+ "@memberjunction/ai-core-plus": "4.0.0",
19
+ "@memberjunction/ai-engine-base": "4.0.0",
20
+ "dhtmlx-gantt": "^9.1.1",
21
+ "rxjs": "^7.8.2"
22
22
  },
23
23
  "peerDependencies": {
24
- "@angular/common": "18.2.14",
25
- "@angular/core": "18.2.14"
24
+ "@angular/common": "21.1.3",
25
+ "@angular/core": "21.1.3"
26
26
  },
27
27
  "author": "MemberJunction",
28
28
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ElementRef, ViewChild, OnDestroy, HostListener } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
2
+
3
3
  import { TaskEntity, TaskDependencyEntity } from '@memberjunction/core-entities';
4
4
  import { gantt } from 'dhtmlx-gantt';
5
5
  import { TaskDetailPanelComponent } from './task-detail-panel.component';
@@ -10,31 +10,37 @@ import { TaskDetailPanelComponent } from './task-detail-panel.component';
10
10
  @Component({
11
11
  selector: 'mj-gantt-task-viewer',
12
12
  standalone: true,
13
- imports: [CommonModule, TaskDetailPanelComponent],
13
+ imports: [TaskDetailPanelComponent],
14
14
  template: `
15
15
  <div class="gantt-task-viewer">
16
- <div *ngIf="!tasks || tasks.length === 0" class="no-tasks">
17
- <i class="fas fa-chart-gantt"></i>
18
- <p>No tasks to display in Gantt view</p>
19
- </div>
20
-
21
- <div *ngIf="tasks && tasks.length > 0" class="gantt-layout">
22
- <div #ganttContainer class="gantt-container"></div>
23
-
24
- <div *ngIf="selectedTask" class="gantt-resizer"
25
- (mousedown)="startResize($event)"></div>
26
-
27
- <div *ngIf="selectedTask" class="task-detail-panel" [style.width.px]="detailPanelWidth">
28
- <mj-task-detail-panel
29
- [task]="selectedTask"
30
- [agentRunId]="getAgentRunId(selectedTask)"
31
- (closePanel)="closeDetailPanel()"
32
- (openEntityRecord)="onOpenEntityRecord($event)">
33
- </mj-task-detail-panel>
16
+ @if (!tasks || tasks.length === 0) {
17
+ <div class="no-tasks">
18
+ <i class="fas fa-chart-gantt"></i>
19
+ <p>No tasks to display in Gantt view</p>
20
+ </div>
21
+ }
22
+
23
+ @if (tasks && tasks.length > 0) {
24
+ <div class="gantt-layout">
25
+ <div #ganttContainer class="gantt-container"></div>
26
+ @if (selectedTask) {
27
+ <div class="gantt-resizer"
28
+ (mousedown)="startResize($event)"></div>
29
+ }
30
+ @if (selectedTask) {
31
+ <div class="task-detail-panel" [style.width.px]="detailPanelWidth">
32
+ <mj-task-detail-panel
33
+ [task]="selectedTask"
34
+ [agentRunId]="getAgentRunId(selectedTask)"
35
+ (closePanel)="closeDetailPanel()"
36
+ (openEntityRecord)="onOpenEntityRecord($event)">
37
+ </mj-task-detail-panel>
38
+ </div>
39
+ }
34
40
  </div>
35
- </div>
41
+ }
36
42
  </div>
37
- `,
43
+ `,
38
44
  styles: [`
39
45
  .gantt-task-viewer {
40
46
  height: 100%;
@@ -14,69 +14,83 @@ import { TaskDetailPanelComponent } from './task-detail-panel.component';
14
14
  <div class="simple-task-viewer">
15
15
  <div class="list-layout">
16
16
  <div class="task-list" [class.with-detail]="selectedTask">
17
- <div *ngFor="let task of tasks"
18
- class="task-item"
19
- [class.completed]="task.Status === 'Complete'"
20
- [class.selected]="selectedTask?.ID === task.ID"
21
- (click)="onTaskClick(task)">
22
-
23
- <!-- Status Icon -->
24
- <div class="status-icon" [class.complete]="task.Status === 'Complete'">
25
- <i class="fas" [ngClass]="getStatusIcon(task.Status)"></i>
26
- </div>
27
-
28
- <!-- Task Content -->
29
- <div class="task-content">
30
- <div class="task-header">
31
- <div class="task-title-row">
32
- <span class="task-title" [class.completed-text]="task.Status === 'Complete'">
33
- {{ task.Name }}
34
- <i *ngIf="task.Status === 'Complete'" class="fas fa-check completed-check"></i>
35
- </span>
36
- <!-- Compact progress indicator for all tasks -->
37
- <div *ngIf="task.PercentComplete != null" class="task-progress-compact">
38
- <div class="progress-bar-compact">
39
- <div class="progress-fill-compact"
40
- [style.width.%]="task.PercentComplete"
41
- [class.complete]="task.Status === 'Complete'"></div>
17
+ @for (task of tasks; track task) {
18
+ <div
19
+ class="task-item"
20
+ [class.completed]="task.Status === 'Complete'"
21
+ [class.selected]="selectedTask?.ID === task.ID"
22
+ (click)="onTaskClick(task)">
23
+ <!-- Status Icon -->
24
+ <div class="status-icon" [class.complete]="task.Status === 'Complete'">
25
+ <i class="fas" [ngClass]="getStatusIcon(task.Status)"></i>
26
+ </div>
27
+ <!-- Task Content -->
28
+ <div class="task-content">
29
+ <div class="task-header">
30
+ <div class="task-title-row">
31
+ <span class="task-title" [class.completed-text]="task.Status === 'Complete'">
32
+ {{ task.Name }}
33
+ @if (task.Status === 'Complete') {
34
+ <i class="fas fa-check completed-check"></i>
35
+ }
36
+ </span>
37
+ <!-- Compact progress indicator for all tasks -->
38
+ @if (task.PercentComplete != null) {
39
+ <div class="task-progress-compact">
40
+ <div class="progress-bar-compact">
41
+ <div class="progress-fill-compact"
42
+ [style.width.%]="task.PercentComplete"
43
+ [class.complete]="task.Status === 'Complete'"></div>
44
+ </div>
45
+ <span class="progress-text-compact">{{ task.PercentComplete }}%</span>
46
+ </div>
47
+ }
42
48
  </div>
43
- <span class="progress-text-compact">{{ task.PercentComplete }}%</span>
49
+ <span class="task-meta">
50
+ @if (task.DueAt) {
51
+ <span class="due-date">
52
+ <i class="far fa-calendar"></i>
53
+ {{ formatDate(task.DueAt) }}
54
+ </span>
55
+ }
56
+ @if (task.User) {
57
+ <span class="assigned-to">
58
+ <i class="far fa-user"></i>
59
+ {{ task.User }}
60
+ </span>
61
+ }
62
+ </span>
44
63
  </div>
45
64
  </div>
46
- <span class="task-meta">
47
- <span *ngIf="task.DueAt" class="due-date">
48
- <i class="far fa-calendar"></i>
49
- {{ formatDate(task.DueAt) }}
50
- </span>
51
- <span *ngIf="task.User" class="assigned-to">
52
- <i class="far fa-user"></i>
53
- {{ task.User }}
54
- </span>
55
- </span>
56
65
  </div>
57
- </div>
58
- </div>
59
-
60
- <div *ngIf="!tasks || tasks.length === 0" class="no-tasks">
61
- <i class="fas fa-tasks"></i>
62
- <p>No tasks to display</p>
63
- </div>
64
- </div>
65
-
66
- <div *ngIf="selectedTask" class="list-resizer"
67
- (mousedown)="startResize($event)"></div>
68
-
69
- <div *ngIf="selectedTask" class="task-detail-panel" [style.width.px]="detailPanelWidth">
70
- <mj-task-detail-panel
71
- [task]="selectedTask"
72
- [agentRunId]="getAgentRunId(selectedTask)"
73
- (closePanel)="closeDetailPanel()"
74
- (openEntityRecord)="onOpenEntityRecord($event)">
75
- </mj-task-detail-panel>
66
+ }
67
+
68
+ @if (!tasks || tasks.length === 0) {
69
+ <div class="no-tasks">
70
+ <i class="fas fa-tasks"></i>
71
+ <p>No tasks to display</p>
72
+ </div>
73
+ }
76
74
  </div>
75
+
76
+ @if (selectedTask) {
77
+ <div class="list-resizer"
78
+ (mousedown)="startResize($event)"></div>
79
+ }
80
+
81
+ @if (selectedTask) {
82
+ <div class="task-detail-panel" [style.width.px]="detailPanelWidth">
83
+ <mj-task-detail-panel
84
+ [task]="selectedTask"
85
+ [agentRunId]="getAgentRunId(selectedTask)"
86
+ (closePanel)="closeDetailPanel()"
87
+ (openEntityRecord)="onOpenEntityRecord($event)">
88
+ </mj-task-detail-panel>
89
+ </div>
90
+ }
77
91
  </div>
78
92
  </div>
79
- `,
93
+ `,
80
94
  styles: [`
81
95
  .simple-task-viewer {
82
96
  height: 100%;