tg-ganttchart 0.0.7 → 0.0.8
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/babel.config.js +5 -0
- package/package.json +1 -4
- package/src/.eslintrc.js +18 -0
- package/src/App.vue +780 -0
- package/src/GanttElastic.standalone.vue +48 -0
- package/src/GanttElastic.vue +2305 -0
- package/src/assets/logo.png +0 -0
- package/src/components/Calendar/Calendar.vue +559 -0
- package/src/components/Calendar/CalendarRow.vue +112 -0
- package/src/components/Chart/Chart.vue +117 -0
- package/src/components/Chart/DaysHighlight.vue +60 -0
- package/src/components/Chart/DependencyLines.vue +112 -0
- package/src/components/Chart/Grid.vue +205 -0
- package/src/components/Chart/ProgressBar.vue +110 -0
- package/src/components/Chart/Row/Epic.vue +131 -0
- package/src/components/Chart/Row/Milestone.vue +117 -0
- package/src/components/Chart/Row/Project.vue +132 -0
- package/src/components/Chart/Row/Story.vue +127 -0
- package/src/components/Chart/Row/Subtask.vue +117 -0
- package/src/components/Chart/Row/Task.mixin.js +47 -0
- package/src/components/Chart/Row/Task.vue +82 -0
- package/src/components/Chart/Text.vue +105 -0
- package/src/components/Expander.vue +114 -0
- package/src/components/GanttElastic.standalone.vue +48 -0
- package/src/components/GanttElastic.vue +1646 -0
- package/src/components/Header/GanttViewFilter.vue +154 -0
- package/src/components/Header/Header.vue +266 -0
- package/src/components/MainView.vue +283 -0
- package/src/components/TaskList/ItemColumn.vue +212 -0
- package/src/components/TaskList/TaskList.vue +45 -0
- package/src/components/TaskList/TaskListHeader.vue +143 -0
- package/src/components/TaskList/TaskListItem.vue +35 -0
- package/src/components/bundle.js +28 -0
- package/src/components/components/Calendar/Calendar.vue +332 -0
- package/src/components/components/Calendar/CalendarRow.vue +96 -0
- package/src/components/components/Chart/Chart.vue +111 -0
- package/src/components/components/Chart/DaysHighlight.vue +71 -0
- package/src/components/components/Chart/DependencyLines.vue +112 -0
- package/src/components/components/Chart/Grid.vue +164 -0
- package/src/components/components/Chart/ProgressBar.vue +110 -0
- package/src/components/components/Chart/Row/Milestone.vue +117 -0
- package/src/components/components/Chart/Row/Project.vue +131 -0
- package/src/components/components/Chart/Row/Task.mixin.js +46 -0
- package/src/components/components/Chart/Row/Task.vue +107 -0
- package/src/components/components/Chart/Text.vue +105 -0
- package/src/components/components/Expander.vue +126 -0
- package/src/components/components/Header/Header.vue +265 -0
- package/src/components/components/MainView.vue +282 -0
- package/src/components/components/TaskList/ItemColumn.vue +121 -0
- package/src/components/components/TaskList/TaskList.vue +45 -0
- package/src/components/components/TaskList/TaskListHeader.vue +143 -0
- package/src/components/components/TaskList/TaskListItem.vue +35 -0
- package/src/components/components/bundle.js +28 -0
- package/src/components/style.js +308 -0
- package/src/index.js +12 -0
- package/src/main.js +6 -0
- package/src/style.js +398 -0
- package/vue.config.js +42 -0
- package/dist/demo.html +0 -1
- package/dist/tgganttchart.common.js +0 -9232
- package/dist/tgganttchart.common.js.map +0 -1
- package/dist/tgganttchart.css +0 -1
- package/dist/tgganttchart.umd.js +0 -9243
- package/dist/tgganttchart.umd.js.map +0 -1
- package/dist/tgganttchart.umd.min.js +0 -7
- package/dist/tgganttchart.umd.min.js.map +0 -1
package/src/App.vue
ADDED
|
@@ -0,0 +1,780 @@
|
|
|
1
|
+
<!-- App.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<div id="app">
|
|
4
|
+
<!-- <GanttChart /> -->
|
|
5
|
+
<!-- {{ tasks }} -->
|
|
6
|
+
<gantt-chart ref="ganttChart" :isHeaderVisible="isHeaderVisible" :options="options" :tasks="tasks"
|
|
7
|
+
@tasks-changed="tasksUpdate" @options-changed="optionsUpdate" @dynamic-style-changed="styleUpdate"
|
|
8
|
+
:projectName="projectName">
|
|
9
|
+
<gantt-view-filter slot="header" @view-mode-changed="onViewModeChanged"></gantt-view-filter>
|
|
10
|
+
<!-- <gantt-chart-header slot="header"></gantt-chart-header> -->
|
|
11
|
+
</gantt-chart>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
// import GanttChart from '../src/GanttElastic.standalone.vue';
|
|
17
|
+
import GanttChart from '../src/GanttElastic.vue';
|
|
18
|
+
import GanttViewFilter from '../src/components/Header/GanttViewFilter.vue';
|
|
19
|
+
// import GanttHeader from './components/Header/Header.vue';
|
|
20
|
+
import dayjs from "dayjs";
|
|
21
|
+
import isoWeek from 'dayjs/plugin/weekOfYear';
|
|
22
|
+
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
|
23
|
+
// Extend dayjs with required plugins
|
|
24
|
+
dayjs.extend(isoWeek);
|
|
25
|
+
dayjs.extend(quarterOfYear);
|
|
26
|
+
function getDate(hours) {
|
|
27
|
+
const currentDate = new Date();
|
|
28
|
+
const currentYear = currentDate.getFullYear();
|
|
29
|
+
const currentMonth = currentDate.getMonth();
|
|
30
|
+
const currentDay = currentDate.getDate();
|
|
31
|
+
const timeStamp = new Date(
|
|
32
|
+
currentYear,
|
|
33
|
+
currentMonth,
|
|
34
|
+
currentDay,
|
|
35
|
+
0,
|
|
36
|
+
0,
|
|
37
|
+
0
|
|
38
|
+
).getTime();
|
|
39
|
+
return new Date(timeStamp + hours * 60 * 60 * 1000).getTime();
|
|
40
|
+
}
|
|
41
|
+
let tasks = [
|
|
42
|
+
// === EPIC 1: Project Foundation ===
|
|
43
|
+
{
|
|
44
|
+
id: 1,
|
|
45
|
+
label: "Project Foundation & Setup",
|
|
46
|
+
user: "Project Manager",
|
|
47
|
+
start: "2025-09-01 09:00:00",
|
|
48
|
+
duration: 15 * 24 * 60 * 60 * 1000,
|
|
49
|
+
percent: 85,
|
|
50
|
+
type: "epic",
|
|
51
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 2,
|
|
55
|
+
label: "Project Kickoff Meeting",
|
|
56
|
+
user: "Project Manager",
|
|
57
|
+
start: "2025-09-01 09:00:00",
|
|
58
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
59
|
+
percent: 100,
|
|
60
|
+
type: "story",
|
|
61
|
+
parentId: 1,
|
|
62
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 3,
|
|
66
|
+
label: "Team Onboarding",
|
|
67
|
+
user: "HR Manager",
|
|
68
|
+
start: "2025-09-02 09:00:00",
|
|
69
|
+
duration: 3 * 24 * 60 * 60 * 1000,
|
|
70
|
+
percent: 100,
|
|
71
|
+
type: "task",
|
|
72
|
+
parentId: 1,
|
|
73
|
+
icon: "M3 3 L9 3 L9 7 L7 9 L5 7 L5 3 Z M3 3 L3 11 M5 3 L5 11",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 4,
|
|
77
|
+
label: "Development Environment Setup",
|
|
78
|
+
user: "DevOps Engineer",
|
|
79
|
+
start: "2025-09-05 09:00:00",
|
|
80
|
+
duration: 5 * 24 * 60 * 60 * 1000,
|
|
81
|
+
percent: 90,
|
|
82
|
+
type: "story",
|
|
83
|
+
parentId: 1,
|
|
84
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 5,
|
|
88
|
+
label: "Project Documentation",
|
|
89
|
+
user: "Technical Writer",
|
|
90
|
+
start: "2025-09-08 09:00:00",
|
|
91
|
+
duration: 4 * 24 * 60 * 60 * 1000,
|
|
92
|
+
percent: 70,
|
|
93
|
+
type: "task",
|
|
94
|
+
parentId: 1,
|
|
95
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 6,
|
|
99
|
+
label: "Code Repository Setup",
|
|
100
|
+
user: "DevOps Engineer",
|
|
101
|
+
start: "2025-09-10 09:00:00",
|
|
102
|
+
duration: 2 * 24 * 60 * 60 * 1000,
|
|
103
|
+
percent: 100,
|
|
104
|
+
type: "check",
|
|
105
|
+
parentId: 1,
|
|
106
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 7,
|
|
110
|
+
label: "CI/CD Pipeline Setup",
|
|
111
|
+
user: "DevOps Engineer",
|
|
112
|
+
start: "2025-09-12 09:00:00",
|
|
113
|
+
duration: 6 * 24 * 60 * 60 * 1000,
|
|
114
|
+
percent: 60,
|
|
115
|
+
type: "task",
|
|
116
|
+
parentId: 1,
|
|
117
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 8,
|
|
121
|
+
label: "Foundation Complete",
|
|
122
|
+
user: "Project Manager",
|
|
123
|
+
start: "2025-09-20 09:00:00",
|
|
124
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
125
|
+
percent: 0,
|
|
126
|
+
type: "task",
|
|
127
|
+
parentId: 1,
|
|
128
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// === EPIC 2: Requirements & Design ===
|
|
132
|
+
{
|
|
133
|
+
id: 9,
|
|
134
|
+
label: "Requirements & Design Phase",
|
|
135
|
+
user: "Business Analyst",
|
|
136
|
+
start: "2025-09-15 09:00:00",
|
|
137
|
+
duration: 25 * 24 * 60 * 60 * 1000,
|
|
138
|
+
percent: 65,
|
|
139
|
+
type: "epic",
|
|
140
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 10,
|
|
144
|
+
label: "Stakeholder Interviews",
|
|
145
|
+
user: "Business Analyst",
|
|
146
|
+
start: "2025-09-15 09:00:00",
|
|
147
|
+
duration: 8 * 24 * 60 * 60 * 1000,
|
|
148
|
+
percent: 100,
|
|
149
|
+
type: "flag",
|
|
150
|
+
parentId: 9,
|
|
151
|
+
icon: "M3 3 L9 3 L9 7 L7 9 L5 7 L5 3 Z M3 3 L3 11 M5 3 L5 11",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: 11,
|
|
155
|
+
label: "Functional Requirements",
|
|
156
|
+
user: "Business Analyst",
|
|
157
|
+
start: "2025-09-20 09:00:00",
|
|
158
|
+
duration: 6 * 24 * 60 * 60 * 1000,
|
|
159
|
+
percent: 90,
|
|
160
|
+
type: "task",
|
|
161
|
+
parentId: 9,
|
|
162
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: 12,
|
|
166
|
+
label: "Technical Requirements",
|
|
167
|
+
user: "Solution Architect",
|
|
168
|
+
start: "2025-09-22 09:00:00",
|
|
169
|
+
duration: 5 * 24 * 60 * 60 * 1000,
|
|
170
|
+
percent: 80,
|
|
171
|
+
type: "task",
|
|
172
|
+
parentId: 9,
|
|
173
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: 13,
|
|
177
|
+
label: "UI/UX Design",
|
|
178
|
+
user: "UI/UX Designer",
|
|
179
|
+
start: "2025-09-25 09:00:00",
|
|
180
|
+
duration: 10 * 24 * 60 * 60 * 1000,
|
|
181
|
+
percent: 40,
|
|
182
|
+
type: "check",
|
|
183
|
+
parentId: 9,
|
|
184
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 14,
|
|
188
|
+
label: "Design System Creation",
|
|
189
|
+
user: "UI/UX Designer",
|
|
190
|
+
start: "2025-09-28 09:00:00",
|
|
191
|
+
duration: 7 * 24 * 60 * 60 * 1000,
|
|
192
|
+
percent: 30,
|
|
193
|
+
type: "task",
|
|
194
|
+
parentId: 9,
|
|
195
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 15,
|
|
199
|
+
label: "Requirements Sign-off",
|
|
200
|
+
user: "Client",
|
|
201
|
+
start: "2025-10-08 09:00:00",
|
|
202
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
203
|
+
percent: 0,
|
|
204
|
+
type: "milestone",
|
|
205
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// === EPIC 3: Core Development ===
|
|
209
|
+
{
|
|
210
|
+
id: 16,
|
|
211
|
+
label: "Core Development Phase",
|
|
212
|
+
user: "Tech Lead",
|
|
213
|
+
start: "2025-10-01 09:00:00",
|
|
214
|
+
duration: 40 * 24 * 60 * 60 * 1000,
|
|
215
|
+
percent: 35,
|
|
216
|
+
type: "epic",
|
|
217
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: 17,
|
|
221
|
+
label: "Backend API Development",
|
|
222
|
+
user: "Backend Developer",
|
|
223
|
+
start: "2025-10-01 09:00:00",
|
|
224
|
+
duration: 20 * 24 * 60 * 60 * 1000,
|
|
225
|
+
percent: 45,
|
|
226
|
+
type: "story",
|
|
227
|
+
parentId: 16,
|
|
228
|
+
icon: "M3 4 L11 4 L11 10 L3 10 Z"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 17.1,
|
|
232
|
+
label: "Database Schema Design",
|
|
233
|
+
user: "Backend Developer",
|
|
234
|
+
start: "2025-10-01 09:00:00",
|
|
235
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
236
|
+
percent: 80,
|
|
237
|
+
type: "subtask",
|
|
238
|
+
parentId: 17,
|
|
239
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
id: 17.2,
|
|
243
|
+
label: "API Endpoints Implementation",
|
|
244
|
+
user: "Backend Developer",
|
|
245
|
+
start: "2025-10-08 09:00:00",
|
|
246
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
247
|
+
percent: 30,
|
|
248
|
+
type: "subtask",
|
|
249
|
+
parentId: 17,
|
|
250
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: 17.3,
|
|
254
|
+
label: "Data Validation Layer",
|
|
255
|
+
user: "Backend Developer",
|
|
256
|
+
start: "2025-10-15 09:00:00",
|
|
257
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
258
|
+
percent: 50,
|
|
259
|
+
type: "subtask",
|
|
260
|
+
parentId: 17,
|
|
261
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
id: 18,
|
|
265
|
+
label: "Frontend Development",
|
|
266
|
+
user: "Frontend Developer",
|
|
267
|
+
start: "2025-10-05 09:00:00",
|
|
268
|
+
duration: 25 * 24 * 60 * 60 * 1000,
|
|
269
|
+
percent: 30,
|
|
270
|
+
type: "story",
|
|
271
|
+
parentId: 16,
|
|
272
|
+
icon: "M3 4 L11 4 L11 10 L3 10 Z"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
id: 18.1,
|
|
276
|
+
label: "UI Components Setup",
|
|
277
|
+
user: "Frontend Developer",
|
|
278
|
+
start: "2025-10-05 09:00:00",
|
|
279
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
280
|
+
percent: 60,
|
|
281
|
+
type: "subtask",
|
|
282
|
+
parentId: 18,
|
|
283
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: 18.2,
|
|
287
|
+
label: "State Management",
|
|
288
|
+
user: "Frontend Developer",
|
|
289
|
+
start: "2025-10-12 09:00:00",
|
|
290
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
291
|
+
percent: 40,
|
|
292
|
+
type: "subtask",
|
|
293
|
+
parentId: 18,
|
|
294
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 18.3,
|
|
298
|
+
label: "API Integration",
|
|
299
|
+
user: "Frontend Developer",
|
|
300
|
+
start: "2025-10-19 09:00:00",
|
|
301
|
+
duration: 7 * 24 * 60 * 60 * 1000, // 1 week
|
|
302
|
+
percent: 20,
|
|
303
|
+
type: "subtask",
|
|
304
|
+
parentId: 18,
|
|
305
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
id: 19,
|
|
309
|
+
label: "Database Design & Implementation",
|
|
310
|
+
user: "Database Developer",
|
|
311
|
+
start: "2025-10-03 09:00:00",
|
|
312
|
+
duration: 12 * 24 * 60 * 60 * 1000,
|
|
313
|
+
percent: 70,
|
|
314
|
+
type: "check",
|
|
315
|
+
parentId: 16,
|
|
316
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
id: 20,
|
|
320
|
+
label: "Authentication System",
|
|
321
|
+
user: "Backend Developer",
|
|
322
|
+
start: "2025-10-08 09:00:00",
|
|
323
|
+
duration: 8 * 24 * 60 * 60 * 1000,
|
|
324
|
+
percent: 60,
|
|
325
|
+
type: "flag",
|
|
326
|
+
parentId: 16,
|
|
327
|
+
icon: "M3 3 L9 3 L9 7 L7 9 L5 7 L5 3 Z M3 3 L3 11 M5 3 L5 11",
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: 21,
|
|
331
|
+
label: "API Integration",
|
|
332
|
+
user: "Backend Developer",
|
|
333
|
+
start: "2025-10-15 09:00:00",
|
|
334
|
+
duration: 10 * 24 * 60 * 60 * 1000,
|
|
335
|
+
percent: 25,
|
|
336
|
+
type: "task",
|
|
337
|
+
parentId: 16,
|
|
338
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
id: 22,
|
|
342
|
+
label: "Core Features Complete",
|
|
343
|
+
user: "Tech Lead",
|
|
344
|
+
start: "2025-11-08 09:00:00",
|
|
345
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
346
|
+
percent: 0,
|
|
347
|
+
type: "milestone",
|
|
348
|
+
parentId: 16,
|
|
349
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
// === EPIC 4: Testing & Quality Assurance ===
|
|
353
|
+
{
|
|
354
|
+
id: 23,
|
|
355
|
+
label: "Testing & Quality Assurance",
|
|
356
|
+
user: "QA Lead",
|
|
357
|
+
start: "2025-10-25 09:00:00",
|
|
358
|
+
duration: 30 * 24 * 60 * 60 * 1000,
|
|
359
|
+
percent: 20,
|
|
360
|
+
type: "epic",
|
|
361
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
id: 24,
|
|
365
|
+
label: "Unit Testing",
|
|
366
|
+
user: "Developer",
|
|
367
|
+
start: "2025-10-25 09:00:00",
|
|
368
|
+
duration: 15 * 24 * 60 * 60 * 1000,
|
|
369
|
+
percent: 40,
|
|
370
|
+
type: "check",
|
|
371
|
+
parentId: 23,
|
|
372
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
id: 25,
|
|
376
|
+
label: "Integration Testing",
|
|
377
|
+
user: "QA Engineer",
|
|
378
|
+
start: "2025-11-05 09:00:00",
|
|
379
|
+
duration: 12 * 24 * 60 * 60 * 1000,
|
|
380
|
+
percent: 15,
|
|
381
|
+
type: "task",
|
|
382
|
+
parentId: 23,
|
|
383
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
id: 26,
|
|
387
|
+
label: "Performance Testing",
|
|
388
|
+
user: "QA Engineer",
|
|
389
|
+
start: "2025-11-10 09:00:00",
|
|
390
|
+
duration: 8 * 24 * 60 * 60 * 1000,
|
|
391
|
+
percent: 10,
|
|
392
|
+
type: "flag",
|
|
393
|
+
parentId: 23,
|
|
394
|
+
icon: "M3 3 L9 3 L9 7 L7 9 L5 7 L5 3 Z M3 3 L3 11 M5 3 L5 11",
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
id: 27,
|
|
398
|
+
label: "User Acceptance Testing",
|
|
399
|
+
user: "Business Analyst",
|
|
400
|
+
start: "2025-11-15 09:00:00",
|
|
401
|
+
duration: 10 * 24 * 60 * 60 * 1000,
|
|
402
|
+
percent: 5,
|
|
403
|
+
type: "task",
|
|
404
|
+
parentId: 23,
|
|
405
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: 28,
|
|
409
|
+
label: "Testing Complete",
|
|
410
|
+
user: "QA Lead",
|
|
411
|
+
start: "2025-11-22 09:00:00",
|
|
412
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
413
|
+
percent: 0,
|
|
414
|
+
type: "milestone",
|
|
415
|
+
parentId: 23,
|
|
416
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
// === EPIC 5: Deployment & Launch ===
|
|
420
|
+
{
|
|
421
|
+
id: 29,
|
|
422
|
+
label: "Deployment & Launch",
|
|
423
|
+
user: "DevOps Engineer",
|
|
424
|
+
start: "2025-11-20 09:00:00",
|
|
425
|
+
duration: 20 * 24 * 60 * 60 * 1000,
|
|
426
|
+
percent: 10,
|
|
427
|
+
type: "epic",
|
|
428
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: 30,
|
|
432
|
+
label: "Staging Environment Setup",
|
|
433
|
+
user: "DevOps Engineer",
|
|
434
|
+
start: "2025-11-20 09:00:00",
|
|
435
|
+
duration: 5 * 24 * 60 * 60 * 1000,
|
|
436
|
+
percent: 80,
|
|
437
|
+
type: "task",
|
|
438
|
+
parentId: 29,
|
|
439
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: 31,
|
|
443
|
+
label: "Production Environment Setup",
|
|
444
|
+
user: "DevOps Engineer",
|
|
445
|
+
start: "2025-11-25 09:00:00",
|
|
446
|
+
duration: 4 * 24 * 60 * 60 * 1000,
|
|
447
|
+
percent: 60,
|
|
448
|
+
type: "check",
|
|
449
|
+
parentId: 29,
|
|
450
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z M5 7 L7 9 L9 5"
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
id: 32,
|
|
454
|
+
label: "Security Audit",
|
|
455
|
+
user: "Security Engineer",
|
|
456
|
+
start: "2025-11-28 09:00:00",
|
|
457
|
+
duration: 3 * 24 * 60 * 60 * 1000,
|
|
458
|
+
percent: 20,
|
|
459
|
+
type: "flag",
|
|
460
|
+
parentId: 29,
|
|
461
|
+
icon: "M3 3 L9 3 L9 7 L7 9 L5 7 L5 3 Z M3 3 L3 11 M5 3 L5 11",
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
id: 33,
|
|
465
|
+
label: "Go-Live Deployment",
|
|
466
|
+
user: "DevOps Engineer",
|
|
467
|
+
start: "2025-12-05 09:00:00",
|
|
468
|
+
duration: 2 * 24 * 60 * 60 * 1000,
|
|
469
|
+
percent: 0,
|
|
470
|
+
type: "milestone",
|
|
471
|
+
parentId: 29,
|
|
472
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
id: 34,
|
|
476
|
+
label: "Post-Launch Monitoring",
|
|
477
|
+
user: "DevOps Engineer",
|
|
478
|
+
start: "2025-12-07 09:00:00",
|
|
479
|
+
duration: 7 * 24 * 60 * 60 * 1000,
|
|
480
|
+
percent: 0,
|
|
481
|
+
type: "task",
|
|
482
|
+
parentId: 29,
|
|
483
|
+
icon: "M3 3 L11 3 L11 11 L3 11 Z"
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
// === Project Milestones ===
|
|
487
|
+
{
|
|
488
|
+
id: 35,
|
|
489
|
+
label: "Project Complete",
|
|
490
|
+
user: "Project Manager",
|
|
491
|
+
start: "2025-12-15 09:00:00",
|
|
492
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
493
|
+
percent: 0,
|
|
494
|
+
type: "milestone",
|
|
495
|
+
icon: "M7 2 L12 7 L7 12 L2 7 Z"
|
|
496
|
+
}
|
|
497
|
+
];
|
|
498
|
+
|
|
499
|
+
let options = {
|
|
500
|
+
taskMapping: {
|
|
501
|
+
progress: "percent"
|
|
502
|
+
},
|
|
503
|
+
maxRows: 100,
|
|
504
|
+
maxHeight: 500,
|
|
505
|
+
title: {
|
|
506
|
+
label: "Your project title as html (link or whatever...)",
|
|
507
|
+
html: true
|
|
508
|
+
},
|
|
509
|
+
row: {
|
|
510
|
+
height: 24
|
|
511
|
+
},
|
|
512
|
+
calendar: {
|
|
513
|
+
// hour: {
|
|
514
|
+
// display: true
|
|
515
|
+
// },
|
|
516
|
+
viewMode: 'day',
|
|
517
|
+
hour: { height: 20, display: false },
|
|
518
|
+
day: { height: 30, display: true },
|
|
519
|
+
week: { height: 24, display: true },
|
|
520
|
+
month: { height: 30, display: true },
|
|
521
|
+
quarter: {
|
|
522
|
+
height: 30,
|
|
523
|
+
display: true,
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
chart: {
|
|
527
|
+
progress: {
|
|
528
|
+
bar: false
|
|
529
|
+
},
|
|
530
|
+
expander: {
|
|
531
|
+
display: true
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
taskList: {
|
|
535
|
+
expander: {
|
|
536
|
+
straight: false
|
|
537
|
+
},
|
|
538
|
+
columns: [
|
|
539
|
+
{
|
|
540
|
+
id: 1,
|
|
541
|
+
label: "ID",
|
|
542
|
+
value: "id",
|
|
543
|
+
width: 40
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
id: 2,
|
|
547
|
+
label: "Description",
|
|
548
|
+
value: "label",
|
|
549
|
+
width: 200,
|
|
550
|
+
expander: true,
|
|
551
|
+
html: true,
|
|
552
|
+
events: {
|
|
553
|
+
click({ data, column }) {
|
|
554
|
+
alert("description clicked!\n" + data.label);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
id: 3,
|
|
560
|
+
label: "Assigned to",
|
|
561
|
+
value: "user",
|
|
562
|
+
width: 130,
|
|
563
|
+
html: true
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
id: 3,
|
|
567
|
+
label: "Start",
|
|
568
|
+
value: task => dayjs(task.start).format("YYYY-MM-DD HH:mm A"),
|
|
569
|
+
width: 78
|
|
570
|
+
},
|
|
571
|
+
// {
|
|
572
|
+
// id: 4,
|
|
573
|
+
// label: "Type",
|
|
574
|
+
// value: "type",
|
|
575
|
+
// width: 68
|
|
576
|
+
// },
|
|
577
|
+
{
|
|
578
|
+
id: 5,
|
|
579
|
+
label: "%",
|
|
580
|
+
value: "progress",
|
|
581
|
+
width: 35,
|
|
582
|
+
style: {
|
|
583
|
+
"task-list-header-label": {
|
|
584
|
+
"text-align": "center",
|
|
585
|
+
width: "100%"
|
|
586
|
+
},
|
|
587
|
+
"task-list-item-value-container": {
|
|
588
|
+
"text-align": "center",
|
|
589
|
+
width: "100%"
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
]
|
|
594
|
+
},
|
|
595
|
+
locale: {
|
|
596
|
+
name: "en",
|
|
597
|
+
Now: "Now",
|
|
598
|
+
"X-Scale": "Zoom-X",
|
|
599
|
+
"Y-Scale": "Zoom-Y",
|
|
600
|
+
"Task list width": "Task list",
|
|
601
|
+
"Before/After": "Expand",
|
|
602
|
+
"Display task list": "Task list"
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
export default {
|
|
607
|
+
name: 'App',
|
|
608
|
+
components: {
|
|
609
|
+
'gantt-chart': GanttChart,
|
|
610
|
+
// 'gantt-chart-header': GanttHeader
|
|
611
|
+
'gantt-view-filter': GanttViewFilter
|
|
612
|
+
},
|
|
613
|
+
data() {
|
|
614
|
+
return {
|
|
615
|
+
tasks,
|
|
616
|
+
options,
|
|
617
|
+
dynamicStyle: {},
|
|
618
|
+
lastId: 16,
|
|
619
|
+
isHeaderVisible: false,
|
|
620
|
+
projectName: 'MY First Project'
|
|
621
|
+
};
|
|
622
|
+
},
|
|
623
|
+
methods: {
|
|
624
|
+
addTask() {
|
|
625
|
+
this.tasks.push({
|
|
626
|
+
id: this.lastId++,
|
|
627
|
+
label:
|
|
628
|
+
'<a href="https://images.pexels.com/photos/423364/pexels-photo-423364.jpeg?auto=compress&cs=tinysrgb&h=650&w=940" target="_blank" style="color:#0077c0;">Yeaahh! you have added a task bro!</a>',
|
|
629
|
+
user:
|
|
630
|
+
'<a href="https://images.pexels.com/photos/423364/pexels-photo-423364.jpeg?auto=compress&cs=tinysrgb&h=650&w=940" target="_blank" style="color:#0077c0;">Awesome!</a>',
|
|
631
|
+
start: getDate(24 * 3),
|
|
632
|
+
duration: 1 * 24 * 60 * 60 * 1000,
|
|
633
|
+
percent: 50,
|
|
634
|
+
type: "project"
|
|
635
|
+
});
|
|
636
|
+
},
|
|
637
|
+
tasksUpdate(tasks) {
|
|
638
|
+
this.tasks = tasks;
|
|
639
|
+
},
|
|
640
|
+
optionsUpdate(options) {
|
|
641
|
+
this.options = options;
|
|
642
|
+
},
|
|
643
|
+
styleUpdate(style) {
|
|
644
|
+
this.dynamicStyle = style;
|
|
645
|
+
},
|
|
646
|
+
onViewModeChanged(mode) {
|
|
647
|
+
// Update the calendar view mode
|
|
648
|
+
this.options.calendar.viewMode = mode;
|
|
649
|
+
|
|
650
|
+
// Update the step duration based on the view mode
|
|
651
|
+
if (this.options.times) {
|
|
652
|
+
switch (mode) {
|
|
653
|
+
case 'quarter':
|
|
654
|
+
this.options.times.stepDuration = 'quarter';
|
|
655
|
+
this.options.times.timeZoom = 15; // Reset zoom for better quarter view
|
|
656
|
+
break;
|
|
657
|
+
case 'month':
|
|
658
|
+
this.options.times.stepDuration = 'month';
|
|
659
|
+
this.options.times.timeZoom = 17; // Reset zoom for better month view
|
|
660
|
+
break;
|
|
661
|
+
case 'week':
|
|
662
|
+
this.options.times.stepDuration = 'week';
|
|
663
|
+
this.options.times.timeZoom = 19; // Reset zoom for better week view
|
|
664
|
+
break;
|
|
665
|
+
default: // 'day' or any other mode
|
|
666
|
+
this.options.times.stepDuration = 'day';
|
|
667
|
+
this.options.times.timeZoom = 21; // Reset zoom for better day view
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Force recalculation by triggering a reactive update
|
|
673
|
+
this.$nextTick(() => {
|
|
674
|
+
this.$forceUpdate();
|
|
675
|
+
// Recalculate start date based on new view mode and trigger full recalculation
|
|
676
|
+
if (this.$refs.ganttChart) {
|
|
677
|
+
// Trigger recalculation of dates and times with new view mode
|
|
678
|
+
this.$refs.ganttChart.prepareDates();
|
|
679
|
+
this.$refs.ganttChart.initTimes();
|
|
680
|
+
this.$refs.ganttChart.calculateSteps();
|
|
681
|
+
this.$refs.ganttChart.computeCalendarWidths();
|
|
682
|
+
|
|
683
|
+
// Ensure perfect alignment between calendar and chart
|
|
684
|
+
if (this.$refs.ganttChart.ensureCalendarChartAlignment) {
|
|
685
|
+
this.$refs.ganttChart.ensureCalendarChartAlignment();
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
},
|
|
690
|
+
// In App.vue -> onViewModeChanged method
|
|
691
|
+
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
</script>
|
|
695
|
+
|
|
696
|
+
<style>
|
|
697
|
+
#app {
|
|
698
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
699
|
+
-webkit-font-smoothing: antialiased;
|
|
700
|
+
-moz-osx-font-smoothing: grayscale;
|
|
701
|
+
text-align: center;
|
|
702
|
+
color: #2c3e50;
|
|
703
|
+
height: 100vh;
|
|
704
|
+
overflow: hidden;
|
|
705
|
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
706
|
+
position: relative;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
#app::before {
|
|
710
|
+
content: '';
|
|
711
|
+
position: absolute;
|
|
712
|
+
top: 0;
|
|
713
|
+
left: 0;
|
|
714
|
+
right: 0;
|
|
715
|
+
bottom: 0;
|
|
716
|
+
background:
|
|
717
|
+
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
|
|
718
|
+
radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
|
|
719
|
+
radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%);
|
|
720
|
+
pointer-events: none;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/* Modern container styling */
|
|
724
|
+
.gantt-elastic {
|
|
725
|
+
margin: 20px;
|
|
726
|
+
border-radius: 16px;
|
|
727
|
+
overflow: hidden;
|
|
728
|
+
box-shadow:
|
|
729
|
+
0 20px 40px rgba(0, 0, 0, 0.1),
|
|
730
|
+
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
731
|
+
background: rgba(255, 255, 255, 0.9);
|
|
732
|
+
backdrop-filter: blur(20px);
|
|
733
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/* Responsive design */
|
|
737
|
+
@media (max-width: 768px) {
|
|
738
|
+
#app {
|
|
739
|
+
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.gantt-elastic {
|
|
743
|
+
margin: 10px;
|
|
744
|
+
border-radius: 12px;
|
|
745
|
+
box-shadow:
|
|
746
|
+
0 10px 20px rgba(0, 0, 0, 0.08),
|
|
747
|
+
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
@media (max-width: 480px) {
|
|
752
|
+
.gantt-elastic {
|
|
753
|
+
margin: 5px;
|
|
754
|
+
border-radius: 8px;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* Dark mode support */
|
|
759
|
+
@media (prefers-color-scheme: dark) {
|
|
760
|
+
#app {
|
|
761
|
+
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
|
|
762
|
+
color: #e9ecef;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
#app::before {
|
|
766
|
+
background:
|
|
767
|
+
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.05) 0%, transparent 50%),
|
|
768
|
+
radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.05) 0%, transparent 50%),
|
|
769
|
+
radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.05) 0%, transparent 50%);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.gantt-elastic {
|
|
773
|
+
background: rgba(45, 45, 45, 0.9);
|
|
774
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
775
|
+
box-shadow:
|
|
776
|
+
0 20px 40px rgba(0, 0, 0, 0.3),
|
|
777
|
+
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
</style>
|