diff --git a/demo/App.vue b/demo/App.vue index 288e87c..747e26a 100644 --- a/demo/App.vue +++ b/demo/App.vue @@ -13,6 +13,7 @@ import { useMessage } from '../src/composables/useMessage' import { useI18n } from '../src/composables/useI18n' import { getPredecessorIds, predecessorIdsToString } from '../src/utils/predecessorUtils' import type { Task } from '../src/models/Task' +import type { TaskListConfig, TaskListColumnConfig } from '../src/models/configs/TaskListConfig' const { showMessage } = useMessage() const { t, formatTranslation } = useI18n() @@ -41,6 +42,36 @@ const toolbarConfig = { timeScaleDimensions: ['hour', 'day', 'week', 'month', 'quarter', 'year'], // 设置时间刻度按钮的展示维度,包含所有时间维度 } +// TaskList列配置 +const availableColumns = ref([ + { key: 'predecessor', label: '前置任务', visible: true }, + { key: 'assignee', label: '负责人', visible: true }, + { key: 'startDate', label: '开始日期', visible: true }, + { key: 'endDate', label: '结束日期', visible: true }, + { key: 'estimatedHours', label: '预估工时', visible: true }, + { key: 'actualHours', label: '实际工时', visible: true }, + { key: 'progress', label: '进度', visible: true }, +]) + +const taskListConfig = ref({ + columns: availableColumns.value, +}) + +// 切换列显示状态 +const toggleColumn = (columnKey: string, event: Event) => { + const target = event.target as HTMLInputElement + const visible = target?.checked ?? false + + const column = availableColumns.value.find(col => col.key === columnKey) + if (column) { + column.visible = visible + // 更新taskListConfig以触发响应式更新 + taskListConfig.value = { + columns: [...availableColumns.value], + } + } +} + // 工作时间配置示例 const workingHoursConfig = { morning: { start: 8, end: 11 }, // 上午8:00-11:59为工作时间 @@ -632,11 +663,34 @@ function onTimerStopped(task: Task) { + + +
+

+ + + + + TaskList 列配置 +

+
+ +
+
+
+import { ref, reactive } from 'vue' +import { GanttChart } from '../src/index' +import type { Task } from '../src/models/classes/Task' +import type { TaskListConfig, TaskListColumnConfig } from '../src/models/configs/TaskListConfig' + +// 示例任务数据 +const tasks = ref([ + { + id: 1, + name: '项目启动', + startDate: '2024-01-15', + endDate: '2024-01-20', + progress: 100, + assignee: '张三', + estimatedHours: 40, + actualHours: 35, + predecessor: null, + type: 'task', + }, + { + id: 2, + name: '需求分析', + startDate: '2024-01-21', + endDate: '2024-01-30', + progress: 80, + assignee: '李四', + estimatedHours: 80, + actualHours: 75, + predecessor: [1], + type: 'task', + }, + { + id: 3, + name: '系统设计', + startDate: '2024-02-01', + endDate: '2024-02-15', + progress: 60, + assignee: '王五', + estimatedHours: 120, + actualHours: 90, + predecessor: [3], + type: 'task', + }, + { + id: 4, + name: '开发实现', + startDate: '2024-02-16', + endDate: '2024-03-30', + progress: 30, + assignee: '赵六', + estimatedHours: 200, + actualHours: 80, + predecessor: [3], + type: 'task', + }, +] as Task[]) + +// 可用的列配置 +const availableColumns = reactive([ + { key: 'predecessor', label: '前置任务', visible: true }, + { key: 'assignee', label: '负责人', visible: true }, + { key: 'startDate', label: '开始日期', visible: true }, + { key: 'endDate', label: '结束日期', visible: true }, + { key: 'estimatedHours', label: '预估工时', visible: true }, + { key: 'actualHours', label: '实际工时', visible: true }, + { key: 'progress', label: '进度', visible: true }, +]) + +// 任务列表配置 +const taskListConfig = reactive({ + columns: availableColumns, +}) + +// 切换列显示状态 +const toggleColumn = (columnKey: string, visible: boolean) => { + const column = availableColumns.find(col => col.key === columnKey) + if (column) { + column.visible = visible + } +} + + + +import { ref, reactive } from 'vue' +import { GanttChart } from '../src/index' +import type { Task } from '../src/models/classes/Task' +import type { TaskListConfig, TaskListColumnConfig } from '../src/models/configs/TaskListConfig' + +// 示例任务数据 +const tasks = ref([ + { + id: 1, + name: '项目启动', + startDate: '2024-01-15', + endDate: '2024-01-20', + progress: 100, + assignee: '张三', + estimatedHours: 40, + actualHours: 35, + predecessor: null, + type: 'task' + }, + { + id: 2, + name: '需求分析', + startDate: '2024-01-21', + endDate: '2024-01-30', + progress: 80, + assignee: '李四', + estimatedHours: 80, + actualHours: 75, + predecessor: [1], + type: 'task' + }, + { + id: 3, + name: '系统设计', + startDate: '2024-02-01', + endDate: '2024-02-15', + progress: 60, + assignee: '王五', + estimatedHours: 120, + actualHours: 90, + predecessor: [2], + type: 'task' + }, + { + id: 4, + name: '开发实现', + startDate: '2024-02-16', + endDate: '2024-03-30', + progress: 30, + assignee: '赵六', + estimatedHours: 200, + actualHours: 80, + predecessor: [3], + type: 'task' + } +] as Task[]) + +// 可用的列配置 +const availableColumns = reactive([ + { key: 'predecessor', label: '前置任务', visible: true }, + { key: 'assignee', label: '负责人', visible: true }, + { key: 'startDate', label: '开始日期', visible: true }, + { key: 'endDate', label: '结束日期', visible: true }, + { key: 'estimatedHours', label: '预估工时', visible: true }, + { key: 'actualHours', label: '实际工时', visible: true }, + { key: 'progress', label: '进度', visible: true } +]) + +// 任务列表配置 +const taskListConfig = reactive({ + columns: availableColumns +}) + +// 切换列显示状态 +const toggleColumn = (columnKey: string, visible: boolean) => { + const column = availableColumns.find(col => col.key === columnKey) + if (column) { + column.visible = visible + } +} + + + diff --git a/demo/test-result.html b/demo/test-result.html new file mode 100644 index 0000000..4c6ca45 --- /dev/null +++ b/demo/test-result.html @@ -0,0 +1,78 @@ + + + + + + TaskList 列配置演示 + + +
+ + + diff --git a/src/components/GanttChart.vue b/src/components/GanttChart.vue index 55c477a..72e725e 100644 --- a/src/components/GanttChart.vue +++ b/src/components/GanttChart.vue @@ -11,6 +11,7 @@ import html2canvas from 'html2canvas' import type { Task } from '../models/classes/Task' import type { Milestone } from '../models/classes/Milestone' import type { ToolbarConfig } from '../models/configs/ToolbarConfig' +import type { TaskListConfig } from '../models/configs/TaskListConfig' import { TimelineScale } from '../models/types/TimelineScale' import { useMessage } from '../composables/useMessage' @@ -41,6 +42,7 @@ const props = withDefaults(defineProps(), { morning: { start: 8, end: 11 }, afternoon: { start: 13, end: 17 }, }), + taskListConfig: undefined, }) const emit = defineEmits([ @@ -107,6 +109,8 @@ interface Props { morning?: { start: number; end: number } // 上午工作时间,如 { start: 8, end: 11 } afternoon?: { start: number; end: number } // 下午工作时间,如 { start: 13, end: 17 } } + // 任务列表配置 + taskListConfig?: TaskListConfig } const leftPanelWidth = ref(320) @@ -1539,6 +1543,7 @@ function handleTaskDelete(task: Task, deleteChildren?: boolean) { :on-task-double-click="props.onTaskDoubleClick" :edit-component="props.editComponent" :use-default-drawer="props.useDefaultDrawer" + :task-list-config="props.taskListConfig" @task-collapse-change="handleTaskCollapseChange" @start-timer="handleStartTimer" @stop-timer="handleStopTimer" diff --git a/src/components/TaskList.vue b/src/components/TaskList.vue index 572ea6e..cad7656 100644 --- a/src/components/TaskList.vue +++ b/src/components/TaskList.vue @@ -4,12 +4,15 @@ import type { Component } 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 { DEFAULT_TASK_LIST_COLUMNS } from '../models/configs/TaskListConfig' interface Props { tasks?: Task[] onTaskDoubleClick?: (task: Task) => void editComponent?: Component useDefaultDrawer?: boolean + taskListConfig?: TaskListConfig } const props = defineProps() @@ -33,6 +36,18 @@ const hasRowSlot = computed(() => Boolean(slots['custom-task-content'])) // 多语言支持 const { t } = useI18n() +// 计算可见的列配置 +const visibleColumns = computed(() => { + const columns = props.taskListConfig?.columns || DEFAULT_TASK_LIST_COLUMNS + const showAllColumns = props.taskListConfig?.showAllColumns ?? true + + if (!showAllColumns) { + return columns.filter(col => col.visible !== false) + } + + return columns +}) + // 内部响应式任务列表 const localTasks = ref([]) @@ -385,14 +400,15 @@ onUnmounted(() => {