v1.7.0 - add TaskListContextMenu and TaskBarContextMenu components & slots

This commit is contained in:
LINING-PC\lining
2026-01-10 23:16:56 +08:00
parent 84aabe53d7
commit 396c7b24da
20 changed files with 1338 additions and 151 deletions
+29 -39
View File
@@ -13,6 +13,8 @@ import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'
import type { Task } from '../models/classes/Task'
import type { Milestone } from '../models/classes/Milestone'
import { useTaskListContextMenu } from './TaskList/composables/taskList/useTaskListContextMenu'
import { useTaskBarContextMenu } from './Timeline/composables/useTaskBarContextMenu'
import type { ToolbarConfig } from '../models/configs/ToolbarConfig'
import type { TaskListConfig } from '../models/configs/TaskListConfig'
import {
@@ -54,7 +56,8 @@ const props = withDefaults(defineProps<Props>(), {
assigneeOptions: () => [],
taskListRowClassName: undefined,
taskListRowStyle: undefined,
useDefaultContextMenu: true,
enableTaskListContextMenu: true,
enableTaskBarContextMenu: true,
})
const emit = defineEmits([
@@ -94,29 +97,24 @@ const slots = useSlots()
provide('gantt-column-slots', slots)
// 提供右键菜单配置给子组件
provide('use-default-context-menu', computed(() => props.useDefaultContextMenu))
provide('enable-task-list-context-menu', computed(() => props.enableTaskListContextMenu))
provide('enable-task-bar-context-menu', computed(() => props.enableTaskBarContextMenu))
// 计算是否使用自定义 TaskList 右键菜单
const hasTaskListContextMenuSlot = computed(() => Boolean(slots['task-list-context-menu']))
const shouldUseCustomTaskListContextMenu = computed(() => {
if (!props.useDefaultContextMenu) {
return hasTaskListContextMenuSlot.value
}
return hasTaskListContextMenuSlot.value
})
// 使用声明式右键菜单 composables
const { hasDeclarativeContextMenu: hasDeclarativeTaskListContextMenu, declarativeContextMenu: declarativeTaskListContextMenu } =
useTaskListContextMenu(slots)
const { hasDeclarativeContextMenu: hasDeclarativeTaskBarContextMenu, declarativeContextMenu: declarativeTaskBarContextMenu } =
useTaskBarContextMenu(slots)
// 计算是否使用自定义 TaskBar 右键菜单
const hasTaskBarContextMenuSlot = computed(() => Boolean(slots['task-bar-context-menu']))
const shouldUseCustomTaskBarContextMenu = computed(() => {
if (!props.useDefaultContextMenu) {
return hasTaskBarContextMenuSlot.value
}
return hasTaskBarContextMenuSlot.value
})
// 计算是否使用自定义 TaskList 右键菜单(声明式方式)
const hasTaskListContextMenuSlot = computed(() => hasDeclarativeTaskListContextMenu.value)
provide('task-list-context-menu-slot', hasTaskListContextMenuSlot)
provide('declarative-task-list-context-menu', declarativeTaskListContextMenu)
// 提供右键菜单 slot 给子组件
provide('task-list-context-menu-slot', computed(() => shouldUseCustomTaskListContextMenu.value))
provide('task-bar-context-menu-slot', computed(() => shouldUseCustomTaskBarContextMenu.value))
// 计算是否使用自定义 TaskBar 右键菜单(声明式方式)
const hasTaskBarContextMenuSlot = computed(() => hasDeclarativeTaskBarContextMenu.value)
provide('task-bar-context-menu-slot', hasTaskBarContextMenuSlot)
provide('declarative-task-bar-context-menu', declarativeTaskBarContextMenu)
interface Props {
// 任务数据
@@ -181,10 +179,16 @@ interface Props {
// 任务行自定义样式,支持对象或函数,优先级高于 taskListRowClassName
// 函数形式:(row: Task, rowIndex: number) => StyleValue
taskListRowStyle?: StyleValue | ((row: Task, rowIndex: number) => StyleValue)
// 是否使用默认的右键菜单(默认为 true
// 当设置为 false 时,将关闭内置的 TaskRow 和 TaskBar 右键菜单
// 可以通过 task-list-context-menu 和 task-bar-context-menu 插槽自定义菜单
useDefaultContextMenu?: boolean
// 是否启用 TaskListTaskRow右键菜单(默认为 true
// 当设置为 true 且未声明 TaskListContextMenu 组件时,使用系统默认菜单
// 当设置为 true 且声明了 TaskListContextMenu 组件时,使用自定义菜单
// 当设置为 false 时,无论是否声明组件,TaskRow 右键菜单都失效
enableTaskListContextMenu?: boolean
// 是否启用 TaskBar 右键菜单(默认为 true
// 当设置为 true 且未声明 TaskBarContextMenu 组件时,使用系统默认菜单
// 当设置为 true 且声明了 TaskBarContextMenu 组件时,使用自定义菜单
// 当设置为 false 时,无论是否声明组件,TaskBar 右键菜单都失效
enableTaskBarContextMenu?: boolean
}
// TaskList的固定总长度(所有列的最小宽度之和 + 边框等额外空间)
@@ -2389,13 +2393,6 @@ function handleMilestoneDialogDelete(milestoneId: number) {
<template v-if="$slots['custom-task-content']" #custom-task-content="rowScope">
<slot name="custom-task-content" v-bind="rowScope" />
</template>
<!-- 传递 task-list-context-menu slot -->
<template
v-if="$slots['task-list-context-menu']"
#task-list-context-menu="contextMenuScope"
>
<slot name="task-list-context-menu" v-bind="contextMenuScope" />
</template>
</TaskList>
</div>
<div class="gantt-splitter" @mousedown="onMouseDown">
@@ -2454,13 +2451,6 @@ function handleMilestoneDialogDelete(milestoneId: number) {
<template v-if="$slots['custom-task-content']" #custom-task-content="barScope">
<slot name="custom-task-content" v-bind="barScope" />
</template>
<!-- 传递 task-bar-context-menu slot -->
<template
v-if="$slots['task-bar-context-menu']"
#task-bar-context-menu="contextMenuScope"
>
<slot name="task-bar-context-menu" v-bind="contextMenuScope" />
</template>
</Timeline>
<!-- 关闭聚焦按钮 - 固定在gantt-panel-right底部居中 -->