jordium-gantt-vue3 1.4.4 → 1.4.6-patch.1
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/README.md +153 -36
- package/dist/assets/jordium-gantt-vue3.css +1 -1
- package/dist/jordium-gantt-vue3-styles.js +1 -1
- package/dist/jordium-gantt-vue3.cjs.js +60 -60
- package/dist/jordium-gantt-vue3.es.js +9002 -8917
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
25
|
<a href="./README.md">中文</a> |
|
|
26
|
-
<a href="./README-EN.md">English</a>
|
|
26
|
+
<a href="./README-EN.md">English</a> |
|
|
27
27
|
<a href="./CHANGELOG.md">更新日志</a>
|
|
28
28
|
</p>
|
|
29
29
|
|
|
@@ -179,16 +179,17 @@ npm run dev
|
|
|
179
179
|
|
|
180
180
|
#### 基础属性
|
|
181
181
|
|
|
182
|
-
| 属性名 | 类型
|
|
183
|
-
| --------------------------- |
|
|
184
|
-
| `tasks` | `Task[]`
|
|
185
|
-
| `milestones` | `Task[]`
|
|
186
|
-
| `showToolbar` | `boolean`
|
|
187
|
-
| `useDefaultDrawer` | `boolean`
|
|
188
|
-
| `useDefaultMilestoneDialog` | `boolean`
|
|
189
|
-
| `autoSortByStartDate` | `boolean`
|
|
190
|
-
| `allowDragAndResize` | `boolean`
|
|
191
|
-
| `enableTaskRowMove`
|
|
182
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
183
|
+
| --------------------------- | ----------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------- |
|
|
184
|
+
| `tasks` | `Task[]` | `[]` | 任务数据数组 |
|
|
185
|
+
| `milestones` | `Task[]` | `[]` | 里程碑数据数组(注意:类型为 Task[],需设置 type='milestone') |
|
|
186
|
+
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
|
187
|
+
| `useDefaultDrawer` | `boolean` | `true` | 是否使用内置任务编辑抽屉(TaskDrawer) |
|
|
188
|
+
| `useDefaultMilestoneDialog` | `boolean` | `true` | 是否使用内置里程碑编辑对话框(MilestoneDialog) |
|
|
189
|
+
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
|
190
|
+
| `allowDragAndResize` | `boolean` | `true` | 是否允许拖拽和调整任务/里程碑大小 |
|
|
191
|
+
| `enableTaskRowMove` | `boolean` | `false` | 是否允许拖拽和摆放TaskRow |
|
|
192
|
+
| `assigneeOptions` | `Array<{ key?: string \| number; value: string \| number; label: string }>` | `[]` | 任务编辑抽屉中负责人下拉菜单的选项列表 |
|
|
192
193
|
|
|
193
194
|
#### 配置对象属性
|
|
194
195
|
|
|
@@ -243,14 +244,14 @@ npm run dev
|
|
|
243
244
|
| `milestone-deleted` | `{ milestoneId: number }` | 里程碑删除 |
|
|
244
245
|
| `milestone-icon-changed` | `{ milestoneId, icon }` | 里程碑图标变更 |
|
|
245
246
|
| `milestone-drag-end` | `(milestone: Task)` | 拖拽里程碑结束 |
|
|
246
|
-
| `task-row-moved` | `payload: { draggedTask: Task
|
|
247
|
+
| `task-row-moved` | `payload: { draggedTask: Task, targetTask: Task, position: 'after' \| 'child', oldParent: Task \| null, newParent: Task \| null }` | 拖拽TaskRow结束(可选) |
|
|
247
248
|
|
|
248
249
|
#### 示例1:最简单的甘特图
|
|
249
250
|
|
|
250
251
|
```vue
|
|
251
252
|
<template>
|
|
252
253
|
<div style="height: 600px;">
|
|
253
|
-
<GanttChart :tasks="tasks" />
|
|
254
|
+
<GanttChart :tasks="tasks" :assignee-options="assigneeOptions" />
|
|
254
255
|
</div>
|
|
255
256
|
</template>
|
|
256
257
|
|
|
@@ -268,6 +269,12 @@ const tasks = ref([
|
|
|
268
269
|
progress: 100,
|
|
269
270
|
},
|
|
270
271
|
])
|
|
272
|
+
|
|
273
|
+
const assigneeOptions = ref([
|
|
274
|
+
{ value: 'zhangsan', label: '张三' },
|
|
275
|
+
{ value: 'lisi', label: '李四' },
|
|
276
|
+
{ value: 'wangwu', label: '王五' },
|
|
277
|
+
])
|
|
271
278
|
</script>
|
|
272
279
|
```
|
|
273
280
|
|
|
@@ -276,7 +283,7 @@ const tasks = ref([
|
|
|
276
283
|
```vue
|
|
277
284
|
<template>
|
|
278
285
|
<div style="height: 600px;">
|
|
279
|
-
<GanttChart :tasks="tasks" :milestones="milestones" />
|
|
286
|
+
<GanttChart :tasks="tasks" :milestones="milestones" :assignee-options="assigneeOptions" />
|
|
280
287
|
</div>
|
|
281
288
|
</template>
|
|
282
289
|
|
|
@@ -304,6 +311,12 @@ const milestones = ref([
|
|
|
304
311
|
icon: 'diamond',
|
|
305
312
|
},
|
|
306
313
|
])
|
|
314
|
+
|
|
315
|
+
const assigneeOptions = ref([
|
|
316
|
+
{ value: 'zhangsan', label: '张三' },
|
|
317
|
+
{ value: 'lisi', label: '李四' },
|
|
318
|
+
{ value: 'wangwu', label: '王五' },
|
|
319
|
+
])
|
|
307
320
|
</script>
|
|
308
321
|
```
|
|
309
322
|
|
|
@@ -324,6 +337,7 @@ const milestones = ref([
|
|
|
324
337
|
:tasks="tasks"
|
|
325
338
|
:milestones="milestones"
|
|
326
339
|
:show-toolbar="false"
|
|
340
|
+
:assignee-options="assigneeOptions"
|
|
327
341
|
@task-added="handleTaskAdded"
|
|
328
342
|
@milestone-saved="handleMilestoneSaved"
|
|
329
343
|
/>
|
|
@@ -339,6 +353,12 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
339
353
|
const tasks = ref([])
|
|
340
354
|
const milestones = ref([])
|
|
341
355
|
|
|
356
|
+
const assigneeOptions = ref([
|
|
357
|
+
{ value: 'zhangsan', label: '张三' },
|
|
358
|
+
{ value: 'lisi', label: '李四' },
|
|
359
|
+
{ value: 'wangwu', label: '王五' },
|
|
360
|
+
])
|
|
361
|
+
|
|
342
362
|
const addTask = () => {
|
|
343
363
|
const newTask = {
|
|
344
364
|
id: Date.now(),
|
|
@@ -386,7 +406,8 @@ const handleMilestoneSaved = milestone => {
|
|
|
386
406
|
| `endDate` | `string` | - | - | 结束日期,格式:'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm' |
|
|
387
407
|
| `progress` | `number` | - | `0` | 任务进度,范围 0-100 |
|
|
388
408
|
| `predecessor` | `number[]` | - | - | 前置任务 ID 数组,标准格式:`[1, 2, 3]`<br/>**兼容格式**:也支持字符串 `'1,2,3'` 或字符串数组 `['1', '2', '3']`,组件会自动解析 |
|
|
389
|
-
| `assignee` | `string` | - | - |
|
|
409
|
+
| `assignee` | `string` | - | - | 任务负责人,用作负责人下拉菜单的值绑定 |
|
|
410
|
+
| `assigneeName` | `string` | - | - | 任务负责人姓名,自动从绑定的数据集`assigneeOptions`中获取Label作为显示,如果需要自定义,可以在GanttChart回调事件`task-added`中自定义信息 |
|
|
390
411
|
| `avatar` | `string` | - | - | 任务负责人头像 URL |
|
|
391
412
|
| `estimatedHours` | `number` | - | - | 预估工时(小时) |
|
|
392
413
|
| `actualHours` | `number` | - | - | 实际工时(小时) |
|
|
@@ -425,7 +446,8 @@ const handleMilestoneSaved = milestone => {
|
|
|
425
446
|
| `taskBarConfig` | `TaskBarConfig` | `{}` | 任务条样式配置,详见 [TaskBarConfig 配置](#taskbarconfig-配置) |
|
|
426
447
|
| `taskListConfig` | `TaskListConfig` | `undefined` | 任务列表配置,详见 [TaskListConfig 配置](#tasklistconfig-配置) |
|
|
427
448
|
| `autoSortByStartDate` | `boolean` | `false` | 是否根据开始时间自动排序任务 |
|
|
428
|
-
| `enableTaskRowMove` | `boolean` | `false` | 是否允许拖拽和摆放TaskRow
|
|
449
|
+
| `enableTaskRowMove` | `boolean` | `false` | 是否允许拖拽和摆放TaskRow |
|
|
450
|
+
| `assigneeOptions` | `Array<{ key?: string \| number; value: string \| number; label: string }>` | `[]` | 任务编辑抽屉中负责人下拉菜单的选项列表 |
|
|
429
451
|
|
|
430
452
|
**配置说明**:
|
|
431
453
|
|
|
@@ -451,7 +473,7 @@ const handleMilestoneSaved = milestone => {
|
|
|
451
473
|
| `successor-added` | `{ targetTask: Task, newTask: Task }` | 通过右键菜单添加后置任务后 | `targetTask` 是原任务,`newTask` 是新创建的后置任务(其 predecessor 已包含 targetTask.id) |
|
|
452
474
|
| `timer-started` | `(task: Task) => void` | 任务计时器启动时 | 开始记录任务工时 |
|
|
453
475
|
| `timer-stopped` | `(task: Task) => void` | 任务计时器停止时 | 停止记录任务工时 |
|
|
454
|
-
| `task-row-moved` | `payload: { draggedTask: Task
|
|
476
|
+
| `task-row-moved` | `payload: { draggedTask: Task, targetTask: Task, position: 'after' \| 'child', oldParent: Task \| null, newParent: Task \| null }` | 拖拽TaskRow结束(可选) | 组件已自动完成数据移动和TaskList/Timeline同步。监听此事件为完全可选,仅用于显示提示、调用API保存等。`position`: 'after'=同级放置,'child'=作为子任务 |
|
|
455
477
|
|
|
456
478
|
**数据同步说明**:
|
|
457
479
|
|
|
@@ -466,6 +488,7 @@ const handleMilestoneSaved = milestone => {
|
|
|
466
488
|
<div style="height: 600px;">
|
|
467
489
|
<GanttChart
|
|
468
490
|
:tasks="tasks"
|
|
491
|
+
:assignee-options="assigneeOptions"
|
|
469
492
|
@add-task="handleAddTask"
|
|
470
493
|
@task-added="handleTaskAdded"
|
|
471
494
|
@task-updated="handleTaskUpdated"
|
|
@@ -503,6 +526,12 @@ const tasks = ref<Task[]>([
|
|
|
503
526
|
},
|
|
504
527
|
])
|
|
505
528
|
|
|
529
|
+
const assigneeOptions = ref([
|
|
530
|
+
{ value: 'zhangsan', label: '张三' },
|
|
531
|
+
{ value: 'lisi', label: '李四' },
|
|
532
|
+
{ value: 'wangwu', label: '王五' },
|
|
533
|
+
])
|
|
534
|
+
|
|
506
535
|
// 工具栏"添加任务"按钮点击事件
|
|
507
536
|
const handleAddTask = () => {
|
|
508
537
|
console.log('准备新增任务...')
|
|
@@ -555,6 +584,7 @@ const handleTaskDragEnd = (task: Task) => {
|
|
|
555
584
|
<template>
|
|
556
585
|
<GanttChart
|
|
557
586
|
:tasks="tasks"
|
|
587
|
+
:assignee-options="assigneeOptions"
|
|
558
588
|
@predecessor-added="handlePredecessorAdded"
|
|
559
589
|
@successor-added="handleSuccessorAdded"
|
|
560
590
|
/>
|
|
@@ -617,6 +647,12 @@ const tasks = ref<Task[]>([
|
|
|
617
647
|
},
|
|
618
648
|
])
|
|
619
649
|
|
|
650
|
+
const assigneeOptions = ref([
|
|
651
|
+
{ value: 'zhangsan', label: '张三' },
|
|
652
|
+
{ value: 'lisi', label: '李四' },
|
|
653
|
+
{ value: 'wangwu', label: '王五' },
|
|
654
|
+
])
|
|
655
|
+
|
|
620
656
|
// 通过右键菜单添加前置任务时触发
|
|
621
657
|
const handlePredecessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|
622
658
|
console.log(`任务 [${event.targetTask.name}] 添加了前置任务 [${event.newTask.name}]`)
|
|
@@ -670,6 +706,7 @@ const handleSuccessorAdded = (event: { targetTask: Task; newTask: Task }) => {
|
|
|
670
706
|
:show-toolbar="false"
|
|
671
707
|
:use-default-drawer="true"
|
|
672
708
|
:use-default-milestone-dialog="true"
|
|
709
|
+
:assignee-options="assigneeOptions"
|
|
673
710
|
@add-task="handleAddTask"
|
|
674
711
|
@add-milestone="handleAddMilestone"
|
|
675
712
|
@task-added="handleTaskAdded"
|
|
@@ -685,6 +722,12 @@ import 'jordium-gantt-vue3/dist/assets/jordium-gantt-vue3.css'
|
|
|
685
722
|
const tasks = ref([])
|
|
686
723
|
const milestones = ref([])
|
|
687
724
|
|
|
725
|
+
const assigneeOptions = ref([
|
|
726
|
+
{ value: 'zhangsan', label: '张三' },
|
|
727
|
+
{ value: 'lisi', label: '李四' },
|
|
728
|
+
{ value: 'wangwu', label: '王五' },
|
|
729
|
+
])
|
|
730
|
+
|
|
688
731
|
// 自定义按钮触发事件(组件会响应并打开内置编辑器)
|
|
689
732
|
const triggerAddTask = () => {
|
|
690
733
|
// 直接触发组件的 add-task 事件
|
|
@@ -728,6 +771,7 @@ const handleTaskAdded = e => {
|
|
|
728
771
|
<GanttChart
|
|
729
772
|
:tasks="tasks"
|
|
730
773
|
:enable-task-row-move="true"
|
|
774
|
+
:assignee-options="assigneeOptions"
|
|
731
775
|
@task-row-moved="handleTaskRowMoved"
|
|
732
776
|
/>
|
|
733
777
|
</div>
|
|
@@ -764,31 +808,47 @@ const tasks = ref<Task[]>([
|
|
|
764
808
|
},
|
|
765
809
|
])
|
|
766
810
|
|
|
767
|
-
|
|
768
|
-
|
|
811
|
+
const assigneeOptions = ref([
|
|
812
|
+
{ value: 'zhangsan', label: '张三' },
|
|
813
|
+
{ value: 'lisi', label: '李四' },
|
|
814
|
+
{ value: 'wangwu', label: '王五' },
|
|
815
|
+
])
|
|
816
|
+
|
|
817
|
+
// 任务行拖拽完成事件(可选)
|
|
818
|
+
const handleTaskRowMoved = async (payload: {
|
|
769
819
|
draggedTask: Task
|
|
770
820
|
targetTask: Task
|
|
771
821
|
position: 'after' | 'child'
|
|
822
|
+
oldParent: Task | null
|
|
823
|
+
newParent: Task | null
|
|
772
824
|
}) => {
|
|
773
|
-
const { draggedTask, targetTask, position } = payload
|
|
825
|
+
const { draggedTask, targetTask, position, oldParent, newParent } = payload
|
|
774
826
|
|
|
775
|
-
|
|
827
|
+
// 组件已自动完成任务移动、parentId更新和TaskList/Timeline同步
|
|
828
|
+
// 监听此事件为完全可选,仅用于:
|
|
776
829
|
|
|
777
|
-
//
|
|
778
|
-
|
|
779
|
-
|
|
830
|
+
// 1. 显示自定义提示消息
|
|
831
|
+
const oldParentName = oldParent?.name || '根目录'
|
|
832
|
+
const newParentName = newParent?.name || '根目录'
|
|
833
|
+
const positionText = position === 'after' ? '在目标任务之后' : '作为目标任务的子任务'
|
|
834
|
+
showMessage(`任务 [${draggedTask.name}] 已从 [${oldParentName}] 移动到 [${newParentName}] (${positionText})`, 'success')
|
|
780
835
|
|
|
781
|
-
// 这里可以:
|
|
782
|
-
// 1. 显示确认对话框,让用户确认是否移动
|
|
783
836
|
// 2. 调用后端 API 保存新的任务层级关系
|
|
784
|
-
|
|
837
|
+
try {
|
|
838
|
+
await api.updateTaskHierarchy({
|
|
839
|
+
taskId: draggedTask.id,
|
|
840
|
+
targetTaskId: targetTask.id,
|
|
841
|
+
position: position,
|
|
842
|
+
oldParentId: oldParent?.id,
|
|
843
|
+
newParentId: newParent?.id,
|
|
844
|
+
})
|
|
845
|
+
} catch (error) {
|
|
846
|
+
console.error('保存任务层级失败:', error)
|
|
847
|
+
showMessage('保存失败,请刷新页面', 'error')
|
|
848
|
+
}
|
|
785
849
|
|
|
786
|
-
//
|
|
787
|
-
//
|
|
788
|
-
// taskId: draggedTask.id,
|
|
789
|
-
// targetTaskId: targetTask.id,
|
|
790
|
-
// position: position
|
|
791
|
-
// })
|
|
850
|
+
// 3. 触发其他业务逻辑(如更新关联数据、记录操作日志等)
|
|
851
|
+
// ...
|
|
792
852
|
}
|
|
793
853
|
</script>
|
|
794
854
|
```
|
|
@@ -796,7 +856,7 @@ const handleTaskRowMoved = (payload: {
|
|
|
796
856
|
**拖拽排序说明**:
|
|
797
857
|
|
|
798
858
|
- **启用拖拽**:设置 `enable-task-row-move="true"` 启用任务行拖拽功能(默认为 `false`)
|
|
799
|
-
-
|
|
859
|
+
- **拖拽算法**(组件内部自动执行):
|
|
800
860
|
- **算法1(放置在后面)**:当目标任务没有子任务时,被拖拽的任务会放置在目标任务之后(同级),`position='after'`
|
|
801
861
|
- **算法2(作为子任务)**:当目标任务有子任务时,被拖拽的任务会成为目标任务的第一个子任务,`position='child'`
|
|
802
862
|
- **视觉反馈**:
|
|
@@ -804,7 +864,16 @@ const handleTaskRowMoved = (payload: {
|
|
|
804
864
|
- 悬停在有效目标任务上时显示蓝色边框提示
|
|
805
865
|
- 无子任务的任务显示蓝色底部边框
|
|
806
866
|
- 有子任务的任务显示蓝色四周边框
|
|
807
|
-
-
|
|
867
|
+
- **自动同步**:组件内部通过对象引用直接修改 `props.tasks`,自动完成任务移动、`parentId` 更新、`children` 数组调整以及 TaskList/Timeline 同步
|
|
868
|
+
- **事件监听(可选)**:
|
|
869
|
+
- `task-row-moved` 事件为完全可选,仅用于显示提示、调用API保存、记录日志等额外处理
|
|
870
|
+
- 无需手动更新 `tasks.value`,组件已自动完成数据同步
|
|
871
|
+
- **事件参数**:
|
|
872
|
+
- `draggedTask`: 被拖拽的任务
|
|
873
|
+
- `targetTask`: 目标任务
|
|
874
|
+
- `position`: 放置位置('after' 或 'child')
|
|
875
|
+
- `oldParent`: 原父任务(null 表示根目录)
|
|
876
|
+
- `newParent`: 新父任务(null 表示根目录)
|
|
808
877
|
- **限制条件**:
|
|
809
878
|
- 不能拖拽到自己身上
|
|
810
879
|
- 不能拖拽到自己的子任务上(避免循环引用)
|
|
@@ -1221,6 +1290,54 @@ const handleDelete = () => {
|
|
|
1221
1290
|
|
|
1222
1291
|
本章节详细介绍 GanttChart 组件的配置选项和扩展能力,包括组件配置、主题与国际化、自定义扩展三个部分。
|
|
1223
1292
|
|
|
1293
|
+
### 任务类型定义
|
|
1294
|
+
|
|
1295
|
+
任务类型(`type` 字段)用于区分不同类型的任务,组件内部会根据类型执行不同的逻辑判断。
|
|
1296
|
+
|
|
1297
|
+
#### 内置任务类型
|
|
1298
|
+
|
|
1299
|
+
| 类型值 | 说明 | 默认值 |
|
|
1300
|
+
| ------- | ---------- | ------ |
|
|
1301
|
+
| `story` | 用户故事 | - |
|
|
1302
|
+
| `task` | 普通任务 | ✅ |
|
|
1303
|
+
| `bug` | 缺陷/问题 | - |
|
|
1304
|
+
|
|
1305
|
+
#### 功能区分
|
|
1306
|
+
|
|
1307
|
+
不同任务类型在组件中具有不同的功能特性:
|
|
1308
|
+
|
|
1309
|
+
| 功能 | story | task | bug |
|
|
1310
|
+
| ---------------- | ----- | ---- | --- |
|
|
1311
|
+
| 可作为上级任务 | ✅ | ✅ | ❌ |
|
|
1312
|
+
| 可作为前置任务 | ❌ | ✅ | ❌ |
|
|
1313
|
+
| 支持计时器 | ❌ | ✅ | ✅ |
|
|
1314
|
+
| 自动视为父任务 | ✅ | ❌ | ❌ |
|
|
1315
|
+
| 删除时特殊提示 | ✅ | ❌ | ❌ |
|
|
1316
|
+
|
|
1317
|
+
#### 注意事项
|
|
1318
|
+
|
|
1319
|
+
> ⚠️ **重要提示**
|
|
1320
|
+
>
|
|
1321
|
+
> 1. 任务类型值为组件内置判断使用,**请勿随意修改**这些枚举值
|
|
1322
|
+
> 2. 客制化 TaskDrawer 时,必须保持 `story`、`task`、`bug` 这三个枚举值
|
|
1323
|
+
> 3. 如需添加其他业务标签,建议使用自定义属性字段,例如:`customType`、`category`、`label` 等
|
|
1324
|
+
|
|
1325
|
+
**示例:使用自定义标签**
|
|
1326
|
+
|
|
1327
|
+
```typescript
|
|
1328
|
+
const tasks = ref([
|
|
1329
|
+
{
|
|
1330
|
+
id: 1,
|
|
1331
|
+
name: '需求分析',
|
|
1332
|
+
type: 'task', // 保持组件内置类型
|
|
1333
|
+
customType: 'requirement', // 自定义业务类型
|
|
1334
|
+
category: 'analysis', // 自定义分类
|
|
1335
|
+
startDate: '2025-01-01',
|
|
1336
|
+
endDate: '2025-01-10',
|
|
1337
|
+
},
|
|
1338
|
+
])
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1224
1341
|
### 组件配置
|
|
1225
1342
|
|
|
1226
1343
|
#### ToolbarConfig(工具栏配置)
|
|
@@ -2172,5 +2289,5 @@ jordium-gantt-vue3/
|
|
|
2172
2289
|
---
|
|
2173
2290
|
|
|
2174
2291
|
<p align="center">
|
|
2175
|
-
|
|
2292
|
+
如果这个项目对你有帮助,请给一个 ⭐️ 支持一下!
|
|
2176
2293
|
</p>
|