UNPKG

vxe-gantt

Version:
292 lines (272 loc) 11.3 kB
import { h, inject, VNode, ref, Ref, onMounted, onUnmounted } from 'vue' import { defineVxeComponent } from '../../ui/src/comp' import { getCellRestHeight } from './util' import { getClass } from '../../ui/src/utils' import XEUtils from 'xe-utils' import GanttViewChartComponent from './gantt-chart' import type { VxeTableConstructor, VxeTableMethods, VxeTablePrivateMethods, VxeTableDefines } from 'vxe-table' import type { VxeGanttViewConstructor, VxeGanttViewPrivateMethods, VxeGanttConstructor, VxeGanttPrivateMethods, VxeGanttDefines } from '../../../types' const sourceType = 'gantt' const viewType = 'body' export default defineVxeComponent({ name: 'VxeGanttViewBody', setup () { const $xeGantt = inject('$xeGantt', {} as (VxeGanttConstructor & VxeGanttPrivateMethods)) const $xeGanttView = inject('$xeGanttView', {} as VxeGanttViewConstructor & VxeGanttViewPrivateMethods) const { computeTaskViewOpts, computeScaleUnit } = $xeGantt.getComputeMaps() const { reactData, internalData } = $xeGanttView const refElem = ref() as Ref<HTMLDivElement> const refBodyScroll = ref() as Ref<HTMLDivElement> const refBodyTable = ref() as Ref<HTMLTableElement> const refBodyXSpace = ref() as Ref<HTMLDivElement> const refBodyYSpace = ref() as Ref<HTMLDivElement> const renderColumn = ($xeTable: VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods, row: any, rowid: string, rowIndex: number, $rowIndex: number, _rowIndex: number, column: VxeGanttDefines.ViewColumn, $columnIndex: number) => { const tableReactData = $xeTable.reactData const { resizeHeightFlag } = tableReactData const tableInternalData = $xeTable.internalData const { fullAllDataRowIdData, visibleColumn } = tableInternalData const { computeCellOpts, computeRowOpts, computeDefaultRowHeight, computeResizableOpts } = $xeTable.getComputeMaps() const cellOpts = computeCellOpts.value const rowOpts = computeRowOpts.value const defaultRowHeight = computeDefaultRowHeight.value const resizableOpts = computeResizableOpts.value const { isAllRowDrag } = resizableOpts const { headerGroups } = reactData const { todayDateMaps } = internalData const taskViewOpts = computeTaskViewOpts.value const { showNowLine, viewStyle } = taskViewOpts const scaleUnit = computeScaleUnit.value const { scaleItem } = headerGroups[headerGroups.length - 1] || {} const { field, dateObj } = column const { cellClassName, cellStyle } = viewStyle || {} const todayValue = showNowLine && scaleItem ? todayDateMaps[scaleItem.type] : null const rowRest = fullAllDataRowIdData[rowid] || {} const cellHeight = resizeHeightFlag ? getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight) : 0 const tdVNs: VNode[] = [] if (isAllRowDrag && rowOpts.resizable) { const cellParams: VxeTableDefines.CellRenderBodyParams = { $table: $xeTable, $grid: null, $gantt: $xeGantt, seq: -1, rowid, row, rowIndex, $rowIndex, _rowIndex, column: visibleColumn[0], columnIndex: 0, $columnIndex: 0, _columnIndex: 0, fixed: '', source: sourceType, type: viewType, isHidden: false, isEdit: false, level: -1, // 已废弃属性 visibleData: [], data: [], items: [] } tdVNs.push( h('div', { class: 'vxe-gantt-view-cell--row-resizable', onMousedown: (evnt: MouseEvent) => $xeTable.handleRowResizeMousedownEvent(evnt, cellParams), onDblclick: (evnt: MouseEvent) => $xeTable.handleRowResizeDblclickEvent(evnt, cellParams) }) ) } const ctParams = { $gantt: $xeGantt, source: sourceType, type: viewType, scaleType: scaleUnit, dateObj, row, column, $rowIndex, rowIndex, _rowIndex } return h('td', { key: cellClassName || cellStyle ? field : $columnIndex, class: [ 'vxe-gantt-view--body-column', { 'is--now': showNowLine && todayValue === field }, getClass(cellClassName, ctParams) ], style: cellStyle ? Object.assign({}, XEUtils.isFunction(cellStyle) ? cellStyle(ctParams) : cellStyle, { height: `${cellHeight}px` }) : { height: `${cellHeight}px` }, onClick (evnt) { $xeGantt.handleTaskCellClickEvent(evnt, { row, column }) }, onDblclick (evnt) { $xeGantt.handleTaskCellDblclickEvent(evnt, { row, column }) }, onContextmenu (evnt) { $xeGantt.handleTaskBodyContextmenuEvent(evnt, ctParams) } }, tdVNs) } const renderRows = ($xeTable: VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods, tableData: any[]) => { const tableProps = $xeTable.props const { treeConfig, stripe, highlightHoverRow, editConfig } = tableProps const tableReactData = $xeTable.reactData const { treeExpandedFlag, selectRadioRow, pendingRowFlag, isRowGroupStatus } = tableReactData const tableInternalData = $xeTable.internalData const { fullAllDataRowIdData, treeExpandedMaps, pendingRowMaps } = tableInternalData const { computeRadioOpts, computeCheckboxOpts, computeTreeOpts, computeRowOpts } = $xeTable.getComputeMaps() const radioOpts = computeRadioOpts.value const checkboxOpts = computeCheckboxOpts.value const rowOpts = computeRowOpts.value const treeOpts = computeTreeOpts.value const { transform } = treeOpts const childrenField = treeOpts.children || treeOpts.childrenField const scaleUnit = computeScaleUnit.value const taskViewOpts = computeTaskViewOpts.value const { viewStyle } = taskViewOpts const { rowClassName, rowStyle, cellClassName, cellStyle } = viewStyle || {} const { tableColumn, scrollYLoad } = reactData const trVNs:VNode[] = [] tableData.forEach((row, $rowIndex) => { const rowid = $xeTable.getRowid(row) const rowRest = fullAllDataRowIdData[rowid] || {} const trOns: Record<string, any> = {} let rowIndex = $rowIndex let _rowIndex = -1 if (rowRest) { rowIndex = rowRest.index _rowIndex = rowRest._index } // 是否新增行 let isNewRow = false if (editConfig) { isNewRow = $xeTable.isInsertByRow(row) } // 当前行事件 if (rowOpts.isHover || highlightHoverRow) { trOns.onMouseenter = (evnt: MouseEvent) => { $xeTable.triggerHoverEvent(evnt, { row, rowIndex }) } trOns.onMouseleave = () => { $xeTable.clearHoverRow() } } // 拖拽行事件 if (rowOpts.drag && !isRowGroupStatus && (!treeConfig || transform)) { trOns.onDragstart = $xeTable.handleRowDragDragstartEvent trOns.onDragend = $xeTable.handleRowDragDragendEvent trOns.onDragover = $xeTable.handleRowDragDragoverEvent } const rowParams = { $gantt: $xeGantt, source: sourceType, type: viewType, scaleType: scaleUnit, row, rowIndex, $rowIndex, _rowIndex } trVNs.push( h('tr', { key: rowClassName || rowStyle || cellClassName || cellStyle ? rowid : $rowIndex, class: [ 'vxe-gantt-view--body-row', { 'row--stripe': stripe && (_rowIndex + 1) % 2 === 0, 'is--new': isNewRow, 'row--radio': radioOpts.highlight && $xeTable.eqRow(selectRadioRow, row), 'row--checked': checkboxOpts.highlight && $xeTable.isCheckedByCheckboxRow(row), 'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid] }, getClass(rowClassName, rowParams) ], rowid, style: rowStyle ? (XEUtils.isFunction(rowStyle) ? rowStyle(rowParams) || undefined : rowStyle) : undefined, ...trOns }, tableColumn.map((column, $columnIndex) => renderColumn($xeTable, row, rowid, rowIndex, $rowIndex, _rowIndex, column, $columnIndex))) ) let isExpandTree = false let rowChildren: any[] = [] if (treeConfig && !scrollYLoad && !transform) { rowChildren = row[childrenField] isExpandTree = !!treeExpandedFlag && rowChildren && rowChildren.length > 0 && !!treeExpandedMaps[rowid] } // 如果是树形表格 if (isExpandTree) { trVNs.push(...renderRows($xeTable, rowChildren)) } }) return trVNs } const renderVN = () => { const $xeTable = $xeGanttView.internalData.xeTable const { tableData, tableColumn, viewCellWidth } = reactData return h('div', { ref: refElem, class: 'vxe-gantt-view--body-wrapper' }, [ h('div', { ref: refBodyScroll, class: 'vxe-gantt-view--body-inner-wrapper', onScroll: $xeGanttView.triggerBodyScrollEvent, onContextmenu (evnt) { $xeGantt.handleTaskBodyContextmenuEvent(evnt, { source: sourceType, type: viewType, rowIndex: -1, $rowIndex: -1, _rowIndex: -1 }) } }, [ h('div', { ref: refBodyXSpace, class: 'vxe-body--x-space' }), h('div', { ref: refBodyYSpace, class: 'vxe-body--y-space' }), h('table', { ref: refBodyTable, class: 'vxe-gantt-view--body-table' }, [ h('colgroup', {}, tableColumn.map((column, cIndex) => { return h('col', { key: cIndex, style: { width: `${viewCellWidth}px` } }) })), h('tbody', {}, $xeTable ? renderRows($xeTable, tableData) : []) ]), h(GanttViewChartComponent) ]) ]) } onMounted(() => { const { elemStore } = internalData const prefix = 'main-body-' elemStore[`${prefix}wrapper`] = refElem elemStore[`${prefix}scroll`] = refBodyScroll elemStore[`${prefix}table`] = refBodyTable elemStore[`${prefix}xSpace`] = refBodyXSpace elemStore[`${prefix}ySpace`] = refBodyYSpace }) onUnmounted(() => { const { elemStore } = internalData const prefix = 'main-body-' elemStore[`${prefix}wrapper`] = null elemStore[`${prefix}scroll`] = null elemStore[`${prefix}table`] = null elemStore[`${prefix}xSpace`] = null elemStore[`${prefix}ySpace`] = null }) return renderVN } })