vxe-gantt
Version:
A vue based gantt component
138 lines (127 loc) • 5.55 kB
text/typescript
import { h, inject, ref, Ref, onMounted, onUnmounted } from 'vue'
import { defineVxeComponent } from '../../ui/src/comp'
import { VxeUI } from '@vxe-ui/core'
import XEUtils from 'xe-utils'
import type { VxeComponentSlotType } from 'vxe-pc-ui'
import type { VxeGanttViewConstructor, VxeGanttViewPrivateMethods, VxeGanttConstructor, VxeGanttPrivateMethods } from '../../../types'
const { getI18n } = VxeUI
const sourceType = 'gantt'
const viewType = 'header'
export default defineVxeComponent({
name: 'VxeGanttViewHeader',
setup () {
const $xeGantt = inject('$xeGantt', {} as (VxeGanttConstructor & VxeGanttPrivateMethods))
const $xeGanttView = inject('$xeGanttView', {} as VxeGanttViewConstructor & VxeGanttViewPrivateMethods)
const { computeTaskViewOpts } = $xeGantt.getComputeMaps()
const { reactData, internalData } = $xeGanttView
const refElem = ref() as Ref<HTMLDivElement>
const refHeaderScroll = ref() as Ref<HTMLDivElement>
const refHeaderTable = ref() as Ref<HTMLTableElement>
const refHeaderXSpace = ref() as Ref<HTMLDivElement>
const renderVN = () => {
const { headerGroups, viewCellWidth } = reactData
const { todayDateMaps, visibleColumn } = internalData
const taskViewOpts = computeTaskViewOpts.value
const { showNowLine } = taskViewOpts
return h('div', {
ref: refElem,
class: 'vxe-gantt-view--header-wrapper'
}, [
h('div', {
ref: refHeaderScroll,
class: 'vxe-gantt-view--header-inner-wrapper',
onScroll: $xeGanttView.triggerHeaderScrollEvent
}, [
h('div', {
ref: refHeaderXSpace,
class: 'vxe-body--x-space'
}),
h('table', {
ref: refHeaderTable,
class: 'vxe-gantt-view--header-table'
}, [
h('colgroup', {}, visibleColumn.map((column, cIndex) => {
return h('col', {
key: cIndex,
style: {
width: `${viewCellWidth}px`
}
})
})),
h('thead', {}, headerGroups.map(({ scaleItem, columns }, $rowIndex) => {
const { type, titleFormat, titleMethod, headerCellStyle, slots } = scaleItem
const titleSlot = slots ? slots.title : null
const isLast = $rowIndex === headerGroups.length - 1
const todayValue = isLast && showNowLine ? todayDateMaps[type] : null
return h('tr', {
key: $rowIndex
}, columns.map((column, cIndex) => {
const { field, childCount, dateObj } = column
let label = `${column.title}`
if (scaleItem.type === 'day') {
label = getI18n(`vxe.gantt.dayss.w${dateObj.e}`)
} else {
if ($rowIndex) {
label = getI18n(`vxe.gantt.tSimpleFormat.${type}`, dateObj)
} else {
if (isLast && scaleItem.type === 'week') {
label = getI18n(`vxe.gantt.tSimpleFormat.${type}`, dateObj)
} else {
label = getI18n(`vxe.gantt.tFullFormat.${type}`, dateObj)
}
}
}
let cellVNs: string | VxeComponentSlotType[] = label
const ctParams = { source: sourceType, type: viewType, column, scaleObj: scaleItem, title: label, dateObj: dateObj, $rowIndex }
if (titleSlot) {
cellVNs = $xeGantt.callSlot(titleSlot, ctParams)
} else if (titleMethod) {
cellVNs = `${titleMethod(ctParams)}`
} else if (titleFormat) {
cellVNs = XEUtils.toDateString(dateObj.date, titleFormat)
}
let cellStys: Partial<CSSStyleDeclaration> | null = {}
if (headerCellStyle) {
if (XEUtils.isFunction(headerCellStyle)) {
cellStys = headerCellStyle(ctParams) || null
} else {
cellStys = headerCellStyle
}
}
return h('th', {
key: cIndex,
class: ['vxe-gantt-view--header-column', {
'is--now': showNowLine && todayValue && todayValue === field
}],
colspan: childCount || null,
title: titleSlot ? null : label,
style: cellStys || undefined,
onContextmenu (evnt) {
$xeGantt.handleTaskHeaderContextmenuEvent(evnt, ctParams)
}
}, cellVNs)
}))
}))
])
])
])
}
onMounted(() => {
const { elemStore } = internalData
const prefix = 'main-header-'
elemStore[`${prefix}wrapper`] = refElem
elemStore[`${prefix}scroll`] = refHeaderScroll
elemStore[`${prefix}table`] = refHeaderTable
elemStore[`${prefix}xSpace`] = refHeaderXSpace
})
onUnmounted(() => {
const { elemStore } = internalData
const prefix = 'main-header-'
elemStore[`${prefix}wrapper`] = null
elemStore[`${prefix}scroll`] = null
elemStore[`${prefix}table`] = null
elemStore[`${prefix}xSpace`] = null
})
return renderVN
}
})