v1.4.1 - 修复TaskList组件自定义列及数据绑定问题 & SonarQube安全弱点修复
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.4.1] - 2025-10-26
|
||||
|
||||
### Fixed
|
||||
- TaskList客制化列展示问题修复
|
||||
- TaskList客制化列数据动态绑定问题修复
|
||||
- SonarQube代码质量检查问题修改
|
||||
- MTaskList Custom Column Display Issue Fix
|
||||
- TaskList Custom Column Data Dynamic Binding Issue Fix
|
||||
- SonarQube code quality inspection issue modification
|
||||
|
||||
## [1.4.0] - 2025-10-11
|
||||
|
||||
### Added
|
||||
|
||||
@@ -53,6 +53,7 @@ const availableColumns = ref<TaskListColumnConfig[]>([
|
||||
{ key: 'estimatedHours', label: '预估工时', visible: true },
|
||||
{ key: 'actualHours', label: '实际工时', visible: true },
|
||||
{ key: 'progress', label: '进度', visible: true },
|
||||
{ key: 'custom', label: '自定义列', visible: true, width: 120 }, // 添加默认宽度120px
|
||||
])
|
||||
|
||||
// TaskList宽度配置
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"actualHours": 3942.75,
|
||||
"type": "story",
|
||||
"description": "ADX-2024新药完整临床试验计划,从I期到III期临床试验",
|
||||
"custom": 180000,
|
||||
"children": [
|
||||
{
|
||||
"id": 1100,
|
||||
@@ -24,6 +25,7 @@
|
||||
"type": "story",
|
||||
"parentId": 1000,
|
||||
"description": "评估ADX-2024在健康志愿者和患者中的安全性、耐受性和药代动力学特征",
|
||||
"custom": "test11111",
|
||||
"children": [
|
||||
{
|
||||
"id": 1101,
|
||||
@@ -36,7 +38,8 @@
|
||||
"actualHours": 480,
|
||||
"type": "task",
|
||||
"parentId": 1100,
|
||||
"description": "完成I期试验方案设计、伦理委员会审批及监管部门申报"
|
||||
"description": "完成I期试验方案设计、伦理委员会审批及监管部门申报",
|
||||
"custom": "test11111"
|
||||
},
|
||||
{
|
||||
"id": 1102,
|
||||
@@ -50,7 +53,8 @@
|
||||
"type": "task",
|
||||
"predecessor": [1101],
|
||||
"parentId": 1100,
|
||||
"description": "招募24名健康志愿者,完成医学筛选和入组评估"
|
||||
"description": "招募24名健康志愿者,完成医学筛选和入组评估",
|
||||
"custom": "test11111"
|
||||
},
|
||||
{
|
||||
"id": 1103,
|
||||
@@ -64,7 +68,8 @@
|
||||
"type": "task",
|
||||
"predecessor": [1102],
|
||||
"parentId": 1100,
|
||||
"description": "按照剂量递增方案给药,密切监测不良反应和药代动力学参数"
|
||||
"description": "按照剂量递增方案给药,密切监测不良反应和药代动力学参数",
|
||||
"custom": "test11111"
|
||||
}
|
||||
],
|
||||
"collapsed": false
|
||||
@@ -81,6 +86,7 @@
|
||||
"type": "story",
|
||||
"parentId": 1000,
|
||||
"description": "在目标患者群体中评估ADX-2024的初步疗效和进一步的安全性",
|
||||
"custom": "test11111",
|
||||
"children": [
|
||||
{
|
||||
"id": 1201,
|
||||
@@ -94,7 +100,8 @@
|
||||
"type": "task",
|
||||
"predecessor": [1103],
|
||||
"parentId": 1200,
|
||||
"description": "启动5个临床中心,完成研究者培训和质量体系建立"
|
||||
"description": "启动5个临床中心,完成研究者培训和质量体系建立",
|
||||
"custom": "test11111"
|
||||
},
|
||||
{
|
||||
"id": 1202,
|
||||
@@ -108,7 +115,8 @@
|
||||
"type": "task",
|
||||
"predecessor": [1201],
|
||||
"parentId": 1200,
|
||||
"description": "计划入组120名患者,采用双盲随机对照设计"
|
||||
"description": "计划入组120名患者,采用双盲随机对照设计",
|
||||
"custom": "test11111"
|
||||
},
|
||||
{
|
||||
"id": 1203,
|
||||
@@ -122,7 +130,8 @@
|
||||
"type": "task",
|
||||
"predecessor": [1202],
|
||||
"parentId": 1200,
|
||||
"description": "定期评估患者疗效指标,收集安全性数据,进行中期分析"
|
||||
"description": "定期评估患者疗效指标,收集安全性数据,进行中期分析",
|
||||
"custom": "test11111"
|
||||
}
|
||||
],
|
||||
"collapsed": false
|
||||
|
||||
@@ -216,5 +216,19 @@
|
||||
"<span style=\"font-weight: bold; color: #f00;\">特别感谢贡献者 @qiuchengw</span>",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to contributor @qiuchengw</span>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.4.1",
|
||||
"date": "2025-10-26",
|
||||
"notes": [
|
||||
"TaskList客制化列展示问题修复",
|
||||
"TaskList Custom Column Display Issue Fix",
|
||||
"TaskList客制化列数据动态绑定问题修复",
|
||||
"TaskList Custom Column Data Dynamic Binding Issue Fix",
|
||||
"SonarQube代码质量检查问题修改",
|
||||
"SonarQube code quality inspection issue modification",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">特别感谢 @Guduxwa</span>",
|
||||
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to @Guduxwa</span>"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jordium-gantt-vue3",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"type": "module",
|
||||
"main": "dist/jordium-gantt-vue3.cjs.js",
|
||||
"module": "dist/jordium-gantt-vue3.es.js",
|
||||
|
||||
@@ -244,13 +244,13 @@ const taskBarStyle = computed(() => {
|
||||
const startDateOnly = new Date(
|
||||
startDate.getFullYear(),
|
||||
startDate.getMonth(),
|
||||
startDate.getDate()
|
||||
startDate.getDate(),
|
||||
)
|
||||
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate())
|
||||
const baseStartOnly = new Date(
|
||||
baseStart.getFullYear(),
|
||||
baseStart.getMonth(),
|
||||
baseStart.getDate()
|
||||
baseStart.getDate(),
|
||||
)
|
||||
|
||||
if (props.currentTimeScale === TimelineScale.YEAR) {
|
||||
@@ -272,7 +272,7 @@ const taskBarStyle = computed(() => {
|
||||
const startPosition = calculatePositionFromTimelineData(
|
||||
startDateOnly,
|
||||
props.timelineData,
|
||||
props.currentTimeScale
|
||||
props.currentTimeScale,
|
||||
)
|
||||
// 计算结束位置:为结束日期添加一天来获取正确的结束位置
|
||||
const nextDay = new Date(endDateOnly)
|
||||
@@ -280,7 +280,7 @@ const taskBarStyle = computed(() => {
|
||||
let endPosition = calculatePositionFromTimelineData(
|
||||
nextDay,
|
||||
props.timelineData,
|
||||
props.currentTimeScale
|
||||
props.currentTimeScale,
|
||||
)
|
||||
|
||||
// 如果结束日期+1天超出范围,使用结束日期的位置+一天的宽度
|
||||
@@ -295,7 +295,7 @@ const taskBarStyle = computed(() => {
|
||||
calculatePositionFromTimelineData(
|
||||
endDateOnly,
|
||||
props.timelineData,
|
||||
props.currentTimeScale
|
||||
props.currentTimeScale,
|
||||
) + dayWidth
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ const taskBarStyle = computed(() => {
|
||||
} else {
|
||||
// 日视图:基于日期的简单计算
|
||||
const startDiff = Math.floor(
|
||||
(startDateOnly.getTime() - baseStartOnly.getTime()) / (1000 * 60 * 60 * 24)
|
||||
(startDateOnly.getTime() - baseStartOnly.getTime()) / (1000 * 60 * 60 * 24),
|
||||
)
|
||||
|
||||
// 计算持续天数(基于日期,忽略时间)
|
||||
@@ -501,7 +501,7 @@ const handleMouseMove = (e: MouseEvent) => {
|
||||
mouseX: e.clientX,
|
||||
isDragging: isDragging.value || isResizingLeft.value || isResizingRight.value,
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
// 更新拖拽提示框位置
|
||||
@@ -766,7 +766,7 @@ const handleMouseMove = (e: MouseEvent) => {
|
||||
const newDurationDays = newWidth / props.dayWidth
|
||||
const newEndDate = addDaysToLocalDate(
|
||||
props.startDate,
|
||||
resizeStartLeft.value / props.dayWidth + newDurationDays - 1
|
||||
resizeStartLeft.value / props.dayWidth + newDurationDays - 1,
|
||||
)
|
||||
|
||||
// 只更新临时数据,不触发事件
|
||||
@@ -798,7 +798,7 @@ const handleMouseUp = () => {
|
||||
mouseX: 0,
|
||||
isDragging: false,
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
// 如果有临时数据,说明发生了拖拽或拉伸,提交数据更新
|
||||
@@ -882,7 +882,7 @@ watch(
|
||||
reportBarPosition()
|
||||
})
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
// 处理TaskBar双击事件
|
||||
@@ -1171,7 +1171,7 @@ watch(
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听外部hideBubbles属性变化,确保Timeline的容器变化能及时反应
|
||||
@@ -1184,7 +1184,7 @@ watch(
|
||||
// 强制重新计算bubbleIndicator,确保容器宽度变化后正确显示半圆
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听TaskBar可见性变化,只在滚动时实现重新出现动画
|
||||
@@ -1193,7 +1193,7 @@ watch(
|
||||
() => {
|
||||
// TaskBar重新出现时,不需要动画效果
|
||||
// 半圆会自然消失,TaskBar会立即显示
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听页面缩放和大小变化,重新计算气泡位置
|
||||
@@ -1353,13 +1353,13 @@ const calculateYearViewPosition = (targetDate: Date, baseStartDate: Date): numbe
|
||||
const daysInHalfYear =
|
||||
month <= 6
|
||||
? Math.floor(
|
||||
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
)
|
||||
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
||||
(1000 * 60 * 60 * 24),
|
||||
)
|
||||
: Math.floor(
|
||||
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
)
|
||||
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
||||
(1000 * 60 * 60 * 24),
|
||||
)
|
||||
|
||||
const dayPositionInHalfYear = (dayOffset / daysInHalfYear) * halfYearWidth
|
||||
position += dayPositionInHalfYear
|
||||
@@ -1383,7 +1383,7 @@ const calculatePositionFromTimelineData = (
|
||||
subDays: Array<{ date: Date; dayOfWeek?: number }>
|
||||
}>
|
||||
}>,
|
||||
timeScale: TimelineScale
|
||||
timeScale: TimelineScale,
|
||||
) => {
|
||||
let cumulativePosition = 0
|
||||
|
||||
@@ -1401,11 +1401,11 @@ const calculatePositionFromTimelineData = (
|
||||
// 找到目标日期所在的季度
|
||||
const quarterWidth = 60
|
||||
const daysInQuarter = Math.ceil(
|
||||
(quarterEnd.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||
(quarterEnd.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24),
|
||||
)
|
||||
const dayWidth = quarterWidth / daysInQuarter
|
||||
const dayInQuarter = Math.ceil(
|
||||
(targetDate.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||
(targetDate.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24),
|
||||
)
|
||||
return cumulativePosition + dayInQuarter * dayWidth
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ watch(
|
||||
() => [props.task?.isTimerRunning, props.task?.timerStartTime, props.task?.timerElapsedTime],
|
||||
() => {
|
||||
updateTimer()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 计时器本地状态,保证点击后UI立即切换
|
||||
@@ -84,7 +84,7 @@ watch(
|
||||
timerInterval.value = null
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 修正计时器每秒递增逻辑,保证计时器正常跳动
|
||||
@@ -102,7 +102,7 @@ watch(
|
||||
updateTimer()
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -153,7 +153,7 @@ const availableParentTasks = computed(() => {
|
||||
.filter(
|
||||
task =>
|
||||
task.id !== props.task?.id && // 排除当前任务自己
|
||||
(task.type === 'story' || task.type === 'task') // 只显示story和task类型
|
||||
(task.type === 'story' || task.type === 'task'), // 只显示story和task类型
|
||||
)
|
||||
.map(task => ({
|
||||
...task,
|
||||
@@ -346,7 +346,7 @@ watch(
|
||||
// 抽屉显示时重新请求任务数据,确保前置任务列表是最新的
|
||||
window.dispatchEvent(new CustomEvent('request-task-list'))
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听 isVisible 变化,同步到父组件
|
||||
@@ -363,7 +363,7 @@ watch(
|
||||
formData.parentId = newTask.parentId ?? undefined
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 重置表单
|
||||
@@ -548,7 +548,7 @@ watch(
|
||||
newValue => {
|
||||
progressDisplayValue.value = (newValue || 0).toString()
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 修正计时器首次启动不跳动问题:每次打开抽屉时重置 timerElapsed,且 timerStartTime 为空时立即赋值
|
||||
@@ -566,7 +566,7 @@ watch(
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
const handleStartTimer = (desc?: string) => {
|
||||
|
||||
@@ -67,7 +67,7 @@ const isStoryTask = computed(() => props.task.type === 'story')
|
||||
const isMilestoneGroup = computed(() => props.task.type === 'milestone-group')
|
||||
const isMilestoneTask = computed(() => props.task.type === 'milestone')
|
||||
const isParentTask = computed(
|
||||
() => isStoryTask.value || hasChildren.value || isMilestoneGroup.value
|
||||
() => isStoryTask.value || hasChildren.value || isMilestoneGroup.value,
|
||||
)
|
||||
function handleToggle() {
|
||||
emit('toggle', props.task)
|
||||
@@ -221,7 +221,7 @@ watch(
|
||||
updateTimer()
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 右键菜单相关状态
|
||||
@@ -464,6 +464,11 @@ onUnmounted(() => {
|
||||
{{ props.task.progress != null ? props.task.progress + '%' : '-' }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- 自定义列 - 通过task对象的key动态获取值 -->
|
||||
<template v-else>
|
||||
{{ (props.task as any)[column.key] || '-' }}
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -354,7 +354,7 @@ const optimizedTimelineData = computed(() => {
|
||||
const currentDay = new Date(day.year, day.month - 1, day.day)
|
||||
currentDay.setHours(0, 0, 0, 0)
|
||||
const daysDiff = Math.floor(
|
||||
(currentDay.getTime() - dayStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||
(currentDay.getTime() - dayStart.getTime()) / (1000 * 60 * 60 * 24),
|
||||
)
|
||||
const totalHourOffset = daysDiff * 24
|
||||
|
||||
@@ -455,7 +455,7 @@ const computeAllMilestonesPositions = () => {
|
||||
if (!isNaN(milestoneDate.getTime())) {
|
||||
const startDiff = Math.floor(
|
||||
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
(1000 * 60 * 60 * 24),
|
||||
)
|
||||
const left = startDiff * 30 + 30 / 2 - 12 // 30是dayWidth,12是图标半径
|
||||
|
||||
@@ -489,7 +489,7 @@ const computeAllMilestonesPositions = () => {
|
||||
if (!isNaN(milestoneDate.getTime())) {
|
||||
const startDiff = Math.floor(
|
||||
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
(1000 * 60 * 60 * 24),
|
||||
)
|
||||
const left = startDiff * 30 + 30 / 2 - 12
|
||||
|
||||
@@ -592,7 +592,7 @@ const handleTaskRowHover = (taskId: number | null) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('timeline-task-hover', {
|
||||
detail: taskId,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ const handleMilestoneIconChange = (milestoneId: number, icon: string) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('milestone-icon-changed', {
|
||||
detail: { milestoneId, icon },
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ const handleMilestoneSave = (updatedMilestone: Milestone) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('milestone-data-updated', {
|
||||
detail: { milestone: updatedMilestone },
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -675,14 +675,14 @@ const handleMilestoneDelete = (milestoneId: number) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('milestone-deleted', {
|
||||
detail: { milestoneId },
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
// 广播里程碑数据变化事件,确保Timeline重新渲染
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('milestone-data-changed', {
|
||||
detail: { milestoneId },
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ const handleMilestoneUpdate = (updatedMilestone: Milestone) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('milestone-data-updated', {
|
||||
detail: { milestone: updatedMilestone },
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1017,7 +1017,7 @@ watch(
|
||||
clearTimelineCache()
|
||||
timelineData.value = generateTimelineData()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 保证每次时间轴数据变化后都自动居中今日(仅初始化和外部props变更时触发,不因任务/里程碑变更触发)
|
||||
@@ -1032,7 +1032,7 @@ watch(
|
||||
})
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
// 将今日定位到时间线中间位置
|
||||
@@ -1057,13 +1057,13 @@ const scrollToTodayCenter = (retry = 0) => {
|
||||
startNormalized = new Date(
|
||||
yearRange.startDate.getFullYear(),
|
||||
yearRange.startDate.getMonth(),
|
||||
yearRange.startDate.getDate()
|
||||
yearRange.startDate.getDate(),
|
||||
)
|
||||
} else {
|
||||
startNormalized = new Date(
|
||||
timelineStart.getFullYear(),
|
||||
timelineStart.getMonth(),
|
||||
timelineStart.getDate()
|
||||
timelineStart.getDate(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1136,7 +1136,7 @@ const scrollToTodayCenter = (retry = 0) => {
|
||||
}
|
||||
|
||||
const dayOffset = Math.floor(
|
||||
(todayNormalized.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24)
|
||||
(todayNormalized.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24),
|
||||
)
|
||||
const daysInQuarter =
|
||||
Math.floor((endOfQuarter.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24)) + 1
|
||||
@@ -1193,7 +1193,7 @@ const getTodayLinePositionInYearView = computed(() => {
|
||||
const startNormalized = new Date(
|
||||
yearRange.startDate.getFullYear(),
|
||||
yearRange.startDate.getMonth(),
|
||||
yearRange.startDate.getDate()
|
||||
yearRange.startDate.getDate(),
|
||||
)
|
||||
|
||||
const startYear = startNormalized.getFullYear()
|
||||
@@ -1287,7 +1287,7 @@ const scrollToToday = () => {
|
||||
const startNormalized = new Date(
|
||||
timelineStart.getFullYear(),
|
||||
timelineStart.getMonth(),
|
||||
timelineStart.getDate()
|
||||
timelineStart.getDate(),
|
||||
)
|
||||
|
||||
// 计算今天距离时间线开始日期的天数
|
||||
@@ -1338,7 +1338,7 @@ const updateTask = (updatedTask: Task) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('task-updated', {
|
||||
detail: updatedTask,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1398,7 +1398,7 @@ const handleTaskBarContextMenu = (event: { task: Task; position: { x: number; y:
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('context-menu', {
|
||||
detail: event,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1481,7 +1481,7 @@ onMounted(() => {
|
||||
// 监听TaskList的垂直滚动事件
|
||||
window.addEventListener(
|
||||
'task-list-vertical-scroll',
|
||||
handleTaskListVerticalScroll as EventListener
|
||||
handleTaskListVerticalScroll as EventListener,
|
||||
)
|
||||
// 监听语言变化
|
||||
window.addEventListener('locale-changed', handleLocaleChange as EventListener)
|
||||
@@ -1491,7 +1491,7 @@ onMounted(() => {
|
||||
// 监听Timeline容器resize事件(TaskList切换等)
|
||||
window.addEventListener(
|
||||
'timeline-container-resized',
|
||||
handleTimelineContainerResized as EventListener
|
||||
handleTimelineContainerResized as EventListener,
|
||||
)
|
||||
|
||||
// 监听里程碑点击定位事件
|
||||
@@ -1581,7 +1581,7 @@ const handleTimelineBodyScroll = (event: Event) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('timeline-vertical-scroll', {
|
||||
detail: { scrollTop },
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1594,7 +1594,7 @@ watch(
|
||||
updateSvgSize()
|
||||
})
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 拖拽滑动相关状态
|
||||
@@ -1778,7 +1778,7 @@ const startAutoScroll = (direction: 'left' | 'right') => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('timeline-auto-scroll', {
|
||||
detail: { scrollDelta: newScrollLeft - currentScrollLeft },
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
autoScrollTimer = window.setTimeout(scroll, 16) // 约60fps
|
||||
@@ -1832,14 +1832,14 @@ onUnmounted(() => {
|
||||
window.removeEventListener('task-list-hover', handleTaskListHover as EventListener)
|
||||
window.removeEventListener(
|
||||
'task-list-vertical-scroll',
|
||||
handleTaskListVerticalScroll as EventListener
|
||||
handleTaskListVerticalScroll as EventListener,
|
||||
)
|
||||
window.removeEventListener('locale-changed', handleLocaleChange as EventListener)
|
||||
window.removeEventListener('splitter-drag-start', handleSplitterDragStart as EventListener)
|
||||
window.removeEventListener('splitter-drag-end', handleSplitterDragEnd as EventListener)
|
||||
window.removeEventListener(
|
||||
'timeline-container-resized',
|
||||
handleTimelineContainerResized as EventListener
|
||||
handleTimelineContainerResized as EventListener,
|
||||
)
|
||||
window.removeEventListener('milestone-click-locate', handleMilestoneClickLocate as EventListener)
|
||||
window.removeEventListener('drag-boundary-check', handleDragBoundaryCheck as EventListener)
|
||||
@@ -1950,7 +1950,7 @@ watch(
|
||||
}
|
||||
})
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
// 处理里程碑点击定位事件
|
||||
|
||||
@@ -23,4 +23,6 @@ export interface Task {
|
||||
timerEndTime?: number // 结束计时时间
|
||||
timerStartDesc?: string // 计时开始时填写的描述
|
||||
timerElapsedTime?: number
|
||||
// 支持自定义属性 - 使用 unknown 允许任意类型
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
border-right: 1px solid var(--gantt-border-light);
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
/* 为没有特定样式的列设置默认宽度 */
|
||||
flex: 1 0 120px;
|
||||
min-width: 120px;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.col:last-child {
|
||||
|
||||
Reference in New Issue
Block a user