jordium-gantt-vue3
Version:
A Vue 3 Gantt chart component for project management, task scheduling, resource planning, calendar, resource usage and timeline visualization.
421 lines (420 loc) • 17.6 kB
TypeScript
import { StyleValue } from 'vue';
import { default as CalendarView } from './Calendar/CalendarView.vue';
import { default as ResourceUsageView } from './ResourceUsage/ResourceUsageView.vue';
import { Task } from '../models/classes/Task';
import { Milestone } from '../models/classes/Milestone';
import { Resource, ResourceTypeOption } from '../models/classes/Resource';
import { ToolbarConfig } from '../models/configs/ToolbarConfig';
import { TaskListConfig } from '../models/configs/TaskListConfig';
import { ResourceListConfig } from '../models/configs/ResourceListConfig';
import { TaskBarConfig, LinkConfig } from '../models/configs/TaskBarConfig';
import { TimelineScale } from '../models/types/TimelineScale';
interface Props {
tasks?: Task[];
milestones?: Task[];
resources?: Resource[];
viewMode?: 'task' | 'resource' | 'calendar' | 'resource-usage';
availableViewModes?: Array<'task' | 'resource' | 'calendar' | 'resource-usage'>;
useDefaultDrawer?: boolean;
useDefaultMilestoneDialog?: boolean;
toolbarConfig?: ToolbarConfig;
showToolbar?: boolean;
onTodayLocate?: () => void;
onExportCsv?: () => boolean | void;
onExportPdf?: () => void;
onLanguageChange?: (lang: 'zh-CN' | 'en-US') => void;
onThemeChange?: (isDark: boolean) => void;
onFullscreenChange?: (isFullscreen: boolean) => void;
onSettingsConfirm?: (type: 'theme' | 'language', value: string | boolean) => Promise<boolean> | boolean;
onExpandAll?: () => void;
onCollapseAll?: () => void;
/**
* 自定义多语言(国际化)配置,支持多语言扩展。
* 例如:
* localeMessages={{
* 'zh-CN': { department: '部门', departmentCode: '部门编号' },
* 'en-US': { department: 'Department', departmentCode: 'Department Code' }
* }}
* 支持嵌套对象(如 csvHeaders、taskTypeMap 等)。
* 仅在组件初始化时合并,运行时变更会自动响应。
*/
localeMessages?: Partial<{
'zh-CN'?: Partial<import('../composables/useI18n').Messages['zh-CN']>;
'en-US'?: Partial<import('../composables/useI18n').Messages['en-US']>;
}>;
workingHours?: {
morning?: {
start: number;
end: number;
};
afternoon?: {
start: number;
end: number;
};
};
taskListConfig?: TaskListConfig;
resourceListConfig?: ResourceListConfig;
calendarProps?: Partial<InstanceType<typeof CalendarView>['$props']>;
resourceUsageProps?: Partial<InstanceType<typeof ResourceUsageView>['$props']>;
taskListColumnRenderMode?: 'default' | 'declarative';
taskBarConfig?: TaskBarConfig;
autoSortByStartDate?: boolean;
allowDragAndResize?: boolean;
enableTaskRowMove?: boolean;
assigneeOptions?: Array<{
key?: string | number;
value: string | number;
label: string;
}>;
resourceTypeOptions?: ResourceTypeOption[];
showResourceTypeOption?: boolean;
taskListRowClassName?: string | ((row: Task, rowIndex: number) => string);
taskListRowStyle?: StyleValue | ((row: Task, rowIndex: number) => StyleValue);
enableTaskListContextMenu?: boolean;
enableTaskBarContextMenu?: boolean;
enableLinkAnchor?: boolean;
enableTaskBarTooltip?: boolean;
enableMilestoneTooltip?: boolean;
milestoneLabelPosition?: 'left' | 'top' | 'right' | 'bottom';
showActualTaskbar?: boolean;
showConflicts?: boolean;
showTaskbarTab?: boolean;
taskbarDescFixed?: boolean;
pendingTaskBackgroundColor?: string;
delayTaskBackgroundColor?: string;
completeTaskBackgroundColor?: string;
ongoingTaskBackgroundColor?: string;
fullscreen?: boolean;
expandAll?: boolean;
locale?: 'zh-CN' | 'en-US';
timeScale?: TimelineScale;
theme?: 'light' | 'dark';
/**
* 是否允许 TaskList 展开/收起功能(默认为 true)
* 当设置为 false 时,TaskList 面板强制隐藏,SplitterBar 及折叠按钮同步隐藏,仅展示 Timeline 区域
* taskListVisible 在此情况下失效
*/
enableTaskListCollapsible?: boolean;
/**
* TaskList 可见状态(响应式),默认为 true
* 仅当 enableTaskListCollapsible=true 时有效
* 可通过 prop 传入或通过 defineExpose 暴露的方法控制
*/
taskListVisible?: boolean;
/**
* 是否允许点击遮罩层关闭 TaskDrawer,默认为 true(保持原有行为)
* 设置为 false 可防止 TaskDrawer 在失去焦点(点击遮罩区域)时自动关闭
* 仅在 useDefaultDrawer=true 时有效
*/
enableTaskDrawerAutoClose?: boolean;
/**
* 自定义各刻度配置,支持覆盖 cellWidth / preBuffer / sufBuffer / formatter。
* 仅需传入需要覆盖的刻度,未传入的刻度继续使用内置默认值。
* formatter.primary / formatter.secondary 为格式化字符串,支持 token:
* yyyy / MM / M / dd / d / HH / mm / Q / W
*/
scaleConfigs?: Partial<Record<TimelineScale, Partial<{
cellWidth: number;
preBuffer: number;
sufBuffer: number;
formatter: {
primary: string;
secondary?: string;
};
}>>>;
/**
* 任务行高度(px),同时影响 Timeline 和 TaskList 行高,默认 51px。
* 最小值为 40,否则 TaskBar 可能溢出行高。
*/
rowHeight?: number;
/**
* 父级任务自动调度(默认为 true)
* true:父级 TaskBar 自动跟随子任务最早开始/最晚结束日期
* false:父级 TaskBar 保持自身设定日期;子任务溢出时显示2px红色指示条
*/
enableParentTaskAutoSchedule?: boolean;
/**
* 资源视图车道堆叠模式(默认为 true)v1.12.0
* true:启用贪心车道堆叠——时间不重叠的任务共享同一行,最大化空间利用率
* false:禁用堆叠——每个任务独占一行,适合任务密集、需要清晰辨识的场景
*/
enableResourceLaneStacking?: boolean;
/** R1: 连线样式配置 */
linkConfig?: LinkConfig;
}
declare var __VLS_38: {}, __VLS_55: {}, __VLS_57: {
isRowContent: boolean;
task: Task;
level: number;
indent: string;
isHovered: boolean;
hoveredTaskId: number | string | null;
isParent: boolean;
hasChildren: boolean;
collapsed: boolean;
formattedTimer: string;
timerRunning: boolean;
timerElapsed: number;
isOvertime: number | boolean | undefined;
overdueDays: number;
overtimeText: string;
overdueText: string;
daysText: string;
progressClass: string;
type?: string;
}, __VLS_80: {
type: string;
task: Task;
status: import('./TaskBar.vue').TaskStatus;
statusType: string;
isParent?: boolean;
progress: number;
currentTimeScale?: TimelineScale;
rowHeight: number;
dayWidth: number;
}, __VLS_82: {
task: any;
taskStatus: {
color: string;
label: string;
type?: string | undefined;
};
resourcePercent: number;
}, __VLS_84: {
milestone: {
id?: number | undefined;
name: string;
startDate: string;
endDate?: string | undefined;
assignee?: string | string[] | undefined;
assigneeName?: string | string[] | undefined;
avatar?: string | string[] | undefined;
type: string;
icon?: string | undefined;
description?: string | undefined;
} | null;
}, __VLS_86: {
milestone: Milestone;
task: Task;
rowHeight: number;
dayWidth: number;
currentTimeScale?: TimelineScale | null;
labelPosition: "right" | "left" | "top" | "bottom";
};
type __VLS_Slots = {} & {
default?: (props: typeof __VLS_38) => any;
} & {
default?: (props: typeof __VLS_55) => any;
} & {
'custom-task-content'?: (props: typeof __VLS_57) => any;
} & {
'custom-task-content'?: (props: typeof __VLS_80) => any;
} & {
'taskbar-tooltip'?: (props: typeof __VLS_82) => any;
} & {
'milestone-tooltip'?: (props: typeof __VLS_84) => any;
} & {
'custom-milestone-content'?: (props: typeof __VLS_86) => any;
};
declare const __VLS_component: import('vue').DefineComponent<Props, {
enterFullscreen: () => void;
exitFullscreen: () => void;
toggleFullscreen: () => void;
isFullscreen: () => boolean;
expandAll: () => void;
collapseAll: () => void;
toggleExpandAll: () => void;
isExpandAll: () => boolean;
scrollToToday: () => void;
scrollToTask: (taskId: string | number) => void;
scrollToDate: (date: Date | string) => void;
setLocale: (locale: "zh-CN" | "en-US") => void;
currentLocale: () => string;
setTimeScale: (scale?: TimelineScale) => void;
zoomIn: () => void;
zoomOut: () => void;
currentScale: () => string;
setTheme: (mode?: "light" | "dark") => void;
currentTheme: () => string;
/** 获取 TaskList 当前可见状态 */
getTaskListVisible: () => boolean;
/**
* 设置 TaskList 可见状态(仅在 enableTaskListCollapsible=true 时生效)
* @param visible true=展开,false=收起
*/
setTaskListVisible: (visible: boolean) => void;
/** 切换 TaskList 展开/收起(仅在 enableTaskListCollapsible=true 时生效,带动画) */
toggleTaskList: () => void;
/**
* 动态设置连线样式配置(与 props.linkConfig 合并,运行时调用优先级更高)
* @example ganttRef.value.setLinkConfig({ type: 'orthogonal', color: '#ff0000' })
*/
setLinkConfig: (config: Partial<LinkConfig>) => void;
/**
* 获取当前生效的完整连线配置(合并 DEFAULT + props + setLinkConfig)
*/
getLinkConfig: () => Required<LinkConfig>;
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
"add-predecessor": (...args: any[]) => void;
"add-successor": (...args: any[]) => void;
"task-updated": (...args: any[]) => void;
"task-added": (...args: any[]) => void;
"milestone-icon-changed": (...args: any[]) => void;
"task-collapse-change": (...args: any[]) => void;
"task-row-moved": (...args: any[]) => void;
"milestone-double-click": (...args: any[]) => void;
"predecessor-added": (...args: any[]) => void;
"successor-added": (...args: any[]) => void;
"link-deleted": (...args: any[]) => void;
"resource-drag-end": (...args: any[]) => void;
"taskbar-drag-end": (...args: any[]) => void;
"taskbar-resize-end": (...args: any[]) => void;
"milestone-drag-end": (...args: any[]) => void;
"add-task": (...args: any[]) => void;
"add-milestone": (...args: any[]) => void;
"task-click": (...args: any[]) => void;
"task-double-click": (...args: any[]) => void;
"timer-started": (...args: any[]) => void;
"timer-stopped": (...args: any[]) => void;
"task-deleted": (...args: any[]) => void;
"view-mode-changed": (...args: any[]) => void;
"milestone-saved": (...args: any[]) => void;
"milestone-deleted": (...args: any[]) => void;
"taskbar-resource-change": (...args: any[]) => void;
"calendar-selection-complete": (...args: any[]) => void;
"calendar-selection-cancel": (...args: any[]) => void;
"calendar-resource-change": (...args: any[]) => void;
"calendar-view-change": (...args: any[]) => void;
"calendar-date-change": (...args: any[]) => void;
"calendar-task-click": (...args: any[]) => void;
"calendar-task-move": (...args: any[]) => void;
"resource-usage-scale-change": (...args: any[]) => void;
"resource-usage-cell-click": (...args: any[]) => void;
"resource-usage-cell-hover": (...args: any[]) => void;
"resource-usage-overload-detected": (...args: any[]) => void;
"resource-usage-task-detail-click": (...args: any[]) => void;
}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
"onAdd-predecessor"?: ((...args: any[]) => any) | undefined;
"onAdd-successor"?: ((...args: any[]) => any) | undefined;
"onTask-updated"?: ((...args: any[]) => any) | undefined;
"onTask-added"?: ((...args: any[]) => any) | undefined;
"onMilestone-icon-changed"?: ((...args: any[]) => any) | undefined;
"onTask-collapse-change"?: ((...args: any[]) => any) | undefined;
"onTask-row-moved"?: ((...args: any[]) => any) | undefined;
"onMilestone-double-click"?: ((...args: any[]) => any) | undefined;
"onPredecessor-added"?: ((...args: any[]) => any) | undefined;
"onSuccessor-added"?: ((...args: any[]) => any) | undefined;
"onLink-deleted"?: ((...args: any[]) => any) | undefined;
"onResource-drag-end"?: ((...args: any[]) => any) | undefined;
"onTaskbar-drag-end"?: ((...args: any[]) => any) | undefined;
"onTaskbar-resize-end"?: ((...args: any[]) => any) | undefined;
"onMilestone-drag-end"?: ((...args: any[]) => any) | undefined;
"onAdd-task"?: ((...args: any[]) => any) | undefined;
"onAdd-milestone"?: ((...args: any[]) => any) | undefined;
"onTask-click"?: ((...args: any[]) => any) | undefined;
"onTask-double-click"?: ((...args: any[]) => any) | undefined;
"onTimer-started"?: ((...args: any[]) => any) | undefined;
"onTimer-stopped"?: ((...args: any[]) => any) | undefined;
"onTask-deleted"?: ((...args: any[]) => any) | undefined;
"onView-mode-changed"?: ((...args: any[]) => any) | undefined;
"onMilestone-saved"?: ((...args: any[]) => any) | undefined;
"onMilestone-deleted"?: ((...args: any[]) => any) | undefined;
"onTaskbar-resource-change"?: ((...args: any[]) => any) | undefined;
"onCalendar-selection-complete"?: ((...args: any[]) => any) | undefined;
"onCalendar-selection-cancel"?: ((...args: any[]) => any) | undefined;
"onCalendar-resource-change"?: ((...args: any[]) => any) | undefined;
"onCalendar-view-change"?: ((...args: any[]) => any) | undefined;
"onCalendar-date-change"?: ((...args: any[]) => any) | undefined;
"onCalendar-task-click"?: ((...args: any[]) => any) | undefined;
"onCalendar-task-move"?: ((...args: any[]) => any) | undefined;
"onResource-usage-scale-change"?: ((...args: any[]) => any) | undefined;
"onResource-usage-cell-click"?: ((...args: any[]) => any) | undefined;
"onResource-usage-cell-hover"?: ((...args: any[]) => any) | undefined;
"onResource-usage-overload-detected"?: ((...args: any[]) => any) | undefined;
"onResource-usage-task-detail-click"?: ((...args: any[]) => any) | undefined;
}>, {
expandAll: boolean;
fullscreen: boolean;
taskListConfig: TaskListConfig;
taskBarConfig: TaskBarConfig;
locale: "zh-CN" | "en-US";
tasks: Task[];
resources: Resource[];
taskListRowClassName: string | ((row: Task, rowIndex: number) => string);
taskListRowStyle: string | false | import('vue').CSSProperties | StyleValue[] | ((row: Task, rowIndex: number) => StyleValue) | null;
viewMode: "task" | "resource" | "calendar" | "resource-usage";
rowHeight: number;
enableParentTaskAutoSchedule: boolean;
useDefaultDrawer: boolean;
taskListColumnRenderMode: "default" | "declarative";
enableTaskRowMove: boolean;
allowDragAndResize: boolean;
showActualTaskbar: boolean;
enableTaskBarTooltip: boolean;
enableLinkAnchor: boolean;
showTaskbarTab: boolean;
milestones: Task[];
useDefaultMilestoneDialog: boolean;
workingHours: {
morning?: {
start: number;
end: number;
};
afternoon?: {
start: number;
end: number;
};
};
enableMilestoneTooltip: boolean;
milestoneLabelPosition: "left" | "top" | "right" | "bottom";
scaleConfigs: Partial<Record<TimelineScale, Partial<{
cellWidth: number;
preBuffer: number;
sufBuffer: number;
formatter: {
primary: string;
secondary?: string;
};
}>>>;
showConflicts: boolean;
timeScale: TimelineScale;
theme: "light" | "dark";
onTodayLocate: () => void;
onExportCsv: () => boolean | void;
onExportPdf: () => void;
onLanguageChange: (lang: "zh-CN" | "en-US") => void;
onThemeChange: (isDark: boolean) => void;
onFullscreenChange: (isFullscreen: boolean) => void;
onExpandAll: () => void;
onCollapseAll: () => void;
onSettingsConfirm: (type: "theme" | "language", value: string | boolean) => Promise<boolean> | boolean;
assigneeOptions: Array<{
key?: string | number;
value: string | number;
label: string;
}>;
resourceTypeOptions: ResourceTypeOption[];
showResourceTypeOption: boolean;
resourceListConfig: ResourceListConfig;
toolbarConfig: ToolbarConfig;
showToolbar: boolean;
localeMessages: Partial<{
"zh-CN"?: Partial<import('../composables/useI18n').Messages["zh-CN"]>;
"en-US"?: Partial<import('../composables/useI18n').Messages["en-US"]>;
}>;
autoSortByStartDate: boolean;
enableTaskListContextMenu: boolean;
enableTaskBarContextMenu: boolean;
taskbarDescFixed: boolean;
enableTaskListCollapsible: boolean;
taskListVisible: boolean;
enableTaskDrawerAutoClose: boolean;
enableResourceLaneStacking: boolean;
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
export default _default;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};