Skip to content

Commit 4824424

Browse files
committed
Merge branch 'release/3.6.0'
2 parents 0ceadc2 + f4aa140 commit 4824424

File tree

17 files changed

+3145
-288
lines changed

17 files changed

+3145
-288
lines changed

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ All notable changes to this project will be documented in this file.
88

99
[Full Changelog](https://github.com/Xeyos88/HyVueGantt/compare/v3.4.0...v3.5.0)
1010

11-
12-
1311
**✨ New Features:**
1412

1513
- Export Gantt in: pdf, png, svg and excel

docs/.vitepress/theme/components/AdvancedGanttDemo.vue

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
<script setup lang="ts">
22
import { ref, computed } from 'vue'
33
import { GGanttChart, GGanttRow } from 'hy-vue-gantt'
4-
import type { ConnectionType, ConnectionSpeed, MarkerConnection, TimeUnit, DayOptionLabel, ConnectionPattern, GanttBarObject, ChartRow, ExportOptions } from 'hy-vue-gantt'
4+
import type { ConnectionType, ConnectionSpeed, MarkerConnection, TimeUnit, DayOptionLabel, ConnectionPattern, GanttBarObject, ChartRow, ExportOptions, ImportResult } from 'hy-vue-gantt'
5+
import { downloadSampleCSV } from './CSVGenerator'
6+
import {downloadSampleJIRA} from './JIRAGEnerator'
57
68
const sections = ref<{ [key: string]: boolean }>({
79
timeConfig: false,
810
displayConfig: false,
911
connectionConfig: false,
1012
behaviorConfig: false,
1113
slotsConfig: false,
12-
exportConfig: false
13-
14+
exportConfig: false,
15+
importConfig: false
1416
})
1517
18+
const showImporter = ref(false)
19+
1620
const toggleSection = (section: string) => {
1721
sections.value[section] = !sections.value[section]
1822
}
@@ -160,6 +164,34 @@ const handleEvent = (event: any, type: string) => {
160164
addEventLog(type, event)
161165
}
162166
167+
const handleImport = (result: ImportResult) => {
168+
if (result.success && result.data) {
169+
showImporter.value = false
170+
171+
/*if (result.data.chartStart) {
172+
chartStart.value = result.data.chartStart instanceof Date
173+
? result.data.chartStart.toISOString().split('T')[0]
174+
: result.data.chartStart.split('T')[0]
175+
}
176+
177+
if (result.data.chartEnd) {
178+
chartEnd.value = result.data.chartEnd instanceof Date
179+
? result.data.chartEnd.toISOString().split('T')[0]
180+
: result.data.chartEnd.split('T')[0]
181+
}*/
182+
183+
addEventLog('Import', {
184+
success: true,
185+
rowsCount: result.data.rows.length,
186+
warnings: result.warnings?.length || 0
187+
})
188+
} else {
189+
addEventLog('Importazione Fallita', {
190+
error: result.error
191+
})
192+
}
193+
}
194+
163195
export type ChartRowWithOptionalBars = Omit<ChartRow, "bars"> & { bars?: GanttBarObject[] };
164196
165197
@@ -629,6 +661,41 @@ const formattedEventLog = computed(() => {
629661
</div>
630662
</div>
631663
</div>
664+
665+
<div class="settings-group">
666+
<h4 @click="toggleSection('importConfig')" class="toggle-header">Import Data
667+
<span :class="{'arrow-down': sections.importConfig, 'arrow-up': !sections.importConfig}">▼</span>
668+
</h4>
669+
<div v-if="sections.importConfig" class="settings-grid">
670+
<div class="setting-item">
671+
<button
672+
class="import-button"
673+
@click="showImporter = true"
674+
style="width: 100%; padding: 8px; background: #42b883; color: white; border: none; border-radius: 4px; cursor: pointer;"
675+
>
676+
Open Importer
677+
</button>
678+
</div>
679+
<div class="setting-item">
680+
<button
681+
class="download-csv-button"
682+
@click="downloadSampleCSV"
683+
style="width: 100%; padding: 8px; background: #42b883; color: white; border: none; border-radius: 4px; cursor: pointer;"
684+
>
685+
Download Example CSV
686+
</button>
687+
</div>
688+
<div class="setting-item">
689+
<button
690+
class="download-csv-button"
691+
@click="downloadSampleJIRA"
692+
style="width: 100%; padding: 8px; background: #42b883; color: white; border: none; border-radius: 4px; cursor: pointer;"
693+
>
694+
Download Example JIRA
695+
</button>
696+
</div>
697+
</div>
698+
</div>
632699
</div>
633700

634701
<div class="settings-column">
@@ -907,6 +974,10 @@ const formattedEventLog = computed(() => {
907974
:eventsAxisHeight="eventsAxisHeight"
908975
:exportEnabled="exportEnabled"
909976
:exportOptions="exportOptions"
977+
:show-importer="showImporter"
978+
:importer-title="'Import project data'"
979+
:importer-default-format="'csv'"
980+
:importer-allowed-formats="['msproject', 'jira', 'csv', 'excel']"
910981
@click-bar="handleEvent($event, 'Bar Click')"
911982
@drag-bar="handleEvent($event, 'Bar Drag')"
912983
@sort="handleEvent($event, 'Sort Change')"
@@ -921,6 +992,7 @@ const formattedEventLog = computed(() => {
921992
@export-start="handleEvent($event, 'Start Export')"
922993
@export-success="handleEvent($event, 'Start Success')"
923994
@export-error="handleEvent($event, 'Start Error')"
995+
@import-data="handleImport"
924996
>
925997
<g-gantt-row
926998
v-for="row in sampleData"
@@ -999,7 +1071,7 @@ const formattedEventLog = computed(() => {
9991071
<!-- Custom Bar Tooltip Slot -->
10001072
<template v-if="customSlots.barTooltip" #bar-tooltip="{ bar, barStart, barEnd }">
10011073
<div class="custom-tooltip">
1002-
<div class="tooltip-header">{{ bar.ganttBarConfig.label }}</div>
1074+
<div class="tooltip-header">{{ bar!.ganttBarConfig.label }}</div>
10031075
<div class="tooltip-content">
10041076
<div>Start: {{ new Date(barStart).toLocaleDateString() }}</div>
10051077
<div>End: {{ new Date(barEnd).toLocaleDateString() }}</div>
@@ -1037,7 +1109,6 @@ const formattedEventLog = computed(() => {
10371109
</div>
10381110
</template>
10391111
</g-gantt-chart>
1040-
10411112
<!-- Event Log Panel -->
10421113
<div class="event-log">
10431114
<h4>Event Log</h4>
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import dayjs from 'dayjs';
2+
3+
export function generateSampleCSV(): string {
4+
const year = new Date().getFullYear();
5+
const month = new Date().getMonth() + 1;
6+
7+
const projectStart = dayjs(`${year}-${month}-10`);
8+
9+
const tasks = [
10+
{
11+
id: 1,
12+
name: "Management System Project",
13+
startDate: projectStart.format('YYYY-MM-DD HH:mm:ss'),
14+
endDate: projectStart.add(60, 'day').format('YYYY-MM-DD'),
15+
progress: 20,
16+
parentId: "",
17+
dependencies: ""
18+
},
19+
{
20+
id: 2,
21+
name: "Requirements Analysis",
22+
startDate: projectStart.add(1, 'day').format('YYYY-MM-DD'),
23+
endDate: projectStart.add(10, 'day').format('YYYY-MM-DD'),
24+
progress: 100,
25+
parentId: 1,
26+
dependencies: ""
27+
},
28+
{
29+
id: 3,
30+
name: "Requirements Documentation",
31+
startDate: projectStart.add(1, 'day').format('YYYY-MM-DD HH:mm:ss'),
32+
endDate: projectStart.add(5, 'day').format('YYYY-MM-DD'),
33+
progress: 100,
34+
parentId: 2,
35+
dependencies: ""
36+
},
37+
{
38+
id: 4,
39+
name: "Stakeholder Interviews",
40+
startDate: projectStart.add(4, 'day').format('YYYY-MM-DD'),
41+
endDate: projectStart.add(8, 'day').format('YYYY-MM-DD'),
42+
progress: 100,
43+
parentId: 2,
44+
dependencies: "3"
45+
},
46+
{
47+
id: 5,
48+
name: "Requirements Approval",
49+
startDate: projectStart.add(9, 'day').format('YYYY-MM-DD'),
50+
endDate: projectStart.add(10, 'day').format('YYYY-MM-DD'),
51+
progress: 100,
52+
parentId: 2,
53+
dependencies: "4"
54+
},
55+
{
56+
id: 6,
57+
name: "Design",
58+
startDate: projectStart.add(11, 'day').format('YYYY-MM-DD'),
59+
endDate: projectStart.add(25, 'day').format('YYYY-MM-DD'),
60+
progress: 80,
61+
parentId: 1,
62+
dependencies: "5"
63+
},
64+
{
65+
id: 7,
66+
name: "System Architecture",
67+
startDate: projectStart.add(11, 'day').format('YYYY-MM-DD'),
68+
endDate: projectStart.add(18, 'day').format('YYYY-MM-DD'),
69+
progress: 100,
70+
parentId: 6,
71+
dependencies: "5"
72+
},
73+
{
74+
id: 8,
75+
name: "Database Design",
76+
startDate: projectStart.add(19, 'day').format('YYYY-MM-DD'),
77+
endDate: projectStart.add(23, 'day').format('YYYY-MM-DD'),
78+
progress: 100,
79+
parentId: 6,
80+
dependencies: "7"
81+
},
82+
{
83+
id: 9,
84+
name: "UI/UX Design",
85+
startDate: projectStart.add(19, 'day').format('YYYY-MM-DD'),
86+
endDate: projectStart.add(25, 'day').format('YYYY-MM-DD'),
87+
progress: 60,
88+
parentId: 6,
89+
dependencies: "7"
90+
},
91+
{
92+
id: 10,
93+
name: "Development",
94+
startDate: projectStart.add(26, 'day').format('YYYY-MM-DD'),
95+
endDate: projectStart.add(45, 'day').format('YYYY-MM-DD'),
96+
progress: 30,
97+
parentId: 1,
98+
dependencies: "6"
99+
},
100+
{
101+
id: 11,
102+
name: "Backend Implementation",
103+
startDate: projectStart.add(26, 'day').format('YYYY-MM-DD'),
104+
endDate: projectStart.add(35, 'day').format('YYYY-MM-DD'),
105+
progress: 50,
106+
parentId: 10,
107+
dependencies: "8"
108+
},
109+
{
110+
id: 12,
111+
name: "Frontend Implementation",
112+
startDate: projectStart.add(30, 'day').format('YYYY-MM-DD'),
113+
endDate: projectStart.add(42, 'day').format('YYYY-MM-DD'),
114+
progress: 30,
115+
parentId: 10,
116+
dependencies: "9"
117+
},
118+
{
119+
id: 13,
120+
name: "API Integration",
121+
startDate: projectStart.add(36, 'day').format('YYYY-MM-DD'),
122+
endDate: projectStart.add(45, 'day').format('YYYY-MM-DD'),
123+
progress: 10,
124+
parentId: 10,
125+
dependencies: "11"
126+
},
127+
{
128+
id: 14,
129+
name: "Testing",
130+
startDate: projectStart.add(46, 'day').format('YYYY-MM-DD'),
131+
endDate: projectStart.add(51, 'day').format('YYYY-MM-DD'),
132+
progress: 0,
133+
parentId: 1,
134+
dependencies: "10"
135+
},
136+
{
137+
id: 15,
138+
name: "Unit Testing",
139+
startDate: projectStart.add(46, 'day').format('YYYY-MM-DD'),
140+
endDate: projectStart.add(48, 'day').format('YYYY-MM-DD'),
141+
progress: 0,
142+
parentId: 14,
143+
dependencies: "13"
144+
},
145+
{
146+
id: 16,
147+
name: "Integration Testing",
148+
startDate: projectStart.add(49, 'day').format('YYYY-MM-DD'),
149+
endDate: projectStart.add(50, 'day').format('YYYY-MM-DD'),
150+
progress: 0,
151+
parentId: 14,
152+
dependencies: "15"
153+
},
154+
{
155+
id: 17,
156+
name: "Acceptance Testing",
157+
startDate: projectStart.add(51, 'day').format('YYYY-MM-DD'),
158+
endDate: projectStart.add(51, 'day').format('YYYY-MM-DD'),
159+
progress: 0,
160+
parentId: 14,
161+
dependencies: "16"
162+
},
163+
{
164+
id: 18,
165+
name: "Deployment",
166+
startDate: projectStart.add(52, 'day').format('YYYY-MM-DD'),
167+
endDate: projectStart.add(55, 'day').format('YYYY-MM-DD'),
168+
progress: 0,
169+
parentId: 1,
170+
dependencies: "14"
171+
},
172+
{
173+
id: 19,
174+
name: "Data Migration",
175+
startDate: projectStart.add(52, 'day').format('YYYY-MM-DD'),
176+
endDate: projectStart.add(53, 'day').format('YYYY-MM-DD'),
177+
progress: 0,
178+
parentId: 18,
179+
dependencies: "17"
180+
},
181+
{
182+
id: 20,
183+
name: "Production Release",
184+
startDate: projectStart.add(54, 'day').format('YYYY-MM-DD'),
185+
endDate: projectStart.add(55, 'day').format('YYYY-MM-DD'),
186+
progress: 0,
187+
parentId: 18,
188+
dependencies: "19"
189+
}
190+
];
191+
192+
193+
const header = "id,name,start_date,end_date,progress,parent_id,dependencies";
194+
195+
const rows = tasks.map(task => {
196+
return `${task.id},"${task.name}",${task.startDate},${task.endDate},${task.progress},${task.parentId},${task.dependencies}`;
197+
});
198+
199+
return [header, ...rows].join('\n');
200+
}
201+
202+
203+
export function downloadSampleCSV(): void {
204+
const csvContent = generateSampleCSV();
205+
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
206+
const url = URL.createObjectURL(blob);
207+
208+
const link = document.createElement('a');
209+
link.setAttribute('href', url);
210+
link.setAttribute('download', `gantt-sample-data-${new Date().toISOString().slice(0, 10)}.csv`);
211+
link.style.display = 'none';
212+
213+
document.body.appendChild(link);
214+
link.click();
215+
document.body.removeChild(link);
216+
217+
setTimeout(() => {
218+
URL.revokeObjectURL(url);
219+
}, 100);
220+
}

0 commit comments

Comments
 (0)