@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.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +10 -0
- package/README.md +233 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/components/gantt-task-viewer.component.d.ts +44 -0
- package/dist/lib/components/gantt-task-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/gantt-task-viewer.component.js +461 -0
- package/dist/lib/components/gantt-task-viewer.component.js.map +1 -0
- package/dist/lib/components/simple-task-viewer.component.d.ts +36 -0
- package/dist/lib/components/simple-task-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/simple-task-viewer.component.js +275 -0
- package/dist/lib/components/simple-task-viewer.component.js.map +1 -0
- package/dist/lib/components/task-detail-panel.component.d.ts +26 -0
- package/dist/lib/components/task-detail-panel.component.d.ts.map +1 -0
- package/dist/lib/components/task-detail-panel.component.js +294 -0
- package/dist/lib/components/task-detail-panel.component.js.map +1 -0
- package/dist/lib/components/task.component.d.ts +34 -0
- package/dist/lib/components/task.component.d.ts.map +1 -0
- package/dist/lib/components/task.component.js +201 -0
- package/dist/lib/components/task.component.js.map +1 -0
- package/dist/lib/models/task-view.models.d.ts +17 -0
- package/dist/lib/models/task-view.models.d.ts.map +1 -0
- package/dist/lib/models/task-view.models.js +2 -0
- package/dist/lib/models/task-view.models.js.map +1 -0
- package/dist/lib/ng-tasks.module.d.ts +14 -0
- package/dist/lib/ng-tasks.module.d.ts.map +1 -0
- package/dist/lib/ng-tasks.module.js +37 -0
- package/dist/lib/ng-tasks.module.js.map +1 -0
- package/dist/public-api.d.ts +9 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +12 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +31 -0
- package/src/index.ts +1 -0
- package/src/lib/components/gantt-task-viewer.component.ts +524 -0
- package/src/lib/components/simple-task-viewer.component.ts +356 -0
- package/src/lib/components/task-detail-panel.component.ts +304 -0
- package/src/lib/components/task.component.ts +175 -0
- package/src/lib/models/task-view.models.ts +19 -0
- package/src/lib/ng-tasks.module.ts +22 -0
- package/src/lib/types/frappe-gantt.d.ts +32 -0
- package/src/public-api.ts +14 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { TaskEntity, TaskDependencyEntity } from '@memberjunction/core-entities';
|
|
4
|
+
import { TaskViewMode } from '../models/task-view.models';
|
|
5
|
+
import { SimpleTaskViewerComponent } from './simple-task-viewer.component';
|
|
6
|
+
import { GanttTaskViewerComponent } from './gantt-task-viewer.component';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Main task component that composes SimpleTaskViewer and GanttTaskViewer
|
|
10
|
+
* Allows switching between list and Gantt chart views
|
|
11
|
+
*/
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'mj-task',
|
|
14
|
+
standalone: true,
|
|
15
|
+
imports: [CommonModule, SimpleTaskViewerComponent, GanttTaskViewerComponent],
|
|
16
|
+
template: `
|
|
17
|
+
<div class="task-component">
|
|
18
|
+
<!-- Header with View Toggle -->
|
|
19
|
+
<div class="task-header" *ngIf="showHeader">
|
|
20
|
+
<div class="header-left">
|
|
21
|
+
<h2 class="task-title" *ngIf="title">{{ title }}</h2>
|
|
22
|
+
<p class="task-description" *ngIf="description">{{ description }}</p>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="view-toggle" *ngIf="showViewToggle">
|
|
26
|
+
<button
|
|
27
|
+
class="toggle-btn"
|
|
28
|
+
[class.active]="viewMode === 'gantt'"
|
|
29
|
+
(click)="setViewMode('gantt')"
|
|
30
|
+
title="Gantt Chart">
|
|
31
|
+
<i class="fas fa-chart-gantt"></i>
|
|
32
|
+
<span>Gantt</span>
|
|
33
|
+
</button>
|
|
34
|
+
<button
|
|
35
|
+
class="toggle-btn"
|
|
36
|
+
[class.active]="viewMode === 'simple'"
|
|
37
|
+
(click)="setViewMode('simple')"
|
|
38
|
+
title="List View">
|
|
39
|
+
<i class="fas fa-list"></i>
|
|
40
|
+
<span>List</span>
|
|
41
|
+
</button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<!-- Task Viewer (Simple or Gantt) -->
|
|
46
|
+
<div class="task-viewer">
|
|
47
|
+
<mj-simple-task-viewer
|
|
48
|
+
*ngIf="viewMode === 'simple'"
|
|
49
|
+
[tasks]="tasks"
|
|
50
|
+
[agentRunMap]="agentRunMap"
|
|
51
|
+
(taskClicked)="onTaskClicked($event)"
|
|
52
|
+
(openEntityRecord)="onOpenEntityRecord($event)">
|
|
53
|
+
</mj-simple-task-viewer>
|
|
54
|
+
|
|
55
|
+
<mj-gantt-task-viewer
|
|
56
|
+
*ngIf="viewMode === 'gantt'"
|
|
57
|
+
[tasks]="ganttTasks || tasks"
|
|
58
|
+
[taskDependencies]="taskDependencies || []"
|
|
59
|
+
[agentRunMap]="agentRunMap"
|
|
60
|
+
(taskClicked)="onTaskClicked($event)"
|
|
61
|
+
(openEntityRecord)="onOpenEntityRecord($event)">
|
|
62
|
+
</mj-gantt-task-viewer>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
`,
|
|
66
|
+
styles: [`
|
|
67
|
+
.task-component {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
height: 100%;
|
|
71
|
+
background: #FAFAFA;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.task-header {
|
|
75
|
+
display: flex;
|
|
76
|
+
justify-content: space-between;
|
|
77
|
+
align-items: flex-start;
|
|
78
|
+
gap: 20px;
|
|
79
|
+
padding: 20px 24px;
|
|
80
|
+
background: white;
|
|
81
|
+
border-bottom: 1px solid #E5E7EB;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.header-left {
|
|
85
|
+
flex: 1;
|
|
86
|
+
min-width: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.task-title {
|
|
90
|
+
margin: 0 0 8px 0;
|
|
91
|
+
font-size: 20px;
|
|
92
|
+
font-weight: 700;
|
|
93
|
+
color: #111827;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.task-description {
|
|
97
|
+
margin: 0;
|
|
98
|
+
font-size: 14px;
|
|
99
|
+
color: #6B7280;
|
|
100
|
+
line-height: 1.5;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.view-toggle {
|
|
104
|
+
display: flex;
|
|
105
|
+
gap: 8px;
|
|
106
|
+
background: #F3F4F6;
|
|
107
|
+
padding: 4px;
|
|
108
|
+
border-radius: 8px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.toggle-btn {
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
gap: 6px;
|
|
115
|
+
padding: 8px 16px;
|
|
116
|
+
border: none;
|
|
117
|
+
background: transparent;
|
|
118
|
+
color: #6B7280;
|
|
119
|
+
font-size: 13px;
|
|
120
|
+
font-weight: 600;
|
|
121
|
+
border-radius: 6px;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
transition: all 0.15s;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.toggle-btn:hover {
|
|
127
|
+
color: #111827;
|
|
128
|
+
background: rgba(255, 255, 255, 0.5);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.toggle-btn.active {
|
|
132
|
+
background: white;
|
|
133
|
+
color: #3B82F6;
|
|
134
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.toggle-btn i {
|
|
138
|
+
font-size: 14px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.task-viewer {
|
|
142
|
+
flex: 1;
|
|
143
|
+
min-height: 0;
|
|
144
|
+
overflow: hidden;
|
|
145
|
+
}
|
|
146
|
+
`]
|
|
147
|
+
})
|
|
148
|
+
export class TaskComponent {
|
|
149
|
+
@Input() tasks: TaskEntity[] = [];
|
|
150
|
+
@Input() ganttTasks?: TaskEntity[]; // Optional separate task list for Gantt (includes parent)
|
|
151
|
+
@Input() taskDependencies?: TaskDependencyEntity[]; // Task dependencies for Gantt links
|
|
152
|
+
@Input() agentRunMap?: Map<string, string>; // Maps TaskID -> AgentRunID
|
|
153
|
+
@Input() title?: string;
|
|
154
|
+
@Input() description?: string;
|
|
155
|
+
@Input() showHeader: boolean = true;
|
|
156
|
+
@Input() showViewToggle: boolean = true; // Show Gantt/List toggle
|
|
157
|
+
@Input() viewMode: TaskViewMode = 'simple';
|
|
158
|
+
|
|
159
|
+
@Output() viewModeChanged = new EventEmitter<TaskViewMode>();
|
|
160
|
+
@Output() taskClicked = new EventEmitter<TaskEntity>();
|
|
161
|
+
@Output() openEntityRecord = new EventEmitter<{ entityName: string; recordId: string }>();
|
|
162
|
+
|
|
163
|
+
public setViewMode(mode: TaskViewMode): void {
|
|
164
|
+
this.viewMode = mode;
|
|
165
|
+
this.viewModeChanged.emit(mode);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public onTaskClicked(task: TaskEntity): void {
|
|
169
|
+
this.taskClicked.emit(task);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public onOpenEntityRecord(event: { entityName: string; recordId: string }): void {
|
|
173
|
+
this.openEntityRecord.emit(event);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TaskEntity } from '@memberjunction/core-entities';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* View mode for task display
|
|
5
|
+
*/
|
|
6
|
+
export type TaskViewMode = 'simple' | 'gantt';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gantt bar data for Frappe Gantt
|
|
10
|
+
*/
|
|
11
|
+
export interface GanttTask {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
start: string;
|
|
15
|
+
end: string;
|
|
16
|
+
progress: number;
|
|
17
|
+
dependencies?: string;
|
|
18
|
+
custom_class?: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { TaskComponent } from './components/task.component';
|
|
3
|
+
import { SimpleTaskViewerComponent } from './components/simple-task-viewer.component';
|
|
4
|
+
import { GanttTaskViewerComponent } from './components/gantt-task-viewer.component';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MemberJunction Tasks Module
|
|
8
|
+
* Provides task visualization components with Gantt chart support
|
|
9
|
+
*/
|
|
10
|
+
@NgModule({
|
|
11
|
+
imports: [
|
|
12
|
+
TaskComponent,
|
|
13
|
+
SimpleTaskViewerComponent,
|
|
14
|
+
GanttTaskViewerComponent
|
|
15
|
+
],
|
|
16
|
+
exports: [
|
|
17
|
+
TaskComponent,
|
|
18
|
+
SimpleTaskViewerComponent,
|
|
19
|
+
GanttTaskViewerComponent
|
|
20
|
+
]
|
|
21
|
+
})
|
|
22
|
+
export class NgTasksModule { }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
declare module 'frappe-gantt/dist/frappe-gantt.js' {
|
|
2
|
+
export interface GanttOptions {
|
|
3
|
+
view_mode?: 'Quarter Day' | 'Half Day' | 'Day' | 'Week' | 'Month' | 'Year';
|
|
4
|
+
bar_height?: number;
|
|
5
|
+
bar_corner_radius?: number;
|
|
6
|
+
arrow_curve?: number;
|
|
7
|
+
padding?: number;
|
|
8
|
+
view_modes?: string[];
|
|
9
|
+
date_format?: string;
|
|
10
|
+
custom_popup_html?: (task: any) => string;
|
|
11
|
+
on_click?: (task: any) => void;
|
|
12
|
+
on_date_change?: (task: any, start: Date, end: Date) => void;
|
|
13
|
+
on_progress_change?: (task: any, progress: number) => void;
|
|
14
|
+
on_view_change?: (mode: string) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface GanttTask {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
start: string;
|
|
21
|
+
end: string;
|
|
22
|
+
progress: number;
|
|
23
|
+
dependencies?: string;
|
|
24
|
+
custom_class?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default class Gantt {
|
|
28
|
+
constructor(element: string | HTMLElement | SVGElement, tasks: GanttTask[], options?: GanttOptions);
|
|
29
|
+
change_view_mode(mode: string): void;
|
|
30
|
+
refresh(tasks: GanttTask[]): void;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API Surface of @memberjunction/ng-tasks
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Module
|
|
6
|
+
export * from './lib/ng-tasks.module';
|
|
7
|
+
|
|
8
|
+
// Components
|
|
9
|
+
export * from './lib/components/task.component';
|
|
10
|
+
export * from './lib/components/simple-task-viewer.component';
|
|
11
|
+
export * from './lib/components/gantt-task-viewer.component';
|
|
12
|
+
|
|
13
|
+
// Models
|
|
14
|
+
export * from './lib/models/task-view.models';
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"experimentalDecorators": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"lib": ["es2022", "dom"]
|
|
13
|
+
},
|
|
14
|
+
"angularCompilerOptions": {
|
|
15
|
+
"skipTemplateCodegen": true,
|
|
16
|
+
"strictMetadataEmit": true,
|
|
17
|
+
"enableResourceInlining": true,
|
|
18
|
+
"strictTemplates": true
|
|
19
|
+
},
|
|
20
|
+
"include": [
|
|
21
|
+
"src/**/*.ts"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
|