v1.6.0 - 提供Task列表插槽功能

This commit is contained in:
LINING-PC\lining
2025-12-14 16:06:44 +08:00
parent 70c77316b7
commit c7ea67b4cc
15 changed files with 788 additions and 414 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ const onNo = () => emit('no')
<template v-else>
<button type="button" class="gantt-btn gantt-btn-default" @click="onCancel">
{{ props.cancelText }}
</button>
</button> &nbsp;&nbsp;
<button type="button" class="gantt-btn gantt-btn-danger" @click="onConfirm">
{{ props.confirmText }}
</button>
+1
View File
@@ -1003,6 +1003,7 @@ onUnmounted(() => {
.dialog-actions {
display: flex;
justify-content: center;
gap: 12px;
}
.dialog-actions .btn + .btn {
+21 -16
View File
@@ -4,12 +4,11 @@ import type { StyleValue, Slots } from 'vue'
import TaskRow from './TaskRow.vue'
import { useI18n } from '../composables/useI18n'
import type { Task } from '../models/classes/Task'
import type { TaskListConfig } from '../models/configs/TaskListConfig'
import type { TaskListConfig, TaskListColumnConfig } from '../models/configs/TaskListConfig'
import { DEFAULT_TASK_LIST_COLUMNS } from '../models/configs/TaskListConfig'
import { useTaskRowDrag } from '../composables/useTaskRowDrag'
import { moveTask } from '../utils/taskTreeUtils'
import { useTaskListColumns } from '../composables/useTaskListColumns'
import type { DeclarativeColumnConfig } from '../composables/useTaskListColumns'
interface Props {
tasks?: Task[]
@@ -57,7 +56,7 @@ const columnSlots = inject<Slots>('gantt-column-slots', {})
const { t } = useI18n()
// 使用声明式列管理 composable
const { declarativeColumns, finalColumns, getColumnWidthStyle: getDeclarativeColumnWidth } =
const { declarativeColumns, getColumnWidthStyle: getDeclarativeColumnWidth } =
useTaskListColumns(
props.taskListColumnRenderMode || 'default',
slots,
@@ -125,8 +124,14 @@ const getColumnWidthStyle = (column: { width?: number | string }) => {
}
}
// 计算可见的列配置(已被 columnsToUse 替代,保留以兼容
const visibleColumns = computed(() => columnsToUse.value)
// 计算可见的列配置(仅用于默认模式
const visibleColumns = computed(() => {
if (props.taskListColumnRenderMode === 'declarative') {
return [] as TaskListColumnConfig[] // 声明式模式不需要这个
}
const columns = props.taskListConfig?.columns || DEFAULT_TASK_LIST_COLUMNS
return columns.filter(col => col.visible !== false)
})
// 使用 props.tasks 的引用,不创建副本
// 这样可以直接修改对象,触发响应式更新,不需要外部监听事件
@@ -636,16 +641,16 @@ onUnmounted(() => {
:class="column.cssClass"
:style="{
...getColumnWidthStyle(column),
justifyContent: column.align === 'center' ? 'center' : column.align === 'right' ? 'flex-end' : 'flex-start',
textAlign: column.align || 'left'
justifyContent: (column as any).align === 'center' ? 'center' : (column as any).align === 'right' ? 'flex-end' : 'flex-start',
textAlign: (column as any).align || 'left'
}"
>
<!-- 使用 header slot 或显示 label -->
<template v-if="column.headerSlot">
<component :is="column.headerSlot" />
<template v-if="(column as any).headerSlot">
<component :is="(column as any).headerSlot" />
</template>
<template v-else>
{{ column.label }}
{{ (column as any).label }}
</template>
</div>
</template>
@@ -665,17 +670,17 @@ onUnmounted(() => {
<!-- 可配置的其他列 -->
<div
v-for="column in visibleColumns"
:key="column.key"
:key="(column as TaskListColumnConfig).key"
class="col"
:class="column.cssClass || `col-${column.key}`"
:class="(column as TaskListColumnConfig).cssClass || `col-${(column as TaskListColumnConfig).key}`"
:style="getColumnWidthStyle(column)"
>
<!-- 检查是否有对应的 header-{key} slot -->
<template v-if="columnSlots[`header-${column.key}`]">
<component :is="columnSlots[`header-${column.key}`]" />
<template v-if="columnSlots[`header-${(column as TaskListColumnConfig).key}`]">
<component :is="columnSlots[`header-${(column as TaskListColumnConfig).key}`]" />
</template>
<template v-else>
{{ (t as any)[column.key] || column.label }}
{{ (t as any)[(column as TaskListColumnConfig).key] || (column as TaskListColumnConfig).label }}
</template>
</div>
</template>
@@ -692,7 +697,7 @@ onUnmounted(() => {
:is-hovered="hoveredTaskId === task.id"
:hovered-task-id="hoveredTaskId"
:on-hover="handleTaskRowHover"
:columns="visibleColumns"
:columns="taskListColumnRenderMode === 'declarative' ? [] : visibleColumns"
:declarative-columns="taskListColumnRenderMode === 'declarative' ? columnsToUse : undefined"
:render-mode="taskListColumnRenderMode"
:get-column-width-style="getColumnWidthStyle"
+1 -1
View File
@@ -23,7 +23,7 @@ interface Props {
cssClass?: string
}
const props = withDefaults(defineProps<Props>(), {
withDefaults(defineProps<Props>(), {
align: 'left',
})
+13 -13
View File
@@ -133,10 +133,10 @@ const renderDeclarativeColumn = (
class: ['task-name-text', { 'parent-task': isParentTask.value }],
title: columnValue,
},
column.defaultSlot({
[column.defaultSlot({
row: props.task,
$index: index,
}),
})],
),
])
}
@@ -549,10 +549,10 @@ onUnmounted(() => {
:key="index"
class="col"
:class="[column.cssClass, { 'col-name': isFirstColumn(index) }]"
:style="{
...(getColumnWidthStyle ? getColumnWidthStyle(column) : {}),
...getDeclarativeColumnAlign(column),
}"
:style="[
getColumnWidthStyle ? getColumnWidthStyle(column) : {},
getDeclarativeColumnAlign(column),
]"
>
<!-- 第一列保留 collapse-btn, milestone-spacer, leaf-spacer -->
<div v-if="isFirstColumn(index)"
@@ -630,16 +630,16 @@ onUnmounted(() => {
value: props.task.name,
isParentTask,
hasChildren,
isStoryTask: isStoryTask.value,
isMilestoneGroup: isMilestoneGroup.value,
isMilestoneTask: isMilestoneTask.value,
isStoryTask: isStoryTask,
isMilestoneGroup: isMilestoneGroup,
isMilestoneTask: isMilestoneTask,
showTaskIcon: props.showTaskIcon,
formattedTimer: formattedTimer.value,
formattedTimer: formattedTimer,
isOvertime: isOvertime(),
overdueDays: overdueDays(),
overtimeText: overtimeText.value,
overdueText: overdueText.value,
daysText: daysText.value,
overtimeText: overtimeText,
overdueText: overdueText,
daysText: daysText,
})"
v-if="hasColumnSlot('name')"
/>
+8 -2
View File
@@ -209,7 +209,10 @@ const messages = {
taskListConfig: {
title: 'TaskList 配置',
columns: {
title: '列显示',
title: '列显示(默认渲染模式下生效)',
renderMode: '渲染模式',
renderModeDefault: '默认(通过 TaskListColumnConfig 设置)',
renderModeDeclarative: '声明式(使用 TaskListColumn 设置可见列)',
},
width: {
title: '宽度设置',
@@ -474,7 +477,10 @@ const messages = {
taskListConfig: {
title: 'TaskList Configuration',
columns: {
title: 'Columns',
title: 'Columns(默effective in default render mode)',
renderMode: 'Render Mode',
renderModeDefault: 'Default (via TaskListColumnConfig)',
renderModeDeclarative: 'Declarative (via TaskListColumn)',
},
width: {
title: 'Width Settings',