v1.6.0 - 提供Task列表插槽功能
This commit is contained in:
+57
-30
@@ -142,6 +142,9 @@ const toolbarConfig = {
|
||||
showExpandCollapse: true, // 显示全部展开/折叠按钮
|
||||
}
|
||||
|
||||
// TaskList列渲染模式配置
|
||||
const taskListColumnRenderMode = ref<'default' | 'declarative'>('declarative')
|
||||
|
||||
// TaskList列配置
|
||||
const availableColumns = ref<TaskListColumnConfig[]>([
|
||||
{ key: 'predecessor', label: '前置任务', visible: true },
|
||||
@@ -518,6 +521,7 @@ const handleTaskAddEvent = (e: { task: Task }) => {
|
||||
// 任务删除事件处理器
|
||||
const handleTaskDeleteEvent = (e: { task: Task; deleteChildren?: boolean }) => {
|
||||
const task = e.task
|
||||
const deleteChildren = e.deleteChildren
|
||||
|
||||
showMessage(`Demo 任务[${task.name}] 已删除`, 'success')
|
||||
|
||||
@@ -525,8 +529,10 @@ const handleTaskDeleteEvent = (e: { task: Task; deleteChildren?: boolean }) => {
|
||||
// 这里只需要显示消息,无需再次执行删除逻辑
|
||||
// 如果需要在删除后清理其他数据(如 predecessor),可以在这里处理
|
||||
|
||||
// 收集被删除任务的所有ID(包括子任务)
|
||||
const deletedTaskIds = collectAllTaskIds(task)
|
||||
// 收集被删除任务的ID
|
||||
// 如果 deleteChildren 为 false,只删除父任务本身,子任务会被提升,所以不应该收集子任务ID
|
||||
// 如果 deleteChildren 为 true,删除父任务及所有子任务,需要收集所有ID
|
||||
const deletedTaskIds = deleteChildren ? collectAllTaskIds(task) : [task.id]
|
||||
// 清理predecessor依赖关系
|
||||
cleanupPredecessorReferences(deletedTaskIds)
|
||||
}
|
||||
@@ -749,13 +755,24 @@ const handleTaskRowMoved = async (payload: {
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="docs-links">
|
||||
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||
<img src="https://img.shields.io/npm/v/jordium-gantt-vue3?style=flat-square" alt="npm version">
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/jordium-gantt-vue3">
|
||||
<img src="https://img.shields.io/npm/dt/jordium-gantt-vue3?style=flat-square" alt="npm total">
|
||||
</a>
|
||||
<span class="docs-divider"></span>
|
||||
<a href="#github-docs" class="doc-link github-link" @click="handleGithubDocsClick">
|
||||
<img class="doc-icon" src="./public/github.svg" alt="GitHub" />
|
||||
</a>
|
||||
<a href='https://github.com/nelson820125/jordium-gantt-vue3/stargazers'><img src='https://img.shields.io/github/stars/nelson820125/jordium-gantt-vue3?style=social' alt='star'></img></a>
|
||||
<a href='https://github.com/nelson820125/jordium-gantt-vue3/network/members'><img src='https://img.shields.io/github/forks/nelson820125/jordium-gantt-vue3?style=social' alt='fork'></img></a>
|
||||
<span class="docs-divider"></span>
|
||||
<a href="#gitee-docs" class="doc-link gitee-link" @click="handleGiteeDocsClick">
|
||||
<img class="doc-icon" src="./public/gitee.svg" alt="Gitee" />
|
||||
</a>
|
||||
<a href='https://gitee.com/jordium/jordium-gantt-vue3/stargazers'><img src='https://gitee.com/jordium/jordium-gantt-vue3/badge/star.svg?theme=dark' alt='star'></img></a>
|
||||
<a href='https://gitee.com/jordium/jordium-gantt-vue3/members'><img src='https://gitee.com/jordium/jordium-gantt-vue3/badge/fork.svg?theme=dark' alt='fork'></img></a>
|
||||
</div>
|
||||
</h1>
|
||||
<VersionHistoryDrawer :visible="showVersionDrawer" @close="showVersionDrawer = false" />
|
||||
@@ -998,6 +1015,25 @@ const handleTaskRowMoved = async (payload: {
|
||||
|
||||
<!-- 列配置 -->
|
||||
<div class="subsection">
|
||||
<!-- 渲染模式选择 -->
|
||||
<div class="render-mode-group" style="margin-bottom: 16px;">
|
||||
<h5 class="subsection-title">{{ t.taskListConfig.columns.renderMode }}</h5>
|
||||
<div
|
||||
class="width-unit-toggle"
|
||||
style="margin-bottom: 12px; display: flex; align-items: center; gap: 16px"
|
||||
>
|
||||
<label class="taskbar-control">
|
||||
<input v-model="taskListColumnRenderMode" type="radio" value="default" />
|
||||
<span class="taskbar-label">
|
||||
{{ t.taskListConfig.columns.renderModeDefault }}
|
||||
</span>
|
||||
</label>
|
||||
<label class="taskbar-control">
|
||||
<input v-model="taskListColumnRenderMode" type="radio" value="declarative" />
|
||||
<span class="taskbar-label">{{ t.taskListConfig.columns.renderModeDeclarative }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="subsection-title">{{ t.taskListConfig.columns.title }}</h5>
|
||||
<div class="column-controls">
|
||||
<label v-for="column in availableColumns" :key="column.key" class="column-control">
|
||||
@@ -1184,7 +1220,7 @@ const handleTaskRowMoved = async (payload: {
|
||||
:on-export-csv="handleCustomCsvExport"
|
||||
:on-language-change="handleLanguageChange"
|
||||
:on-theme-change="handleThemeChange"
|
||||
task-list-column-render-mode="declarative"
|
||||
:task-list-column-render-mode="taskListColumnRenderMode"
|
||||
@milestone-saved="handleMilestoneSaved"
|
||||
@milestone-deleted="handleMilestoneDeleted"
|
||||
@milestone-icon-changed="handleMilestoneIconChanged"
|
||||
@@ -1281,32 +1317,6 @@ const handleTaskRowMoved = async (payload: {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 列级 Slot 示例:自定义 'assignee' 列的渲染(覆盖内置渲染) -->
|
||||
<!-- 取消下面的注释可以看到效果 -->
|
||||
<!--
|
||||
<template #column-assignee="{ task }">
|
||||
<div style="display: flex; align-items: center; gap: 6px;">
|
||||
<div
|
||||
style="
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
"
|
||||
>
|
||||
{{ task.assignee ? task.assignee.charAt(0) : '?' }}
|
||||
</div>
|
||||
<span style="font-size: 13px;">{{ task.assignee || '未分配' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<!-- 使用 TaskListColumn 组件自定义列 声明式模式 -->
|
||||
<TaskListColumn prop="name" :label="t.taskName" width="300" align="center">
|
||||
<template #header>
|
||||
@@ -1344,7 +1354,19 @@ const handleTaskRowMoved = async (payload: {
|
||||
</GanttChart>
|
||||
</div>
|
||||
<div class="license-info">
|
||||
<p>MIT License @JORDIUM.COM</p>
|
||||
<span>MIT License @ 2025 JORDIUM.COM</span>
|
||||
<a href="https://opensource.org/licenses/MIT">
|
||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
|
||||
</a>
|
||||
<a href="https://vuejs.org/">
|
||||
<img src="https://img.shields.io/badge/Vue.js->=3.5.13-4FC08D?style=flat-square&logo=vue.js&logoColor=white" alt="Vue.js">
|
||||
</a>
|
||||
<a href="https://www.typescriptlang.org/">
|
||||
<img src="https://img.shields.io/badge/TypeScript->=5.8.3-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript">
|
||||
</a>
|
||||
<a href="https://nodejs.org/">
|
||||
<img src="https://img.shields.io/badge/Node.js->=16.0.0-339933?style=flat-square&logo=node.js&logoColor=white" alt="Nodejs">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- MilestoneDialog用于新建/编辑里程碑 -->
|
||||
@@ -2037,6 +2059,11 @@ const handleTaskRowMoved = async (payload: {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 全局暗色主题支持 */
|
||||
|
||||
@@ -1,347 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { GanttChart } from '../src/index'
|
||||
import type { Task } from '../src/models/classes/Task'
|
||||
|
||||
// 示例任务数据
|
||||
const tasks = ref<Task[]>([
|
||||
{
|
||||
id: 1,
|
||||
name: '项目规划',
|
||||
type: 'story',
|
||||
startDate: '2024-01-01',
|
||||
endDate: '2024-01-15',
|
||||
progress: 100,
|
||||
assignee: '张三',
|
||||
collapsed: false,
|
||||
children: [
|
||||
{
|
||||
id: 11,
|
||||
name: '需求分析',
|
||||
type: 'task',
|
||||
startDate: '2024-01-01',
|
||||
endDate: '2024-01-05',
|
||||
progress: 100,
|
||||
assignee: '李四',
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: '技术方案设计',
|
||||
type: 'task',
|
||||
startDate: '2024-01-06',
|
||||
endDate: '2024-01-15',
|
||||
progress: 100,
|
||||
assignee: '王五',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '开发阶段',
|
||||
type: 'story',
|
||||
startDate: '2024-01-16',
|
||||
endDate: '2024-02-28',
|
||||
progress: 65,
|
||||
assignee: '张三',
|
||||
collapsed: false,
|
||||
children: [
|
||||
{
|
||||
id: 21,
|
||||
name: '前端开发',
|
||||
type: 'task',
|
||||
startDate: '2024-01-16',
|
||||
endDate: '2024-02-15',
|
||||
progress: 80,
|
||||
assignee: '赵六',
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
name: '后端开发',
|
||||
type: 'task',
|
||||
startDate: '2024-01-16',
|
||||
endDate: '2024-02-20',
|
||||
progress: 70,
|
||||
assignee: '孙七',
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
name: '数据库设计',
|
||||
type: 'task',
|
||||
startDate: '2024-01-20',
|
||||
endDate: '2024-02-10',
|
||||
progress: 50,
|
||||
assignee: '周八',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '测试上线',
|
||||
type: 'story',
|
||||
startDate: '2024-03-01',
|
||||
endDate: '2024-03-15',
|
||||
progress: 30,
|
||||
assignee: '张三',
|
||||
collapsed: false,
|
||||
children: [
|
||||
{
|
||||
id: 31,
|
||||
name: '功能测试',
|
||||
type: 'task',
|
||||
startDate: '2024-03-01',
|
||||
endDate: '2024-03-08',
|
||||
progress: 40,
|
||||
assignee: '吴九',
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
name: '性能优化',
|
||||
type: 'task',
|
||||
startDate: '2024-03-05',
|
||||
endDate: '2024-03-12',
|
||||
progress: 20,
|
||||
assignee: '郑十',
|
||||
},
|
||||
{
|
||||
id: 33,
|
||||
name: '生产部署',
|
||||
type: 'task',
|
||||
startDate: '2024-03-13',
|
||||
endDate: '2024-03-15',
|
||||
progress: 0,
|
||||
assignee: '钱十一',
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const milestones = ref<Task[]>([])
|
||||
|
||||
// Helper function for progress bar background
|
||||
const getProgressColor = (progress: number) => {
|
||||
if (progress >= 100) return '#67c23a'
|
||||
if (progress >= 50) return '#409eff'
|
||||
return '#e6a23c'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="declarative-demo">
|
||||
<h1>声明式列定义演示 (Declarative Columns Demo)</h1>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2>示例 1: 基础声明式列</h2>
|
||||
<GanttChart
|
||||
:tasks="tasks"
|
||||
:milestones="milestones"
|
||||
task-list-column-render-mode="declarative"
|
||||
:show-toolbar="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<TaskListColumn prop="assignee" label="负责人" width="120" align="center" />
|
||||
<TaskListColumn prop="name" label="任务名称" width="300" />
|
||||
|
||||
<TaskListColumn prop="startDate" label="开始日期" width="140" />
|
||||
<TaskListColumn prop="endDate" label="结束日期" width="140" />
|
||||
<TaskListColumn prop="progress" label="进度" width="100" align="center" />
|
||||
</GanttChart>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2>示例 2: 使用默认 Slot 自定义列内容</h2>
|
||||
<GanttChart
|
||||
:tasks="tasks"
|
||||
:milestones="milestones"
|
||||
task-list-column-render-mode="declarative"
|
||||
:show-toolbar="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<TaskListColumn prop="name" label="任务名称" width="300" />
|
||||
|
||||
<!-- 自定义负责人列显示 -->
|
||||
<TaskListColumn prop="assignee" label="负责人" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<div class="assignee-cell">
|
||||
<div class="avatar">
|
||||
{{ scope.row.assignee ? scope.row.assignee.charAt(0).toUpperCase() : '?' }}
|
||||
</div>
|
||||
<span>{{ scope.row.assignee || '未分配' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</TaskListColumn>
|
||||
|
||||
<!-- 自定义进度列显示 -->
|
||||
<TaskListColumn prop="progress" label="进度" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<div class="progress-cell">
|
||||
<div class="progress-bar-container">
|
||||
<div
|
||||
class="progress-bar"
|
||||
:style="{
|
||||
width: `${scope.row.progress || 0}%`,
|
||||
background: getProgressColor(scope.row.progress || 0),
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
<span class="progress-text">{{ scope.row.progress || 0 }}%</span>
|
||||
</div>
|
||||
</template>
|
||||
</TaskListColumn>
|
||||
|
||||
<TaskListColumn prop="startDate" label="开始" width="120" />
|
||||
<TaskListColumn prop="endDate" label="结束" width="120" />
|
||||
</GanttChart>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2>示例 3: 自定义表头</h2>
|
||||
<GanttChart
|
||||
:tasks="tasks"
|
||||
:milestones="milestones"
|
||||
task-list-column-render-mode="declarative"
|
||||
:show-toolbar="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<TaskListColumn prop="name" width="300">
|
||||
<template #header>
|
||||
<div class="header-with-icon">
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-5l-2-2H5a2 2 0 00-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="header-title">任务信息</span>
|
||||
</div>
|
||||
</template>
|
||||
</TaskListColumn>
|
||||
|
||||
<TaskListColumn prop="assignee" width="150">
|
||||
<template #header>
|
||||
<div class="header-success">👤 负责人</div>
|
||||
</template>
|
||||
</TaskListColumn>
|
||||
|
||||
<TaskListColumn prop="progress" width="150">
|
||||
<template #header>
|
||||
<div class="header-warning">📊 完成度</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<span :class="scope.row.progress >= 100 ? 'text-success' : 'text-warning'">
|
||||
{{ scope.row.progress || 0 }}%
|
||||
</span>
|
||||
</template>
|
||||
</TaskListColumn>
|
||||
|
||||
<TaskListColumn prop="startDate" label="开始日期" width="140" />
|
||||
<TaskListColumn prop="endDate" label="结束日期" width="140" />
|
||||
</GanttChart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.declarative-demo {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.demo-section {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.demo-section h2 {
|
||||
color: #409eff;
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.assignee-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background: #409eff;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.progress-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.progress-bar-container {
|
||||
flex: 1;
|
||||
height: 8px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
min-width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.header-with-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-success {
|
||||
color: #67c23a;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-warning {
|
||||
color: #e6a23c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #e6a23c;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -378,5 +378,25 @@
|
||||
"Fixed: Disabled Task drag-and-drop event trigger on double-click",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to @qiuchengw for his professional contribution</span>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.6.0",
|
||||
"date": "2025-12-14",
|
||||
"notes": [
|
||||
"🎉 新增:Task Table列声明式定义方式, 使用组件TaskListColumn",
|
||||
"🎉 新增:Task Table #header和#default Slots",
|
||||
"🎉 新增:Task List行样式设置属性 - task-list-row-class-name和task-list-row-style",
|
||||
"🎉 新增:为兼容旧版本TaskListColumnConfig,提供task-list-column-render-mode属性开关,可以通过设置选择Task表格列定义方式",
|
||||
"🔧 修复:仅删除Story层级后,子Task升级后关系线丢失问题",
|
||||
"🔧 修复:修复已知问题",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">特别感谢 osc_85545913@gitee的使用及反馈</span>",
|
||||
"🎉 Added: Declarative definition method for Task Table columns using the TaskListColumn component",
|
||||
"🎉 Added: Task Table #header and #default Slots",
|
||||
"🎉 Added: Task List row style setting properties - task-list-row-class-name and task-list-row-style",
|
||||
"🎉 Added: A switch for task-list-column-render-mode attribute to choose Task Table column definition method for compatibility with older versions of TaskListColumnConfig",
|
||||
"🔧 Fixed: Issue of missing relationship lines after upgrading child Tasks when only deleting Story",
|
||||
"🔧 Fixed: Fixed issues",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to osc_85545913@gitee for their use and feedback</span>"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user