vxe-gantt
Version:
A vue based gantt component
6,315 lines • 299 kB
JavaScript
import { VxeUI } from '@vxe-ui/core';
export { VxeUI } from '@vxe-ui/core';
import { defineComponent, inject, ref, onMounted, onUnmounted, h, reactive, computed, onBeforeUnmount, provide, nextTick, watch } from 'vue';
import XEUtils from 'xe-utils';
import DomZIndex from 'dom-zindex';
import { VxeTable } from 'vxe-table';
const { setConfig: setConfig$1, setIcon } = VxeUI;
VxeUI.ganttVersion = "4.8.1";
const ymdFormat = 'yyyy-MM-dd';
const ymdhmsFormat = 'yyyy-MM-dd HH:mm:ss';
setConfig$1({
gantt: {
// size: null,
// zoomConfig: {
// escRestore: true
// },
formConfig: {
enabled: true
},
pagerConfig: {
enabled: true
// perfect: false
},
toolbarConfig: {
enabled: true
// perfect: false
},
proxyConfig: {
enabled: true,
autoLoad: true,
showLoading: true,
showResponseMsg: true,
showActionMsg: true,
response: {
list: null,
result: 'result',
total: 'page.total',
message: 'message'
}
// beforeItem: null,
// beforeColumn: null,
// beforeQuery: null,
// afterQuery: null,
// beforeDelete: null,
// afterDelete: null,
// beforeSave: null,
// afterSave: null
},
taskBarTooltipConfig: {
enterable: true
},
taskLinkConfig: {
enabled: true,
isHover: true,
showArrow: true
},
taskViewScaleConfig: {
year: {
valueFormat: ymdFormat
},
quarter: {
valueFormat: ymdFormat
},
month: {
valueFormat: ymdFormat
},
week: {
startDay: 1,
valueFormat: ymdFormat
},
day: {
valueFormat: ymdFormat
},
date: {
valueFormat: ymdFormat
},
hour: {
valueFormat: ymdhmsFormat
},
minute: {
valueFormat: ymdhmsFormat
},
second: {
valueFormat: ymdhmsFormat
}
},
taskViewConfig: {
showNowLine: true,
gridding: {
leftSpacing: 1,
rightSpacing: 1
}
},
taskSplitConfig: {
enabled: true,
resize: true,
autoHideCollapseButton: true,
showCollapseTableButton: true,
showCollapseTaskButton: true
},
taskBarSubviewConfig: {
// showOverview: false
},
taskBarMoveConfig: {
isLimitByLink: true
},
taskBarResizeConfig: {
minWidthSize: 0.5,
isLimitByLink: true
},
taskBarMoveTooltipConfig: {
enterable: true,
enterDelay: 0
},
taskBarResizeTooltipConfig: {
enterable: true,
enterDelay: 0
}
}
});
const iconPrefix = 'vxe-icon-';
setIcon({
// gantt
GANTT_VIEW_LEFT_OPEN: iconPrefix + 'arrow-left',
GANTT_VIEW_LEFT_CLOSE: iconPrefix + 'arrow-right',
GANTT_VIEW_RIGHT_OPEN: iconPrefix + 'arrow-right',
GANTT_VIEW_RIGHT_CLOSE: iconPrefix + 'arrow-left',
GANTT_VIEW_TASK_MILESTONE: iconPrefix + 'square-fill rotate45'
});
const { log } = VxeUI;
const ganttVersion = `gantt v${"4.8.1"}`;
function createComponentLog(name) {
const uiVersion = VxeUI.uiVersion ? `ui v${VxeUI.uiVersion}` : '';
const tableVersion = VxeUI.tableVersion ? `table v${VxeUI.tableVersion}` : '';
const designVersion = VxeUI.designVersion ? `design v${VxeUI.designVersion}` : '';
const versionInfo = [uiVersion, tableVersion, ganttVersion, designVersion].filter(v => v).join(' ');
return {
warnLog: log.create('warn', versionInfo + '] [' + name),
errLog: log.create('error', versionInfo + '] [' + name)
};
}
log.create('warn', ganttVersion);
const errLog$1 = log.create('error', ganttVersion);
function checkDependVersion() {
const pVersion = 4;
const sVersion = 17;
if (VxeUI.checkVersion) {
if (!VxeUI.checkVersion(VxeUI.tableVersion, pVersion, sVersion)) {
errLog$1('vxe.error.errorVersion', [`vxe-table@${VxeUI.tableVersion || '?'}`, `vxe-table v${pVersion}.${sVersion}+`]);
}
}
else {
errLog$1(`Requires vxe-table v${pVersion}.${sVersion}+`);
}
}
const defineVxeComponent = defineComponent;
function isEnableConf(conf) {
return conf && conf.enabled !== false;
}
function hasEnableConf(conf, opts) {
return opts && (conf ? opts.enabled !== false : opts.enabled);
}
function isEmptyValue(cellValue) {
return cellValue === null || cellValue === undefined || cellValue === '';
}
function nextZIndex() {
return DomZIndex.getNext();
}
function getLastZIndex() {
return DomZIndex.getCurrent();
}
function formatText(value, placeholder) {
return '' + (isEmptyValue(value) ? ('') : value);
}
/**
* 判断值为:'' | null | undefined 时都属于空值
*/
function eqEmptyValue(cellValue) {
return cellValue === '' || XEUtils.eqNull(cellValue);
}
function getStringValue(cellValue) {
return eqEmptyValue(cellValue) ? '' : cellValue;
}
function getClass(property, params) {
return property ? XEUtils.isFunction(property) ? property(params) : property : '';
}
const reClsMap = {};
function getClsRE(cls) {
if (!reClsMap[cls]) {
reClsMap[cls] = new RegExp(`(?:^|\\s)${cls}(?!\\S)`, 'g');
}
return reClsMap[cls];
}
function hasClass(elem, cls) {
if (elem) {
if (elem.classList) {
return elem.classList.contains(cls);
}
return !!(elem.className && elem.className.match && elem.className.match(getClsRE(cls)));
}
return false;
}
function removeClass(elem, cls) {
if (elem && hasClass(elem, cls)) {
elem.className = elem.className.replace(getClsRE(cls), '');
}
}
function addClass(elem, cls) {
if (elem && !hasClass(elem, cls)) {
removeClass(elem, cls);
elem.className = `${elem.className} ${cls}`;
}
}
function toCssUnit(val, unit = 'px') {
if (XEUtils.isNumber(val) || /^\d+$/.test(`${val}`)) {
return `${val}${unit}`;
}
return `${val || ''}`;
}
function getDomNode() {
const documentElement = document.documentElement;
const bodyElem = document.body;
return {
scrollTop: documentElement.scrollTop || bodyElem.scrollTop,
scrollLeft: documentElement.scrollLeft || bodyElem.scrollLeft,
visibleHeight: documentElement.clientHeight || bodyElem.clientHeight,
visibleWidth: documentElement.clientWidth || bodyElem.clientWidth
};
}
function getOffsetHeight(elem) {
return elem ? elem.offsetHeight : 0;
}
function getPaddingTopBottomSize(elem) {
if (elem) {
const computedStyle = getComputedStyle(elem);
const paddingTop = XEUtils.toNumber(computedStyle.paddingTop);
const paddingBottom = XEUtils.toNumber(computedStyle.paddingBottom);
return paddingTop + paddingBottom;
}
return 0;
}
function setScrollTop(elem, scrollTop) {
if (elem) {
elem.scrollTop = scrollTop;
}
}
function setScrollLeft(elem, scrollLeft) {
if (elem) {
elem.scrollLeft = scrollLeft;
}
}
function getSlotVNs(vns) {
if (XEUtils.isArray(vns)) {
return vns;
}
return vns ? [vns] : [];
}
const tableEmits = [
'ready',
'init-rendered',
'data-rendered',
'update:data',
'keydown-start',
'keydown',
'keydown-end',
'paste',
'copy',
'cut',
'undo',
'redo',
'context-menu',
'columns-change',
'data-change',
'footer-data-change',
'current-change', // 已废弃
'current-row-change',
'current-row-disabled',
'current-column-change',
'current-column-disabled',
'radio-change',
'checkbox-change',
'checkbox-all',
'checkbox-range-start',
'checkbox-range-change',
'checkbox-range-end',
'checkbox-range-select',
'cell-click',
'cell-dblclick',
'cell-menu',
'cell-mouseenter',
'cell-mouseleave',
'cell-selected',
'cell-delete-value',
'cell-backspace-value',
'header-cell-click',
'header-cell-dblclick',
'header-cell-menu',
'footer-cell-click',
'footer-cell-dblclick',
'footer-cell-menu',
'clear-merge',
'sort-change',
'clear-sort',
'clear-all-sort',
'filter-change',
'filter-visible',
'clear-filter',
'clear-all-filter',
'resizable-change', // 废弃
'column-resizable-change',
'row-resizable-change',
'toggle-row-group-expand',
'toggle-row-expand',
'toggle-tree-expand',
'menu-click',
'edit-closed',
'row-dragstart',
'row-dragover',
'row-dragend',
'row-remove-dragend',
'row-insert-dragend',
'column-dragstart',
'column-dragover',
'column-dragend',
'enter-append-row',
'tab-append-row',
'edit-actived', // 废弃
'edit-activated',
'edit-disabled',
'valid-error',
'scroll',
'scroll-boundary',
'custom',
'custom-open',
'custom-close',
'custom-cancel',
'custom-reset',
'custom-confirm',
'custom-visible-change',
'custom-visible-all',
'custom-fixed-change',
'custom-sort-change',
'custom-align-change',
'custom-header-align-change',
'custom-footer-align-change',
'change-fnr', // 废弃
'open-fnr',
'show-fnr',
'hide-fnr',
'fnr-change',
'fnr-find',
'fnr-find-all',
'fnr-replace',
'fnr-replace-all',
'cell-area-copy',
'cell-area-cut',
'cell-area-paste',
'cell-area-merge',
'clear-cell-area-selection',
'clear-cell-area-merge',
'header-cell-area-selection',
'cell-area-selection-invalid',
'cell-area-selection-start',
'cell-area-selection-drag',
'cell-area-selection-end',
'cell-area-extension-start',
'cell-area-extension-drag',
'cell-area-extension-end',
'cell-area-extension-fill',
'cell-area-selection-all-start',
'cell-area-selection-all-end',
'cell-area-arrows-start',
'cell-area-arrows-end',
'cell-area-fill-copy',
'active-cell-change-start',
'active-cell-change-end'
];
const gridEmits = [
...tableEmits,
'page-change',
'form-submit',
'form-submit-invalid',
'form-reset',
'form-collapse',
'form-toggle-collapse',
'proxy-query',
'proxy-delete',
'proxy-save',
'toolbar-button-click',
'toolbar-tool-click',
'zoom'
];
const ganttEmits = [
...gridEmits,
'task-cell-click',
'task-cell-dblclick',
'task-bar-mouseenter',
'task-bar-mouseleave',
'task-bar-click',
'task-bar-dblclick',
'task-view-cell-click',
'task-view-cell-dblclick',
'task-move-start',
'task-move-drag',
'task-move-end',
'task-resize-start',
'task-resize-drag',
'task-resize-end',
'task-link-click',
'task-link-dblclick',
'task-link-remove'
];
function getRefElem(refEl) {
if (refEl) {
const rest = refEl.value;
if (rest) {
return (rest.$el || rest);
}
}
return null;
}
function getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight) {
return rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
}
function getTaskBarLeft(chartRest, viewCellWidth) {
return chartRest ? viewCellWidth * chartRest.oLeftSize : 0;
}
function getTaskBarWidth(chartRest, viewCellWidth) {
return chartRest && chartRest.oWidthSize ? Math.max(1, chartRest ? (Math.floor(viewCellWidth * chartRest.oWidthSize) - 1) : 0) : 0;
}
const taskTypeMaps = {
milestone: true,
subview: true
};
function hasMilestoneTask(type) {
return type === 'milestone';
}
function hasSubviewTask(type) {
return type === 'subview';
}
function getTaskType(type) {
return taskTypeMaps[type] ? type : 'default';
}
/**
* 依赖线枚举类型
*/
var VxeGanttDependencyType;
(function (VxeGanttDependencyType) {
/**
* 结束后才开始,表示一个任务必须在另一个任务开始之前完成
*/
VxeGanttDependencyType[VxeGanttDependencyType["FinishToStart"] = 0] = "FinishToStart";
/**
* 开始到结束,表示从某个过程的开始到结束的整个过程
*/
VxeGanttDependencyType[VxeGanttDependencyType["StartToFinish"] = 1] = "StartToFinish";
/**
* 开始后才开始,表示一个活动结束了,另一个活动才能开始,它们之间按先后顺序进行
*/
VxeGanttDependencyType[VxeGanttDependencyType["StartToStart"] = 2] = "StartToStart";
/**
* 完成到完成,表示一个任务必须在另一个任务完成之后才能完成
*/
VxeGanttDependencyType[VxeGanttDependencyType["FinishToFinish"] = 3] = "FinishToFinish";
})(VxeGanttDependencyType || (VxeGanttDependencyType = {}));
/**
* 任务渲染类型
*/
var VxeGanttTaskType;
(function (VxeGanttTaskType) {
/**
* 里程碑类型,该类型节点不需要结束日期
*/
VxeGanttTaskType["Milestone"] = "milestone";
/**
* 子视图类型,该类型会将子任务渲染到一行,无需开始日期和结束日期
*/
VxeGanttTaskType["Subview"] = "subview";
})(VxeGanttTaskType || (VxeGanttTaskType = {}));
const { getI18n: getI18n$1 } = VxeUI;
const sourceType$4 = 'gantt';
const viewType$3 = 'header';
var GanttViewHeaderComponent = defineVxeComponent({
name: 'VxeGanttViewHeader',
setup() {
const $xeGantt = inject('$xeGantt', {});
const $xeGanttView = inject('$xeGanttView', {});
const { computeTaskViewOpts, computeScaleStep, computeMinScale } = $xeGantt.getComputeMaps();
const { reactData, internalData } = $xeGanttView;
const refElem = ref();
const refHeaderScroll = ref();
const refHeaderTable = ref();
const refHeaderXSpace = ref();
const renderVN = () => {
const { headerGroups, viewCellWidth } = reactData;
const { todayDateMaps, visibleColumn } = internalData;
const taskViewOpts = computeTaskViewOpts.value;
const minScale = computeMinScale.value;
const scaleStep = computeScaleStep.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, startDateObj, endDateObj } = column;
let label = `${column.title}`;
if ((isLast || (minScale && (minScale.type === 'date' || minScale.type === 'day') && (type === 'date' || type === 'day'))) && scaleStep > 1) {
label = getI18n$1(`vxe.gantt.stepFormat.${type}`, {
start: startDateObj,
end: endDateObj,
eStartLabel: getI18n$1(`vxe.gantt.dayss.w${startDateObj.e}`),
eEndLabel: getI18n$1(`vxe.gantt.dayss.w${endDateObj.e}`)
});
}
else {
if (type === 'day') {
if ($rowIndex) {
label = getI18n$1(`vxe.gantt.tSimpleFormat.${type}`, {
eLabel: getI18n$1(`vxe.gantt.dayss.w${dateObj.e}`)
});
}
else {
label = getI18n$1(`vxe.gantt.tFullFormat.${type}`, {
eLabel: getI18n$1(`vxe.gantt.dayss.w${dateObj.e}`)
});
}
}
else {
if ($rowIndex) {
label = getI18n$1(`vxe.gantt.tSimpleFormat.${type}`, dateObj);
}
else {
label = getI18n$1(`vxe.gantt.tFullFormat.${type}`, dateObj);
}
}
}
let cellVNs = label;
const ctParams = {
source: sourceType$4,
type: viewType$3,
column,
scaleObj: scaleItem,
title: label,
dateObj,
startDateObj,
endDateObj,
$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 = {};
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;
}
});
const { getIcon: getIcon$1, renderEmptyElement: renderEmptyElement$1 } = VxeUI;
const sourceType$3 = 'gantt';
const viewType$2 = 'chart';
var GanttViewChartComponent = defineVxeComponent({
name: 'VxeGanttViewChart',
setup() {
const $xeGantt = inject('$xeGantt', {});
const $xeGanttView = inject('$xeGanttView', {});
const { props: ganttProps, context: ganttContext, reactData: ganttReactData, internalData: ganttInternalData } = $xeGantt;
const { reactData: ganttViewReactData, internalData: ganttViewInternalData } = $xeGanttView;
const { computeProgressField, computeTitleField, computeTypeField, computeTaskBarOpts, computeScaleUnit, computeTaskLinkOpts, computeTaskBarMilestoneOpts, computeTaskBarSubviewOpts } = $xeGantt.getComputeMaps();
const { computeNowLineLeft } = $xeGanttView.getComputeMaps();
const refElem = ref();
const refTaskWrapperElem = ref();
const refChartBeforeWrapperElem = ref();
const refChartAfterWrapperElem = ref();
const refNowLineElem = ref();
const renderTaskBar = ($xeTable, row, rowid, rowIndex, $rowIndex, _rowIndex, rowChildren, isExpandTree) => {
const tableReactData = $xeTable.reactData;
const { resizeHeightFlag, pendingRowFlag } = tableReactData;
const tableInternalData = $xeTable.internalData;
const { fullAllDataRowIdData, pendingRowMaps } = tableInternalData;
const { computeCellOpts, computeRowOpts, computeDefaultRowHeight } = $xeTable.getComputeMaps();
const cellOpts = computeCellOpts.value;
const rowOpts = computeRowOpts.value;
const defaultRowHeight = computeDefaultRowHeight.value;
const { computeTreeOpts } = $xeTable.getComputeMaps();
const treeOpts = computeTreeOpts.value;
const childrenField = treeOpts.children || treeOpts.childrenField;
const ganttSlots = $xeGantt.context.slots;
const taskBarSlot = ganttSlots.taskBar || ganttSlots['task-bar'];
const taskBarOverviewSlot = ganttSlots.taskBarOverview || ganttSlots['task-bar-overview'];
const { treeConfig, taskBarMilestoneConfig, taskBarSubviewConfig } = ganttProps;
const { activeLink, activeBarRowid, criticalPathFlag } = ganttReactData;
const { criticalRowMaps } = ganttInternalData;
const titleField = computeTitleField.value;
const progressField = computeProgressField.value;
const typeField = computeTypeField.value;
const taskBarOpts = computeTaskBarOpts.value;
const taskBarMilestoneOpts = computeTaskBarMilestoneOpts.value;
const taskBarSubviewOpts = computeTaskBarSubviewOpts.value;
const { showOverview, barStyle: subBarStyle } = taskBarSubviewOpts;
const scaleUnit = computeScaleUnit.value;
const barParams = {
$gantt: $xeGantt,
source: sourceType$3,
type: viewType$2,
scaleType: scaleUnit,
row,
$rowIndex,
rowIndex,
_rowIndex
};
const { showProgress, showCriticalPath, showContent, contentMethod, barStyle, moveable, showTooltip } = taskBarOpts;
const isBarRowStyle = XEUtils.isFunction(barStyle);
const barStyObj = (barStyle ? (isBarRowStyle ? barStyle(barParams) || undefined : barStyle) : {}) || {};
const barRound = barStyObj.round;
const barBgColor = barStyObj.bgColor;
const barCompletedBgColor = barStyObj.completedBgColor;
const barHtmlStyle = barStyObj.style;
const rowRest = fullAllDataRowIdData[rowid] || {};
const cellHeight = resizeHeightFlag ? getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight) : 0;
let title = getStringValue(XEUtils.get(row, titleField));
const progressValue = showProgress ? Math.min(100, Math.max(0, XEUtils.toNumber(XEUtils.get(row, progressField)))) : 0;
const renderTaskType = getTaskType(XEUtils.get(row, typeField));
const isMilestone = !!(hasEnableConf(taskBarMilestoneConfig, taskBarMilestoneOpts) && hasMilestoneTask(renderTaskType));
const ctParams = Object.assign({}, barParams);
const vbStyle = {};
const vpStyle = {
width: `${progressValue || 0}%`
};
if (!isMilestone) {
if (isBarRowStyle) {
if (barBgColor) {
vbStyle['--vxe-ui-gantt-view-task-bar-background-color'] = barBgColor;
}
if (barCompletedBgColor) {
vbStyle['--vxe-ui-gantt-view-task-bar-completed-background-color'] = barCompletedBgColor;
}
}
}
if (barHtmlStyle) {
XEUtils.assign(vbStyle, barHtmlStyle);
}
let cbVNs = [];
if ($xeGantt.renderGanttTaskBarContent) {
cbVNs = $xeGantt.renderGanttTaskBarContent(ctParams, {
$gantt: $xeGantt,
$table: $xeTable,
rowid
});
}
else {
const isSubview = !!(hasEnableConf(taskBarSubviewConfig, taskBarSubviewOpts) && hasSubviewTask(renderTaskType));
if (contentMethod) {
title = getStringValue(contentMethod({ row, title, scaleType: scaleUnit }));
}
const ctOns = {};
if (showTooltip) {
ctOns.onMouseover = (evnt) => {
const { dragBarRow } = ganttInternalData;
const ttParams = Object.assign({ $event: evnt }, ctParams);
if (!dragBarRow) {
$xeGantt.triggerTaskBarTooltipEvent(evnt, ttParams);
}
$xeGantt.dispatchEvent('task-bar-mouseenter', ttParams, evnt);
};
ctOns.onMouseleave = (evnt) => {
const { dragBarRow } = ganttInternalData;
const ttParams = Object.assign({ $event: evnt }, ctParams);
if (!dragBarRow) {
$xeGantt.handleTaskBarTooltipLeaveEvent(evnt, ttParams);
}
$xeGantt.dispatchEvent('task-bar-mouseleave', ttParams, evnt);
};
}
if (isSubview && treeConfig && rowChildren && rowChildren.length) {
if (isExpandTree) {
if (showOverview) {
cbVNs.push(h('div', {
key: 'vcso',
class: 'vxe-gantt-view--chart-subview-wrapper is--overview'
}, [
h('div', {
key: rowid,
rowid: rowid,
class: ['vxe-gantt-view--chart-subview-row', {
'is--progress': showProgress,
'is--round': barRound,
'is--move': moveable
}]
}, [
h('div', {
rowid: rowid,
class: [taskBarOverviewSlot ? 'vxe-gantt-view--chart-subview-custom-bar' : 'vxe-gantt-view--chart-subview-bar', `is--${renderTaskType}`]
}, [
taskBarOverviewSlot
? h('div', {
key: 'cbc',
class: 'vxe-gantt-view--chart-subview-custom-bar-content-wrapper'
}, $xeGantt.callSlot(taskBarOverviewSlot, barParams))
: h('div', {
class: 'vxe-gantt-view--chart-subview-bar-content-wrapper'
}, [
showContent
? h('div', {
class: 'vxe-gantt-view--chart-content'
}, title)
: renderEmptyElement$1($xeGantt)
])
])
])
]));
}
}
else {
const cbcVNs = [];
XEUtils.eachTree(rowChildren, childRow => {
const childBarParams = {
$gantt: $xeGantt,
source: sourceType$3,
type: viewType$2,
scaleType: scaleUnit,
row: childRow,
$rowIndex: $xeTable.getRowIndex(childRow),
rowIndex: $xeTable.getVMRowIndex(childRow),
_rowIndex: $xeTable.getVTRowIndex(childRow)
};
const isChildBarRowStyle = XEUtils.isFunction(subBarStyle);
const childBarStyObj = XEUtils.assign({}, (barStyle ? (isBarRowStyle ? barStyle(childBarParams) : barStyle) : {}) || {}, (subBarStyle ? (isChildBarRowStyle ? subBarStyle(childBarParams) : subBarStyle) : {}) || {});
const childRound = childBarStyObj.round;
const childBgColor = childBarStyObj.bgColor;
const childCompletedBgColor = childBarStyObj.completedBgColor;
const childBarHtmlStyle = childBarStyObj.style;
const childRowid = $xeTable.getRowid(childRow);
let childTitle = getStringValue(XEUtils.get(childRow, titleField));
const childProgressValue = showProgress ? Math.min(100, Math.max(0, XEUtils.toNumber(XEUtils.get(childRow, progressField)))) : 0;
const childRenderTaskType = getTaskType(XEUtils.get(childRow, typeField));
const isChildMilestone = !!(hasEnableConf(taskBarMilestoneConfig, taskBarMilestoneOpts) && hasMilestoneTask(childRenderTaskType));
const isChildSubview = !!(hasEnableConf(taskBarSubviewConfig, taskBarSubviewOpts) && hasSubviewTask(childRenderTaskType));
if (isChildSubview) {
return;
}
const childVbStyle = {};
const childVpStyle = {
width: `${childProgressValue || 0}%`
};
if (!isChildMilestone) {
if (childBgColor) {
childVbStyle['--vxe-ui-gantt-view-task-bar-background-color'] = childBgColor;
}
if (childCompletedBgColor) {
childVpStyle['--vxe-ui-gantt-view-task-bar-completed-background-color'] = childCompletedBgColor;
}
}
// 已废弃
if (childBarStyObj.top) {
childVbStyle.top = childBarStyObj.top;
}
// 已废弃
if (childBarHtmlStyle) {
XEUtils.assign(childVbStyle, childBarHtmlStyle);
}
const childCtParams = Object.assign({}, childBarParams);
if (contentMethod) {
childTitle = getStringValue(contentMethod({ row: childRow, title: childTitle, scaleType: scaleUnit }));
}
cbcVNs.push(h('div', {
key: childRowid,
rowid: childRowid,
class: ['vxe-gantt-view--chart-subview-row', `is--${childRenderTaskType}`, {
'is--progress': showProgress,
'is--critical': showCriticalPath && criticalPathFlag && criticalRowMaps.has(childRowid),
'is--round': childRound,
'is--move': moveable,
'row--pending': !!pendingRowFlag && !!pendingRowMaps[childRowid]
}]
}, [
h('div', {
rowid: childRowid,
class: [taskBarSlot ? 'vxe-gantt-view--chart-subview-custom-bar' : 'vxe-gantt-view--chart-subview-bar', `is--${childRenderTaskType}`],
style: childVbStyle,
onClick(evnt) {
evnt.stopPropagation();
$xeGantt.handleTaskBarClickEvent(evnt, childCtParams);
},
onDblclick(evnt) {
evnt.stopPropagation();
$xeGantt.handleTaskBarDblclickEvent(evnt, childCtParams);
},
onMousedown(evnt) {
evnt.stopPropagation();
if ($xeGantt.handleTaskBarMousedownEvent) {
$xeGantt.handleTaskBarMousedownEvent(evnt, childCtParams);
}
}
}, [
taskBarSlot
? h('div', Object.assign({ key: 'cbc', class: 'vxe-gantt-view--chart-subview-custom-bar-content-wrapper' }, ctOns), $xeGantt.callSlot(taskBarSlot, childCtParams))
: h('div', Object.assign({ class: 'vxe-gantt-view--chart-subview-bar-content-wrapper' }, ctOns), [
showProgress
? h('div', {
class: 'vxe-gantt-view--chart-progress',
style: childVpStyle
})
: renderEmptyElement$1($xeGantt),
showContent
? h('div', {
class: 'vxe-gantt-view--chart-content'
}, childTitle)
: renderEmptyElement$1($xeGantt)
])
])
]));
}, { children: childrenField });
cbVNs.push(h('div', {
key: 'vcsc',
class: 'vxe-gantt-view--chart-subview-wrapper is--inline'
}, cbcVNs));
}
}
else {
if (taskBarSlot) {
cbVNs.push(h('div', Object.assign({ key: 'cbc', class: 'vxe-gantt-view--chart-custom-bar-content-wrapper' }, ctOns), $xeGantt.callSlot(taskBarSlot, barParams)));
}
else if (isMilestone) {
const { icon, iconStatus, iconStyle } = taskBarMilestoneOpts;
const tbmParams = { $gantt: $xeGantt, row };
cbVNs.push(h('div', Object.assign({ key: 'vcm', class: 'vxe-gantt-view--chart-milestone-wrapper' }, ctOns), [
h('div', {
class: ['vxe-gantt-view--chart-milestone-icon', iconStatus ? `theme--${XEUtils.isFunction(iconStatus) ? iconStatus(tbmParams) : iconStatus}` : ''],
style: iconStyle ? Object.assign({}, XEUtils.isFunction(iconStyle) ? iconStyle(tbmParams) : iconStyle) : undefined
}, [
h('i', {
class: (icon ? (XEUtils.isFunction(icon) ? icon(tbmParams) : icon) : '') || getIcon$1().GANTT_VIEW_TASK_MILESTONE
})
]),
showContent
? h('div', {
class: 'vxe-gantt-view--chart-milestone-content'
}, title)
: renderEmptyElement$1($xeGantt)
]));
}
else {
cbVNs.push(h('div', Object.assign({ key: 'vbc', class: 'vxe-gantt-view--chart-bar-content-wrapper' }, ctOns), [
showProgress
? h('div', {
class: 'vxe-gantt-view--chart-progress',
style: vpStyle
})
: renderEmptyElement$1($xeGantt),
showContent
? h('div', {
class: 'vxe-gantt-view--chart-content'
}, title)
: renderEmptyElement$1($xeGantt)
]));
}
}
}
return h('div', {
key: rowid,
rowid,
class: ['vxe-gantt-view--chart-row', `is--${renderTaskType}`, {
'is--progress': showProgress,
'is--critical': showCriticalPath && criticalPathFlag && criticalRowMaps.has(rowid),
'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid],
'is--round': barRound,
'is--move': moveable
}],
style: {
height: `${cellHeight}px`
},
onDragstart(evnt) {
if (ganttInternalData.dragBarRow) {
evnt.preventDefault();
}
},
onContextmenu(evnt) {
$xeGantt.handleTaskBarContextmenuEvent(evnt, ctParams);
}
}, [
h('div', {
class: [taskBarSlot ? 'vxe-gantt-view--chart-custom-bar' : 'vxe-gantt-view--chart-bar', `is--${renderTaskType}`, {
'is--active': activeBarRowid === rowid,
'active--link': activeLink && (rowid === `${activeLink.from}` || rowid === `${activeLink.to}`)
}],
style: vbStyle,
rowid,
onClick(evnt) {
$xeGantt.handleTaskBarClickEvent(evnt, barParams);
},
onDblclick(evnt) {
$xeGantt.handleTaskBarDblclickEvent(evnt, barParams);
},
onMousedown(evnt) {
if ($xeGantt.handleTaskBarMousedownEvent) {
$xeGantt.handleTaskBarMousedownEvent(evnt, barParams);
}
}
}, cbVNs)
]);
};
const renderTaskRows = ($xeTable, tableData) => {
const tableProps = $xeTable.props;
const { treeConfig } = tableProps;
const tableReactData = $xeTable.reactData;
const { treeExpandedFlag } = tableReactData;
const tableInternalData = $xeTable.internalData;
const { fullAllDataRowIdData, treeExpandedMaps } = tableInternalData;
const { computeTreeOpts } = $xeTable.getComputeMaps();
const treeOpts = computeTreeOpts.value;
const { transform } = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
const { scrollYLoad } = ganttViewReactData;
const trVNs = [];
tableData.forEach((row, $rowIndex) => {
const rowid = $xeTable.getRowid(row);
const rowRest = fullAllDataRowIdData[rowid] || {};
let rowIndex = $rowIndex;
let _rowIndex = -1;
if (rowRest) {
rowIndex = rowRest.index;
_rowIndex = rowRest._index;
}
let isExpandTree = false;
let rowChildren = [];
if (treeConfig) {
rowChildren = row[childrenField];
isExpandTree = !!treeExpandedFlag && rowChildren && rowChildren.length > 0 && !!treeExpandedMaps[rowid];
}
trVNs.push(renderTaskBar($xeTable, row, rowid, rowIndex, $rowIndex, _rowIndex, rowChildren, isExpandTree));
// 如果是树形表格
if (treeConfig && isExpandTree && !scrollYLoad && !transform) {
trVNs.push(...renderTaskRows($xeTable, rowChildren));
}
});
return trVNs;
};
const renderVN = () => {
const $xeTable = ganttViewInternalData.xeTable;
const { slots: ganttSlots } = ganttContext;
const { dragLinkFromStore } = ganttReactData;
const { tableData } = ganttViewReactData;
const taskLinkOpts = computeTaskLinkOpts.value;
const taskBarOpts = computeTaskBarOpts.value;
const nowLineLeft = computeNowLineLeft.value;
const { isCurrent, isHover } = taskLinkOpts;
const { linkCreatable } = taskBarOpts;
const taskNowLineSlot = ganttSlots.taskNowLine || ganttSlots['task-now-line'];
return h('div', {
ref: refElem,
class: ['vxe-gantt-view--chart-wrapper', {
'is--cl-drag': dragLinkFromStore.rowid
}]
}, [
nowLineLeft > 0
? h('div', {
ref: refNowLineElem,
class: 'vxe-gantt-view--chart-now-line',
style: {
left: nowLineLeft + 'px'
}
}, taskNowLineSlot ? taskNowLineSlot({}) : [])
: renderEmptyElement$1($xeGantt),
$xeGantt.renderGanttTaskChartBefores
? h('div', {
ref: refChartBeforeWrapperElem,
class: ['vxe-gantt-view--chart-before-wrapper', {
'link--current': isCurrent,
'link--hover': isHover
}]
}, $xeTable && isEnableConf(taskLinkOpts) ? $xeGantt.renderGanttTaskChartBefores() : [])
: renderEmptyElement$1($xeGantt),
h('div', {
ref: refTaskWrapperElem,
class: ['vxe-gantt-view--chart-task-wrapper', {
'link--current': isCurrent,
'link--create': linkCreatable
}]
}, $xeTable ? renderTaskRows($xeTable, tableData) : []),
$xeGantt.renderGanttTaskChartAfters
? h('div', {
ref: refChartAfterWrapperElem,
class: 'vxe-gantt-view--chart-after-wrapper'
}, $xeTable && isEnableConf(taskLinkOpts) ? $xeGantt.renderGanttTaskChartAfters() : [])
: renderEmptyElement$1($xeGantt)
]);
};
onMounted(() => {
const { elemStore } = ganttViewInternalData;
const prefix = 'main-chart-';
elemStore[`${prefix}now-line`] = refNowLineElem;
elemStore[`${prefix}task-wrapper`] = refTaskWrapperElem;
elemStore[`${prefix}before-wrapper`] = refChartBeforeWrapperElem;
elemStore[`${prefix}after-wrapper`] = refChartAfterWrapperElem;
});
onUnmounted(() => {
const { elemStore } = ganttViewInternalData;
const prefix = 'main-chart-';
elemStore[`${prefix}now-line`] = null;
elemStore[`${prefix}task-wrapper`] = null;
elemStore[`${prefix}before-wrapper`] = null;
elemStore[`${prefix}after-wrapper`] = null;
});
return renderVN;
}
});
const sourceType$2 = 'gantt';
const viewType$1 = 'body';
var GanttViewBodyComponent = defineVxeComponent({
name: 'VxeGanttViewBody',
setup() {
const $xeGantt = inject('$xeGantt', {});
const $xeGanttView = inject('$xeGanttView', {});
const { computeTaskViewOpts, computeScaleUnit } = $xeGantt.getComputeMaps();
const { reactData, internalData } = $xeGanttView;
const refElem = ref();
const refBodyScroll = ref();
const refBodyTable = ref();
const refBodyXSpace = ref();
const refBodyYSpace = ref();
const renderColumn = ($xeTable, row, rowid, rowIndex, $rowIndex, _rowIndex, column, $columnIndex) => {
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, startDateObj, endDateObj } = 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 = [];
if (isAllRowDrag && rowOpts.resizable) {
const cellParams = {
$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$2,
type: viewType$1,
isHidden: false,
isEdit: false,
level: -1,
// 已废弃属性
visibleData: [],
data: [],
items: []
};
tdVNs.push(h('div', {
class: 'vxe-gantt-view-cell--row-resizable',
onMousedown: (evnt) => $xeTable.handleRowResizeMousedownEvent(evnt, cellParams),
onDblclick: (evnt) => $xeTable.handleRowResizeDblclickEvent(evnt, cellParams)
}));
}
const ctParams = {
$gantt: $xeGantt,
source: sourceType$2,
type: viewType$1,
scaleType: scaleUnit,
dateObj,
startDateObj,
endDateObj,
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, tableData) => {
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 = [];
tableData.forEach((row, $rowIndex) => {
const rowid = $xeTable.getRowid(row);
const rowRest = fullAllDataRowIdData[rowid] || {};
const trOns = {};
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) => {
$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$2,
type: viewType$1,
scaleType: scaleUnit,
row,
rowIndex,
$rowIndex,
_rowIndex
};
trVNs.push(h('tr', Object.assign({ 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 = [];
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$2, type: viewType$1, 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;
}
});
const sourceType$1 = 'gantt';
const viewType = 'footer';
var GanttViewFooterComponent = defineVxeComponent({
name: 'VxeGanttViewFooter',
setup() {
const $xeGantt = inject('$xeGantt', {});
const $xeGanttView = inject('$xeGanttView', {});
const { internalData } = $xeGanttView;
const refElem = ref();
const refHeaderScroll = ref();
const renderVN = () => {
return h('div', {
ref: refElem,
class: 'vxe-gantt-view--footer-wrapper',
onContextmenu(evnt) {
$xeGantt.handleTaskFooterContextmenuEvent(evnt, { source: sourceType$1, type: viewType, $rowIndex: -1 });
}
}, [
h('div', {
ref: refHeaderScroll,
class: 'vxe-gantt-view--footer-inner-wrapper'
})
]);
};
onMounted(() => {
const { elemStore } = internalData;
const prefix = 'main-footer-';
elemStore[`${prefix}wrapper`] = refElem;
elemStore[`${prefix}scroll`] = refHeaderScroll;
});
onUnmounted(() => {
const { elemStore } = internalData;
const prefix = 'main-footer-';
elemStore[`${prefix}wrapper`] = null;
elemStore[`${prefix}scroll`] = null;
});
return renderVN;
}
});
const { globalEvents: globalEvents$1 } = VxeUI;
const { FinishToStart, StartToFinish, StartToStart, FinishToFinish } = VxeGanttDependencyType;
const sourceType = 'gantt';
const secondMs = 1000;
const minuteMs = 1000 * 60;
const hourMs = 1000 * 60 * 60;
const dayMs = hourMs * 24;
function getTaskLinkKey(from, to, type) {
return from + '_' + to + '_' + (type || 0);
}
function createInternalData$1() {
return {
xeTable: null,
visibleColumn: [],
startMaps: {},
endMaps: {},
chartMaps: {},
todayDateMaps: {},
elemStore: {},
// 存放横向 X 虚拟滚动相关的信息
scrollXStore: {
preloadSize: 0,
offsetSize: 0,
visibleSize: 0,
visibleStartIndex: 0,
visibleEndIndex: 0,
startIndex: 0,
endIndex: 0
},
// 最后滚动位置
lastScrollTop: 0,
lastScrollLeft: 0
};
}
function createReactData$1() {
return {
// 是否启用了横向 X 可视渲染方式加载
scrollXLoad: false,
// 是否启用了纵向 Y 可视渲染方式加载
scrollYLoad: false,
// 是否存在纵向滚动条
overflowY: true,
// 是否存在横向滚动条
overflowX: true,
// 纵向滚动条的宽度
scrollbarWidth: 0,
// 横向滚动条的高度
scrollbarHeight: 0,
// 最后滚动时间戳
lastScrollTime: 0,
lazScrollLoading: false,
scrollVMLoading: false,
scrollYHeight: 0,
scrollYTop: 0,
isScrollYBig: false,
scrollXLeft: 0,
scrollXWidth: 0,
isScrollXBig: false,
minViewDate: null,
maxViewDate: null,
tableData: [],
tableColumn: [],
headerGroups: [],
viewCellWidth: 40
};
}
const maxYHeight = 5e6;
// const maxXWidth = 5e6
var GanttViewComponent = defineVxeComponent({
name: 'VxeGanttView',
setup(props, context) {
const xID = XEUtils.uniqueId();
const $xeGantt = inject('$xeGantt', {});
const ganttProps = $xeGantt.props;
const ganttReactData = $xeGantt.reactData;
const ganttInternalData = $xeGantt.internalData;
const { computeDateFormat, computeTaskBarOpts, computeTaskViewOpts, computeStartField, computeEndField, computeTypeField, computeScrollbarOpts, computeScrollbarXToTop, computeScrollbarYToLeft, computeScaleUnit, computeWeekScale, computeMinScale, computeTaskNowLineOpts, computeScaleStep } = $xeGantt.getComputeMaps();
const refElem = ref();
const refScrollXVirtualElem = ref();
const refScrollYVirtualElem = ref();
const refScrollXHandleElem = ref();
const refScrollXLeftCornerElem = ref();
const refScrollXRightCornerElem = ref();
const refScrollYHandleElem = ref();
const refScrollYTopCornerElem = ref();
const refScrollXWrapperElem = ref();
const refScrollYWrapperElem = ref();
const refScrollYBottomCornerElem = ref();
const refScrollXSpaceElem = ref();
const refScrollYSpaceElem = ref();
const refColInfoElem = ref();
const reactData = reactive(createReactData$1());
const internalData = createInternalData$1();
const refMaps = {
refElem,
refScrollXHandleElem,
refScrollYHandleElem
};
const computeScaleDateList = computed(() => {
const { minViewDate, maxViewDate } = reactData;
const taskViewOpts = computeTaskViewOpts.value;
const minScale = computeMinScale.value;
const scaleStep = computeScaleStep.value;
const { gridding } = taskViewOpts;
const dateList = [];
if (!minScale || !minViewDate || !maxViewDate) {
return dateList;
}
const { type, startDay } = minScale;
let leftSize = -(ganttReactData.currLeftSpacing + XEUtils.toNumber(gridding ? gridding.leftSpacing || 0 : 0));
let rightSize = ganttReactData.currRightSpacing + XEUtils.toNumber(gridding ? gridding.rightSpacing || 0 : 0);
if (scaleStep > 0) {
leftSize *= scaleStep;
rightSize *= scaleStep;
}
switch (type) {
case 'year': {
let currDate = XEUtils.getWhatYear(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatYear(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatYear(currDate, scaleStep);
}
break;
}
case 'quarter': {
let currDate = XEUtils.getWhatQuarter(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatQuarter(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatQuarter(currDate, scaleStep);
}
break;
}
case 'month': {
let currDate = XEUtils.getWhatMonth(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatMonth(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatMonth(currDate, scaleStep);
}
break;
}
case 'week': {
let currDate = XEUtils.getWhatWeek(minViewDate, leftSize, startDay, startDay);
const endDate = XEUtils.getWhatWeek(maxViewDate, rightSize, startDay, startDay);
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatWeek(currDate, scaleStep);
}
break;
}
case 'day':
case 'date': {
let currDate = XEUtils.getWhatDay(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatDay(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatDay(currDate, scaleStep);
}
break;
}
case 'hour': {
let currDate = XEUtils.getWhatHours(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatHours(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatHours(currDate, scaleStep);
}
break;
}
case 'minute': {
let currDate = XEUtils.getWhatMinutes(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatMinutes(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatMinutes(currDate, scaleStep);
}
break;
}
case 'second': {
let currDate = XEUtils.getWhatSeconds(minViewDate, leftSize, 'first');
const endDate = XEUtils.getWhatSeconds(maxViewDate, rightSize, 'first');
while (currDate <= endDate) {
const itemDate = currDate;
dateList.push(itemDate);
currDate = XEUtils.getWhatSeconds(currDate, scaleStep);
}
break;
}
}
return dateList;
});
const computeNowLineLeft = computed(() => {
const { minViewDate, maxViewDate, viewCellWidth } = reactData;
const { visibleColumn, todayDateMaps } = internalData;
const minScale = computeMinScale.value;
const taskViewOpts = computeTaskViewOpts.value;
const taskNowLineOpts = computeTaskNowLineOpts.value;
const { showNowLine } = taskViewOpts;
const { mode } = taskNowLineOpts;
const { nowTime } = ganttReactData;
// 此刻线
let nlLeft = 0;
if (showNowLine && minScale && minViewDate && maxViewDate && nowTime >= minViewDate.getTime() && nowTime <= maxViewDate.getTime()) {
const todayValue = todayDateMaps[minScale.type];
const todayDate = XEUtils.toStringDate(todayValue);
let currCol = null;
let nextCol = null;
for (let i = 0; i < visibleColumn.length; i++) {
const column = visibleColumn[i];
const { startDateObj, endDateObj } = column;
if (startDateObj.date <= todayDate && endDateObj.date >= todayDate) {
currCol = column;
nlLeft = i * viewCellWidth;
nextCol = visibleColumn[i + 1];
break;
}
}
if (mode === 'progress') {
if (currCol && nextCol) {
const currTime = currCol.dateObj.date.getTime();
const offsetTime = nowTime - currTime;
const nowProgress = Math.max(0, Math.min(1, offsetTime / (nextCol.dateObj.date.getTime() - currTime)));
nlLeft += nowProgress * viewCellWidth;
}
}
else if (mode === 'center') {
nlLeft += viewCellWidth / 2;
}
else if (mode === 'end') {
nlLeft += viewCellWidth - 1;
}
}
return nlLeft;
});
const computeMaps = {
computeScaleDateList,
computeNowLineLeft
};
const $xeGanttView = {
xID,
props,
context,
reactData,
internalData,
getRefMaps: () => refMaps,
getComputeMaps: () => computeMaps
};
const parseStringDate = (dateValue) => {
const dateFormat = computeDateFormat.value;
return XEUtils.toStringDate(dateValue, dateFormat);
};
const updateTodayData = () => {
const { taskScaleList } = ganttReactData;
const minScale = computeMinScale.value;
if (minScale) {
const weekScale = taskScaleList.find(item => item.type === 'week');
const isMinWeek = minScale.type === 'week';
const itemDate = new Date();
let [yyyy, M, MM, dd, HH, mm, ss] = XEUtils.toDateString(itemDate, 'yyyy-M-MM-dd-HH-mm-ss').split('-');
const e = itemDate.getDay();
const E = e + 1;
const q = Math.ceil((itemDate.getMonth() + 1) / 3);
const W = `${XEUtils.getYearWeek(itemDate, weekScale ? weekScale.startDay : undefined)}`;
if (isMinWeek && checkWeekOfsetYear(W, M)) {
yyyy = `${Number(yyyy) + 1}`;
M = '1';
MM = '0' + M;
}
ganttReactData.nowTime = itemDate.getTime();
internalData.todayDateMaps = {
year: yyyy,
quarter: `${yyyy}_q${q}`,
month: `${yyyy}_${MM}`,
week: `${yyyy}_W${W}`,
day: `${yyyy}_${MM}_${dd}_E${E}`,
date: `${yyyy}_${MM}_${dd}`,
hour: `${yyyy}_${MM}_${dd}_${HH}`,
minute: `${yyyy}_${MM}_${dd}_${HH}_${mm}`,
second: `${yyyy}_${MM}_${dd}_${HH}_${mm}_${ss}`
};
}
};
const handleColumnHeader = () => {
const { taskScaleList } = ganttReactData;
const scaleUnit = computeScaleUnit.value;
const minScale = computeMinScale.value;
const weekScale = computeWeekScale.value;
const scaleDateList = computeScaleDateList.value;
const scaleStep = computeScaleStep.value;
const weekStartDay = weekScale ? weekScale.startDay : undefined;
const fullCols = [];
const groupCols = [];
if (minScale && scaleUnit && scaleDateList.length) {
const renderListMaps = {
year: [],
quarter: [],
month: [],
week: [],
day: [],
date: [],
hour: [],
minute: [],
second: []
};
const tempTypeMaps = {
year: {},
quarter: {},
month: {},
week: {},
day: {},
date: {},
hour: {},
minute: {},
second: {}
};
const isMinWeek = minScale.type === 'week';
const handleData = (type, colMaps, minCol) => {
if (minScale.type === type) {
return;
}
const currCol = colMaps[type];
const currKey = `${currCol.field}`;
let currGpCol = tempTypeMaps[type][currKey];
if (!currGpCol) {
currGpCol = currCol;
tempTypeMaps[type][currKey] = currGpCol;
renderListMaps[type].push(currGpCol);
}
if (currGpCol) {
if (!currGpCol.children) {
currGpCol.children = [];
}
currGpCol.children.push(minCol);
}
};
const createDateObj = (date) => {
let [yy, yyyy, M, MM, d, dd, H, HH, m, mm, s, ss] = XEUtils.toDateString(date, 'yy-yyyy-M-MM-d-dd-H-HH-m-mm-s-ss').split('-');
const e = date.getDay();
const E = e + 1;
const q = Math.ceil((date.getMonth() + 1) / 3);
const W = `${XEUtils.getYearWeek(date, weekScale ? weekScale.startDay : undefined)}`;
const WW = XEUtils.padStart(W, 2, '0');
if (isMinWeek && checkWeekOfsetYear(W, M)) {
yyyy = `${Number(yyyy) + 1}`;
M = '1';
MM = '0' + M;
}
return { date, yy, yyyy, M, MM, d, dd, H, HH, m, mm, s, ss, q, W, WW, E, e };
};
for (let i = 0; i < scaleDateList.length; i++) {
const itemDate = scaleDateList[i];
const dateObj = createDateObj(itemDate);
const { yyyy, MM, dd, HH, mm, ss, q, W, E } = dateObj;
const startDateObj = dateObj;
const colMaps = {
year: {
field: yyyy,
title: yyyy,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatYear(itemDate, scaleStep - 1)) : startDateObj
},
quarter: {
field: `${yyyy}_q${q}`,
title: `${q}`,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatQuarter(itemDate, scaleStep - 1)) : startDateObj
},
month: {
field: `${yyyy}_${MM}`,
title: MM,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatMonth(itemDate, scaleStep - 1)) : startDateObj
},
week: {
field: `${yyyy}_W${W}`,
title: `${W}`,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatWeek(itemDate, scaleStep - 1, weekStartDay, weekStartDay)) : startDateObj
},
day: {
field: `${yyyy}_${MM}_${dd}_E${E}`,
title: `${E}`,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatDay(itemDate, scaleStep - 1)) : startDateObj
},
date: {
field: `${yyyy}_${MM}_${dd}`,
title: dd,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatDay(itemDate, scaleStep - 1)) : startDateObj
},
hour: {
field: `${yyyy}_${MM}_${dd}_${HH}`,
title: HH,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatHours(itemDate, scaleStep - 1)) : startDateObj
},
minute: {
field: `${yyyy}_${MM}_${dd}_${HH}_${mm}`,
title: mm,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatMinutes(itemDate, scaleStep - 1)) : startDateObj
},
second: {
field: `${yyyy}_${MM}_${dd}_${HH}_${mm}_${ss}`,
title: ss,
dateObj,
startDateObj,
endDateObj: scaleStep > 1 ? createDateObj(XEUtils.getWhatSeconds(itemDate, scaleStep - 1)) : startDateObj
}
};
const minCol = colMaps[minScale.type];
if (minScale.level < 19) {
handleData('year', colMaps, minCol);
}
if (minScale.level < 17) {
handleData('quarter', colMaps, minCol);
}
if (minScale.level < 15) {
handleData('month', colMaps, minCol);
}
if (minScale.level < 13) {
handleData('week', colMaps, minCol);
}
if (minScale.level < 11) {
handleData('day', colMaps, minCol);
}
if (minScale.level < 9) {
handleData('date', colMaps, minCol);
}
if (minScale.level < 7) {
handleData('hour', colMaps, minCol);
}
if (minScale.level < 5) {
handleData('minute', colMaps, minCol);
}
if (minScale.level < 3) {
handleData('second', colMaps, minCol);
}
fullCols.push(minCol);
}
taskScaleList.forEach(scaleItem => {
if (scaleItem.type === minScale.type) {
groupCols.push({
scaleItem,
columns: fullCols
});
return;
}
const list = renderListMaps[scaleItem.type] || [];
if (list) {
list.forEach(item => {
item.childCount = item.children ? item.children.length : 0;
item.children = undefined;
});
}
groupCols.push({
scaleItem,
columns: list
});
});
}
return {
fullCols,
groupCols
};
};
/**
* 判断周的年份是否跨年
*/
const checkWeekOfsetYear = (W, M) => {
return `${W}` === '1' && `${M}` === '12';
};
/**
* 周维度,由于年份和第几周是冲突的行为,所以需要特殊处理,判断是否跨年,例如
* '2024-12-31' 'yyyy-MM-dd W' >> '2024-12-31 1'
* '2025-01-01' 'yyyy-MM-dd W' >> '2025-01-01 1'
*/
const parseWeekObj = (date, firstDay) => {
const currDate = XEUtils.toStringDate(date);
let yyyy = currDate.getFullYear();
const month = currDate.getMonth();
const weekNum = XEUtils.getYearWeek(currDate, firstDay);
if (checkWeekOfsetYear(weekNum, month + 1)) {
yyyy++;
}
return {
yyyy,
W: weekNum
};
};
const createChartRender = (fullCols) => {
const minScale = computeMinScale.value;
const scaleStep = computeScaleStep.value;
const scaleUnit = computeScaleUnit.value;
const weekScale = computeWeekScale.value;
const dateFormat = computeDateFormat.value;
if (minScale) {
const currRatio = scaleStep > 1 ? 1 / scaleStep : 0;
switch (scaleUnit) {
case 'year': {
const showActualProgress = /M|d|H|m|s|S/.test(dateFormat);
const renderFormat = 'yyyy';
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, 'yyyy');
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatYear(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatYear(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatYear(startValDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatYear(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatYear(endDate, 0, 'first');
// 当前是年维度,当指定解析格式精确到天时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
// 按年的天数比计算
const syDaySize = XEUtils.getDayOfYear(startDate, 0);
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / dayMs / syDaySize;
const eyDaySize = XEUtils.getDayOfYear(endDate, 0);
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / dayMs / eyDaySize;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'quarter': {
const showActualProgress = /M|d|H|m|ss|S/.test(dateFormat);
const renderFormat = 'yyyy-q';
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatQuarter(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatQuarter(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatQuarter(startValDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatQuarter(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatQuarter(endDate, 0, 'first');
// 当前是季度维度,当指定解析格式精确到天时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
// 按季度天数比计算
const sqDaySize = XEUtils.getDayOfQuarter(startDate, 0);
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / dayMs / sqDaySize;
const eqDaySize = XEUtils.getDayOfQuarter(endDate, 0);
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / dayMs / eqDaySize;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'month': {
const renderFormat = 'yyyy-MM';
const showActualProgress = /d|H|m|ss|S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatMonth(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatMonth(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatMonth(startValDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatMonth(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatMonth(endDate, 0, 'first');
// 当前是月维度,当指定解析格式精确到天时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
// 按月天数比计算
const smDaySize = XEUtils.getDayOfMonth(startDate, 0);
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / dayMs / smDaySize;
const emDaySize = XEUtils.getDayOfMonth(endDate, 0);
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / dayMs / emDaySize;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'week': {
const weekStartDay = weekScale ? weekScale.startDay : undefined;
const showActualProgress = /d|H|m|s|S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = `${dateObj.yyyy}-${dateObj.W}`;
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const offsetDate = XEUtils.getWhatWeek(dateObj.date, scaleStep - currStep, weekStartDay, weekStartDay);
let [yyyy, M] = XEUtils.toDateString(offsetDate, 'yyyy-M-MM-dd-HH-mm-ss').split('-');
const W = `${XEUtils.getYearWeek(offsetDate, weekScale ? weekScale.startDay : undefined)}`;
if (checkWeekOfsetYear(W, M)) {
yyyy = `${Number(yyyy) + 1}`;
}
const currStr = `${yyyy}-${W}`;
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatWeek(startValDate, 0, 'first', weekStartDay);
const startWeekObj = parseWeekObj(startDate, weekStartDay);
const startStr = `${startWeekObj.yyyy}-${startWeekObj.W}`;
const startFirstDate = XEUtils.getWhatWeek(startDate, 0, 'first', weekStartDay);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatWeek(endValDate, 0, 'first', weekStartDay);
const endWeekObj = parseWeekObj(endDate, weekStartDay);
const endStr = `${endWeekObj.yyyy}-${endWeekObj.W}`;
const endFirstDate = XEUtils.getWhatWeek(endDate, 0, 'first', weekStartDay);
// 当前是周维度,当指定解析格式精确到天时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
// 按周天数比计算
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / dayMs / 7;
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / dayMs / 7;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'day':
case 'date': {
const renderFormat = 'yyyy-MM-dd';
const showActualProgress = /H|m|s|S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatDay(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatDay(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatDay(startDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatDay(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatDay(endDate, 0, 'first');
// 当前是天维度,当指定解析格式精确到时分秒豪秒时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / dayMs;
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / dayMs;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'hour': {
const renderFormat = 'yyyy-MM-dd HH';
const showActualProgress = /m|s|S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatHours(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatHours(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatHours(startDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatHours(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatHours(endDate, 0, 'first');
// 当前是小时维度,当指定解析格式精确到分秒豪秒时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / hourMs;
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / hourMs;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'minute': {
const renderFormat = 'yyyy-MM-dd HH:mm';
const showActualProgress = /s|S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatMinutes(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatMinutes(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatMinutes(startDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatMinutes(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatMinutes(endDate, 0, 'first');
// 当前是分钟维度,当指定解析格式精确到秒豪秒时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / minuteMs;
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / minuteMs;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
case 'second': {
const renderFormat = 'yyyy-MM-dd HH:mm:ss';
const showActualProgress = /S/.test(dateFormat);
const indexMaps = {};
fullCols.forEach(({ dateObj }, i) => {
const currStr = XEUtils.toDateString(dateObj.date, renderFormat);
indexMaps[currStr] = i;
if (currRatio) {
let currStep = scaleStep - 1;
while (currStep) {
const currStr = XEUtils.toDateString(XEUtils.getWhatSeconds(dateObj.date, scaleStep - currStep), renderFormat);
indexMaps[currStr] = i + ((scaleStep - currStep) * currRatio);
currStep--;
}
}
});
return (startValue, endValue) => {
const startValDate = parseStringDate(startValue);
const endValDate = parseStringDate(endValue);
const startStr = XEUtils.toDateString(startValDate, renderFormat);
const startDate = showActualProgress ? startValDate : XEUtils.getWhatSeconds(startValDate, 0, 'first');
const startFirstDate = XEUtils.getWhatSeconds(startDate, 0, 'first');
const endStr = XEUtils.toDateString(endValDate, renderFormat);
const endDate = showActualProgress ? endValDate : XEUtils.getWhatSeconds(endValDate, 0, 'last');
const endFirstDate = XEUtils.getWhatSeconds(endDate, 0, 'first');
// 当前是秒维度,当指定解析格式精确到豪秒时,显示实际进度
let startSubtractSize = 0;
let endSubtractSize = 1;
if (showActualProgress) {
startSubtractSize = (startDate.getTime() - startFirstDate.getTime()) / secondMs;
endSubtractSize = (endDate.getTime() - endFirstDate.getTime()) / secondMs;
if (currRatio) {
startSubtractSize *= currRatio;
endSubtractSize *= currRatio;
}
}
const offsetLeftSize = (indexMaps[startStr] || 0) + startSubtractSize;
return {
offsetLeftSize,
offsetWidthSize: (indexMaps[endStr] || 0) - offsetLeftSize + endSubtractSize
};
};
}
}
}
return () => {
return {
offsetLeftSize: 0,
offsetWidthSize: 0
};
};
};
const handleParseColumn = () => {
const ganttProps = $xeGantt.props;
const { treeConfig } = ganttProps;
const { minViewDate, maxViewDate } = reactData;
const { fullCols, groupCols } = handleColumnHeader();
if (minViewDate && maxViewDate && fullCols.length) {
const $xeTable = internalData.xeTable;
if ($xeTable) {
const startField = computeStartField.value;
const endField = computeEndField.value;
const typeField = computeTypeField.value;
const { computeAggregateOpts, computeTreeOpts } = $xeTable.getComputeMaps();
const tableReactData = $xeTable.reactData;
const { isRowGroupStatus } = tableReactData;
const tableInternalData = $xeTable.internalData;
const { afterFullData, afterTreeFullData, afterGroupFullData } = tableInternalData;
const aggregateOpts = computeAggregateOpts.value;
const treeOpts = computeTreeOpts.value;
const { transform } = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
const ctMaps = {};
const renderFn = createChartRender(fullCols);
const handleParseRender = (row) => {
const rowid = $xeTable.getRowid(row);
let startValue = XEUtils.get(row, startField);
let endValue = XEUtils.get(row, endField);
const renderTaskType = getTaskType(XEUtils.get(row, typeField));
const isMilestone = hasMilestoneTask(renderTaskType);
const isSubview = hasSubviewTask(renderTaskType);
if (isMilestone) {
if (!startValue) {
startValue = endValue;
}
endValue = startValue;
}
if (isSubview) {
ctMaps[rowid] = {
row,
rowid,
oLeftSize: 0,
oWidthSize: 0
};
}
else if (startValue && endValue) {
const { offsetLeftSize, offsetWidthSize } = renderFn(startValue, endValue);
ctMaps[rowid] = {
row,
rowid,
oLeftSize: offsetLeftSize,
oWidthSize: offsetWidthSize
};
}
};
if (isRowGroupStatus) {
// 行分组
const mapChildrenField = aggregateOpts.mapChildrenField;
if (mapChildrenField) {
XEUtils.eachTree(afterGroupFullData, handleParseRender, { children: mapChildrenField });
}
}
else if (treeConfig) {
// 树结构
XEUtils.eachTree(afterTreeFullData, handleParseRender, { children: transform ? treeOpts.mapChildrenField : childrenField });
}
else {
afterFullData.forEach(handleParseRender);
}
internalData.chartMaps = ctMaps;
}
}
internalData.visibleColumn = fullCols;
reactData.headerGroups = groupCols;
updateTodayData();
updateScrollXStatus();
handleTableColumn();
};
const handleUpdateData = () => {
const { linkList } = ganttReactData;
const { treeConfig } = ganttProps;
const { scrollXStore } = internalData;
const $xeTable = internalData.xeTable;
const sdMaps = {};
const edMaps = {};
let minDate = null;
let maxDate = null;
const allList = [];
if ($xeTable) {
const startField = computeStartField.value;
const endField = computeEndField.value;
const typeField = computeTypeField.value;
const { computeAggregateOpts, computeTreeOpts } = $xeTable.getComputeMaps();
const tableReactData = $xeTable.reactData;
const { isRowGroupStatus } = tableReactData;
const tableInternalData = $xeTable.internalData;
const { afterFullData, afterTreeFullData, afterGroupFullData } = tableInternalData;
const aggregateOpts = computeAggregateOpts.value;
const treeOpts = computeTreeOpts.value;
const { transform } = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
const handleMinMaxData = (row) => {
let startValue = XEUtils.get(row, startField);
let endValue = XEUtils.get(row, endField);
const typeValue = XEUtils.get(row, typeField);
const isMilestone = hasMilestoneTask(typeValue);
if (!startValue) {
startValue = endValue;
}
if (isMilestone || !endValue) {
endValue = startValue;
}
if (startValue) {
const startDate = parseStringDate(startValue);
if (!minDate || minDate.getTime() > startDate.getTime()) {
minDate = startDate;
}
}
if (endValue) {
const endDate = parseStringDate(endValue);
if (!maxDate || maxDate.getTime() < endDate.getTime()) {
maxDate = endDate;
}
}
allList.push(row);
};
if (isRowGroupStatus) {
// 行分组
const mapChildrenField = aggregateOpts.mapChildrenField;
if (mapChildrenField) {
XEUtils.eachTree(afterGroupFullData, handleMinMaxData, { children: mapChildrenField });
}
}
else if (treeConfig) {
// 树结构
XEUtils.eachTree(afterTreeFullData, handleMinMaxData, { children: transform ? treeOpts.mapChildrenField : childrenField });
}
else {
afterFullData.forEach(handleMinMaxData);
}
}
scrollXStore.startIndex = 0;
scrollXStore.endIndex = Math.max(1, scrollXStore.visibleSize);
reactData.minViewDate = minDate;
reactData.maxViewDate = maxDate;
internalData.startMaps = sdMaps;
internalData.endMaps = edMaps;
handleParseColumn();
handleCriticalPath(allList, linkList);
};
/**
* 正向:后置 ES 的下连接线
*/
function forwardCriticalPathLowerBound(linkType, predES, predEF, duration) {
switch (linkType) {
case FinishToStart:
return predEF;
case StartToFinish:
return predES - duration;
case StartToStart:
return predES;
case FinishToFinish:
return predEF - duration;
default:
return 0;
}
}
/**
* 反向:前置 LF 的上连接线
*/
function backwardCriticalPathUpperBound(linkType, succLS, succLF, duration) {
switch (linkType) {
case FinishToStart:
return succLS;
case StartToFinish:
return succLF + duration;
case StartToStart:
return succLS + duration;
case FinishToFinish:
return succLF;
default:
return -1;
}
}
/**
* 关键边:两端都关键时,约束是否连接
*/
function isCriticalPathLinkTight(linkType, fromES, fromEF, toES, toEF, tolerance) {
switch (linkType) {
case FinishToStart:
return Math.abs(fromEF - toES) < tolerance;
case StartToFinish:
return Math.abs(fromES - toEF) < tolerance;
case StartToStart:
return Math.abs(fromES - toES) < tolerance;
case FinishToFinish:
return Math.abs(fromEF - toEF) < tolerance;
default:
return false;
}
}
function handleCriticalPath(data, links) {
const taskBarOpts = computeTaskBarOpts.value;
const $xeTable = internalData.xeTable;
const criticalRowList = [];
const criticalRowMaps = new Map();
const criticalLinkKeyMaps = new Map();
ganttInternalData.criticalRowList = criticalRowList;
ganttInternalData.criticalRowMaps = criticalRowMaps;
ganttInternalData.criticalLinkKeyMaps = criticalLinkKeyMaps;
if (!taskBarOpts.showCriticalPath || !links.length || !data.length || !$xeTable) {
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
ganttReactData.criticalPathFlag++;
}
ganttReactData.criticalLinks = [];
ganttReactData.criticalRowIds = [];
return;
}
const { chartMaps } = internalData;
const tolerance = 1e-6;
const nodeMap = new Map();
for (const row of data) {
const rowid = $xeTable.getRowid(row);
const chartRest = chartMaps[rowid];
nodeMap.set(rowid, {
row,
rowid: rowid,
duration: chartRest ? chartRest.oWidthSize : 0,
incoming: [],
outgoing: [],
indeg: 0,
ES: 0,
EF: 0,
LS: 0,
LF: 0
});
}
// 边界
const linkList = [];
for (const link of links) {
const fromKey = '' + link.from;
const toKey = '' + link.to;
if (!nodeMap.has(fromKey) || !nodeMap.has(toKey) || fromKey === toKey) {
continue;
}
const lkItemitem = {
from: link.from,
to: link.to,
type: XEUtils.toNumber(link.type) || 0,
raw: link
};
linkList.push(lkItemitem);
const toObjItem = nodeMap.get('' + link.to);
const fromObjItem = nodeMap.get('' + link.from);
if (fromObjItem) {
fromObjItem.outgoing.push(lkItemitem);
}
if (toObjItem) {
toObjItem.incoming.push(lkItemitem);
toObjItem.indeg++;
}
}
// 拓扑排序 + 环检测
const queueList = [];
nodeMap.forEach(nodeitem => {
if (nodeitem.indeg === 0) {
queueList.push(nodeitem);
}
});
const orderList = [];
for (let head = 0; head < queueList.length; head++) {
const node = queueList[head];
orderList.push(node);
for (const lkItemitem of node.outgoing) {
const toObjItem = nodeMap.get('' + lkItemitem.to);
if (toObjItem) {
const nextDeg = toObjItem.indeg - 1;
toObjItem.indeg = nextDeg;
if (nextDeg === 0) {
queueList.push(nodeMap.get('' + lkItemitem.to));
}
}
}
}
if (orderList.length !== nodeMap.size) {
// 异常数据,依赖图中存在环
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
ganttReactData.criticalPathFlag++;
}
ganttReactData.criticalLinks = [];
ganttReactData.criticalRowIds = [];
return;
}
// 正向:ES / EF
let criticalDuration = 0;
for (const node of orderList) {
let earliestStart = 0;
for (const lkItem of node.incoming) {
const fromObjItem = nodeMap.get('' + lkItem.from);
if (fromObjItem) {
const need = forwardCriticalPathLowerBound(lkItem.type, fromObjItem.ES, fromObjItem.EF, node.duration);
if (need > earliestStart) {
earliestStart = need;
}
}
}
node.ES = earliestStart;
node.EF = earliestStart + node.duration;
if (node.EF > criticalDuration) {
criticalDuration = node.EF;
}
}
// 反向:LS / LF
for (let i = orderList.length - 1; i >= 0; i--) {
const node = orderList[i];
let latestFinish = criticalDuration;
for (const lkItem of node.outgoing) {
const toObjItem = nodeMap.get('' + lkItem.to);
if (toObjItem) {
const need = backwardCriticalPathUpperBound(lkItem.type, toObjItem.LS, toObjItem.LF, node.duration);
if (need < latestFinish) {
latestFinish = need;
}
}
}
node.LF = latestFinish;
node.LS = latestFinish - node.duration;
}
// 关键任务
const criticalSet = new Set();
const criticalRowIds = [];
for (const nodeItem of orderList) {
if (Math.abs(nodeItem.LS - nodeItem.ES) < tolerance) {
criticalSet.add(nodeItem.rowid);
criticalRowIds.push(nodeItem.rowid);
criticalRowList.push(nodeItem.row);
criticalRowMaps.set(nodeItem.rowid, nodeItem.row);
}
}
// 关键连接线
const criticalLinks = [];
for (const lkItem of linkList) {
const toObjItem = nodeMap.get('' + lkItem.to);
const fromObjItem = nodeMap.get('' + lkItem.from);
if (!toObjItem || !fromObjItem) {
continue;
}
// 两端必须都是关键任务
if (!criticalSet.has(fromObjItem.rowid) || !criticalSet.has(toObjItem.rowid)) {
continue;
}
// 约束必须是连接的
if (isCriticalPathLinkTight(lkItem.type, fromObjItem.ES, fromObjItem.EF, toObjItem.ES, toObjItem.EF, tolerance)) {
criticalLinks.push(lkItem.raw);
criticalLinkKeyMaps.set(getTaskLinkKey(lkItem.from, lkItem.to, lkItem.type), lkItem.raw);
}
}
ganttReactData.criticalLinks = criticalLinks;
ganttReactData.criticalRowIds = criticalRowIds;
ganttReactData.criticalPathFlag++;
}
const calcScrollbar = () => {
const { scrollXWidth, scrollYHeight } = reactData;
const { elemStore } = internalData;
const scrollbarOpts = computeScrollbarOpts.value;
const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper']);
const xHandleEl = refScrollXHandleElem.value;
const yHandleEl = refScrollYHandleElem.value;
let overflowY = false;
let overflowX = false;
if (bodyWrapperElem) {
overflowY = scrollYHeight > bodyWrapperElem.clientHeight;
if (yHandleEl) {
const scrollbarWidth = scrollbarOpts.width || (yHandleEl.offsetWidth - yHandleEl.clientWidth) || 14;
reactData.scrollbarWidth = scrollbarWidth;
ganttReactData.scrollbarWidth = scrollbarWidth;
}
reactData.overflowY = overflowY;
ganttReactData.overflowY = overflowY;
overflowX = scrollXWidth > bodyWrapperElem.clientWidth;
if (xHandleEl) {
const scrollbarHeight = scrollbarOpts.height || (xHandleEl.offsetHeight - xHandleEl.clientHeight) || 14;
reactData.scrollbarHeight = scrollbarHeight;
ganttReactData.scrollbarHeight = scrollbarHeight;
}
reactData.overflowX = overflowX;
ganttReactData.overflowX = overflowX;
}
};
const handleSubTaskMinMaxSize = ($xeTable, list) => {
const { chartMaps } = internalData;
const { computeTreeOpts } = $xeTable.getComputeMaps();
const treeOpts = computeTreeOpts.value;
const childrenField = treeOpts.children || treeOpts.childrenField;
const typeField = computeTypeField.value;
let minChildLeftSize = 0;
let maxChildLeftSize = 0;
XEUtils.eachTree(list, childRow => {
const childRowid = $xeTable.getRowid(childRow);
const renderTaskType = XEUtils.get(childRow, typeField);
if (hasSubviewTask(renderTaskType)) {
return;
}
const childChartRest = childRowid ? chartMaps[childRowid] : null;
if (childChartRest) {
maxChildLeftSize = Math.max(maxChildLeftSize, childChartRest.oLeftSize + childChartRest.oWidthSize);
minChildLeftSize = minChildLeftSize ? Math.min(minChildLeftSize, childChartRest.oLeftSize) : childChartRest.oLeftSize;
}
}, { children: childrenField });
return {
minSize: minChildLeftSize,
maxSize: maxChildLeftSize
};
};
const updateTaskChartStyle = () => {
const { dragBarRow } = ganttInternalData;
const { viewCellWidth } = reactData;
const { elemStore, chartMaps } = internalData;
const $xeTable = internalData.xeTable;
const chartWrapper = getRefElem(elemStore['main-chart-task-wrapper']);
if (chartWrapper && $xeTable) {
const { computeTreeOpts } = $xeTable.getComputeMaps();
const treeOpts = computeTreeOpts.value;
const childrenField = treeOpts.children || treeOpts.childrenField;
XEUtils.arrayEach(chartWrapper.children, (rowEl) => {
const barEl = rowEl.children[0];
if (!barEl) {
return;
}
const rowid = rowEl.getAttribute('rowid');
if (dragBarRow && $xeTable.getRowid(dragBarRow) === rowid) {
return;
}
const chartRest = rowid ? chartMaps[rowid] : null;
const row = chartRest ? chartRest.row : null;
// 子任务视图
if (hasClass(barEl, 'is--subview')) {
const childWrapperEl = barEl.firstElementChild;
if (childWrapperEl) {
// 行内展示
if (hasClass(childWrapperEl, 'is--inline')) {
XEUtils.arrayEach(childWrapperEl.children, (childRowEl) => {
const childBarEl = childRowEl.children[0];
const childRowid = childBarEl.getAttribute('rowid') || '';
const childChartRest = childRowid ? chartMaps[childRowid] : null;
if (childChartRest) {
const childRow = childChartRest.row;
// 如果是子视图
if (hasClass(childBarEl, 'is--subview')) {
const subChildren = childRow[childrenField];
const { minSize: minChildLeftSize, maxSize: maxChildLeftSize } = handleSubTaskMinMaxSize($xeTable, subChildren);
childBarEl.style.left = `${viewCellWidth * minChildLeftSize}px`;
childBarEl.style.width = `${viewCellWidth * (maxChildLeftSize - minChildLeftSize)}px`;
}
else {
childBarEl.style.left = `${getTaskBarLeft(childChartRest, viewCellWidth)}px`;
if (!hasClass(childBarEl, 'is--milestone')) {
// 里程碑不需要宽度
childBarEl.style.width = `${getTaskBarWidth(childChartRest, viewCellWidth)}px`;
}
}
}
});
}
else {
// 如果展开子任务
const childRowEl = childWrapperEl.children[0];
const childBarEl = childRowEl ? childRowEl.children[0] : null;
if (childBarEl) {
const rowChildren = row ? row[childrenField] : [];
const { minSize: minChildLeftSize, maxSize: maxChildLeftSize } = handleSubTaskMinMaxSize($xeTable, rowChildren);
childBarEl.style.left = `${viewCellWidth * minChildLeftSize}px`;
childBarEl.style.width = `${viewCellWidth * (maxChildLeftSize - minChildLeftSize)}px`;
}
}
}
}
else {
barEl.style.left = `${getTaskBarLeft(chartRest, viewCellWidth)}px`;
// 里程碑不需要宽度
if (!hasClass(barEl, 'is--milestone')) {
barEl.style.width = `${getTaskBarWidth(chartRest, viewCellWidth)}px`;
}
}
});
}
return nextTick();
};
const updateStyle = () => {
const { showLeftView } = ganttReactData;
const { scrollbarWidth, scrollbarHeight, headerGroups, tableColumn } = reactData;
const { elemStore, visibleColumn } = internalData;
const $xeTable = internalData.xeTable;
const el = refElem.value;
if (!el) {
return;
}
if (!$xeGantt) {
return;
}
const scrollbarOpts = computeScrollbarOpts.value;
const scrollbarXToTop = computeScrollbarXToTop.value;
const scrollbarYToLeft = computeScrollbarYToLeft.value;
const xLeftCornerEl = refScrollXLeftCornerElem.value;
const xRightCornerEl = refScrollXRightCornerElem.value;
const scrollXVirtualEl = refScrollXVirtualElem.value;
let osbWidth = scrollbarWidth;
const osbHeight = scrollbarHeight;
let tbHeight = 0;
let tHeaderHeight = 0;
let tFooterHeight = 0;
if ($xeTable) {
const tableInternalData = $xeTable.internalData;
tbHeight = tableInternalData.tBodyHeight;
tHeaderHeight = tableInternalData.tHeaderHeight;
tFooterHeight = tableInternalData.tFooterHeight;
}
let yScrollbarVisible = 'visible';
if ((scrollbarYToLeft && showLeftView) || (scrollbarOpts.y && scrollbarOpts.y.visible === false)) {
osbWidth = 0;
yScrollbarVisible = 'hidden';
}
const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
if (headerScrollElem) {
headerScrollElem.style.height = `${tHeaderHeight}px`;
headerScrollElem.style.setProperty('--vxe-ui-gantt-view-cell-height', `${tHeaderHeight / headerGroups.length}px`);
}
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (bodyScrollElem) {
bodyScrollElem.style.height = `${tbHeight}px`;
}
const footerScrollElem = getRefElem(elemStore['main-footer-scroll']);
if (footerScrollElem) {
footerScrollElem.style.height = `${tFooterHeight}px`;
}
if (scrollXVirtualEl) {
scrollXVirtualEl.style.height = `${osbHeight}px`;
scrollXVirtualEl.style.visibility = 'visible';
}
const xWrapperEl = refScrollXWrapperElem.value;
if (xWrapperEl) {
xWrapperEl.style.left = scrollbarXToTop ? `${osbWidth}px` : '';
xWrapperEl.style.width = `${el.clientWidth - osbWidth}px`;
}
if (xLeftCornerEl) {
xLeftCornerEl.style.width = scrollbarXToTop ? `${osbWidth}px` : '';
xLeftCornerEl.style.display = scrollbarXToTop ? (osbHeight ? 'block' : '') : '';
}
if (xRightCornerEl) {
xRightCornerEl.style.width = scrollbarXToTop ? '' : `${osbWidth}px`;
xRightCornerEl.style.display = scrollbarXToTop ? '' : (osbHeight ? 'block' : '');
}
const scrollYVirtualEl = refScrollYVirtualElem.value;
if (scrollYVirtualEl) {
scrollYVirtualEl.style.width = `${osbWidth}px`;
scrollYVirtualEl.style.height = `${tbHeight + tHeaderHeight + tFooterHeight}px`;
scrollYVirtualEl.style.visibility = yScrollbarVisible;
}
const yTopCornerEl = refScrollYTopCornerElem.value;
if (yTopCornerEl) {
yTopCornerEl.style.height = `${tHeaderHeight}px`;
yTopCornerEl.style.display = tHeaderHeight ? 'block' : '';
}
const yWrapperEl = refScrollYWrapperElem.value;
if (yWrapperEl) {
yWrapperEl.style.height = `${tbHeight}px`;
yWrapperEl.style.top = `${tHeaderHeight}px`;
}
const yBottomCornerEl = refScrollYBottomCornerElem.value;
if (yBottomCornerEl) {
yBottomCornerEl.style.height = `${tFooterHeight}px`;
yBottomCornerEl.style.top = `${tHeaderHeight + tbHeight}px`;
yBottomCornerEl.style.display = tFooterHeight ? 'block' : '';
}
const colInfoElem = refColInfoElem.value;
let viewCellWidth = 40;
if (colInfoElem) {
viewCellWidth = colInfoElem.clientWidth || 40;
}
let viewTableWidth = viewCellWidth;
if (visibleColumn.length) {
viewTableWidth = Math.max(0, viewCellWidth * visibleColumn.length);
if (bodyScrollElem) {
const viewWidth = bodyScrollElem.clientWidth;
const remainWidth = viewWidth - viewTableWidth;
if (remainWidth > 0) {
viewCellWidth += Math.max(0, remainWidth / visibleColumn.length);
viewTableWidth = viewWidth;
}
}
}
reactData.viewCellWidth = viewCellWidth;
const headerTableElem = getRefElem(elemStore['main-header-table']);
const bodyTableElem = getRefElem(elemStore['main-body-table']);
const vmTableWidth = viewCellWidth * tableColumn.length;
if (headerTableElem) {
headerTableElem.style.width = `${viewTableWidth}px`;
}
if (bodyTableElem) {
bodyTableElem.style.width = `${vmTableWidth}px`;
}
reactData.scrollXWidth = viewTableWidth;
return Promise.all([
updateTaskChartStyle(),
$xeGantt.handleUpTaskLinkStyle ? $xeGantt.handleUpTaskLinkStyle($xeGanttView) : null
]);
};
const handleRecalculateStyle = () => {
const el = refElem.value;
internalData.rceRunTime = Date.now();
if (!el || !el.clientWidth) {
return nextTick();
}
if (!$xeGantt) {
return nextTick();
}
calcScrollbar();
updateStyle();
return computeScrollLoad();
};
const handleLazyRecalculate = () => {
return new Promise(resolve => {
const { rceTimeout, rceRunTime } = internalData;
const $xeTable = internalData.xeTable;
let refreshDelay = 30;
if ($xeTable) {
const { computeResizeOpts } = $xeTable.getComputeMaps();
const resizeOpts = computeResizeOpts.value;
refreshDelay = resizeOpts.refreshDelay || refreshDelay;
}
if (rceTimeout) {
clearTimeout(rceTimeout);
if (rceRunTime && rceRunTime + (refreshDelay - 5) < Date.now()) {
resolve(handleRecalculateStyle());
}
else {
nextTick(() => {
resolve();
});
}
}
else {
resolve(handleRecalculateStyle());
}
internalData.rceTimeout = setTimeout(() => {
internalData.rceTimeout = undefined;
handleRecalculateStyle();
}, refreshDelay);
});
};
const computeScrollLoad = () => {
return nextTick().then(() => {
const { scrollXLoad } = reactData;
const { scrollXStore } = internalData;
// 计算 X 逻辑
if (scrollXLoad) {
const { toVisibleIndex: toXVisibleIndex, visibleSize: visibleXSize } = handleVirtualXVisible();
const offsetXSize = 2;
scrollXStore.preloadSize = 1;
scrollXStore.offsetSize = offsetXSize;
scrollXStore.visibleSize = visibleXSize;
scrollXStore.endIndex = Math.max(scrollXStore.startIndex + scrollXStore.visibleSize + offsetXSize, scrollXStore.endIndex);
scrollXStore.visibleStartIndex = Math.max(scrollXStore.startIndex, toXVisibleIndex);
scrollXStore.visibleEndIndex = Math.min(scrollXStore.endIndex, toXVisibleIndex + visibleXSize);
updateScrollXData().then(() => {
loadScrollXData();
});
}
else {
updateScrollXSpace();
}
});
};
const handleVirtualXVisible = () => {
const { viewCellWidth } = reactData;
const { elemStore } = internalData;
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (bodyScrollElem) {
const clientWidth = bodyScrollElem.clientWidth;
const scrollLeft = bodyScrollElem.scrollLeft;
const toVisibleIndex = Math.floor(scrollLeft / viewCellWidth) - 1;
const visibleSize = Math.ceil(clientWidth / viewCellWidth) + 1;
return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(1, visibleSize) };
}
return { toVisibleIndex: 0, visibleSize: 6 };
};
const loadScrollXData = () => {
const { isScrollXBig } = reactData;
const { scrollXStore } = internalData;
const { preloadSize, startIndex, endIndex, offsetSize } = scrollXStore;
const { toVisibleIndex, visibleSize } = handleVirtualXVisible();
const offsetItem = {
startIndex: Math.max(0, isScrollXBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
endIndex: isScrollXBig ? toVisibleIndex + visibleSize : toVisibleIndex + visibleSize + offsetSize + preloadSize
};
scrollXStore.visibleStartIndex = toVisibleIndex - 1;
scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize + 1;
const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem;
if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
scrollXStore.startIndex = offsetStartIndex;
scrollXStore.endIndex = offsetEndIndex;
updateScrollXData();
}
}
};
const updateScrollXData = () => {
handleTableColumn();
updateScrollXSpace();
return nextTick();
};
const updateScrollXStatus = () => {
const scrollXLoad = true;
reactData.scrollXLoad = scrollXLoad;
return scrollXLoad;
};
const handleTableColumn = () => {
const { scrollXLoad } = reactData;
const { visibleColumn, scrollXStore } = internalData;
const tableColumn = scrollXLoad ? visibleColumn.slice(scrollXStore.startIndex, scrollXStore.endIndex) : visibleColumn.slice(0);
reactData.tableColumn = tableColumn;
};
const updateScrollXSpace = () => {
const { scrollXLoad, scrollXWidth, viewCellWidth } = reactData;
const { elemStore, scrollXStore } = internalData;
const bodyTableElem = getRefElem(elemStore['main-body-table']);
// const headerTableElem = getRefElem(elemStore['main-header-table'])
// const footerTableElem = getRefElem(elemStore['main-footer-table'])
const { startIndex } = scrollXStore;
let xSpaceLeft = 0;
if (scrollXLoad) {
xSpaceLeft = Math.max(0, startIndex * viewCellWidth);
}
// if (headerTableElem) {
// headerTableElem.style.transform = `translate(${xSpaceLeft}px, 0px)`
// }
if (bodyTableElem) {
bodyTableElem.style.transform = `translate(${xSpaceLeft}px, ${reactData.scrollYTop || 0}px)`;
}
// if (footerTableElem) {
// footerTableElem.style.transform = `translate(${xSpaceLeft}px, 0px)`
// }
const ySpaceWidth = scrollXWidth;
const layoutList = ['header', 'body', 'footer'];
layoutList.forEach(layout => {
const xSpaceElem = getRefElem(elemStore[`main-${layout}-xSpace`]);
if (xSpaceElem) {
xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : '';
}
});
const scrollXSpaceEl = refScrollXSpaceElem.value;
if (scrollXSpaceEl) {
scrollXSpaceEl.style.width = `${ySpaceWidth}px`;
}
const beforeWrapper = getRefElem(elemStore['main-chart-before-wrapper']);
const beforeSvgElem = beforeWrapper ? beforeWrapper.firstElementChild : null;
if (beforeSvgElem) {
beforeSvgElem.style.width = `${ySpaceWidth}px`;
}
const afterWrapper = getRefElem(elemStore['main-chart-after-wrapper']);
const afterSvgElem = afterWrapper ? afterWrapper.firstElementChild : null;
if (afterSvgElem) {
afterSvgElem.style.width = `${ySpaceWidth}px`;
}
reactData.scrollXLeft = xSpaceLeft;
reactData.scrollXWidth = ySpaceWidth;
calcScrollbar();
return nextTick();
};
const triggerScrollXEvent = () => {
loadScrollXData();
};
const updateScrollYSpace = () => {
const { scrollYLoad, overflowY } = reactData;
const { elemStore } = internalData;
const $xeTable = internalData.xeTable;
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
const bodyTableElem = getRefElem(elemStore['main-body-table']);
let ySpaceTop = 0;
let scrollYHeight = 0;
let isScrollYBig = false;
if ($xeTable) {
const tableReactData = $xeTable.reactData;
ySpaceTop = tableReactData.scrollYTop;
scrollYHeight = tableReactData.scrollYHeight;
isScrollYBig = tableReactData.isScrollYBig;
}
let ySpaceHeight = scrollYHeight;
let scrollYTop = ySpaceTop;
let clientHeight = 0;
if (bodyScrollElem) {
clientHeight = bodyScrollElem.clientHeight;
}
if (isScrollYBig) {
// 触底
if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
scrollYTop = maxYHeight - bodyTableElem.clientHeight;
}
else {
scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight));
}
ySpaceHeight = maxYHeight;
}
if (!(scrollYLoad && overflowY)) {
scrollYTop = 0;
}
const bodyChartWrapperElem = getRefElem(elemStore['main-chart-task-wrapper']);
if (bodyTableElem) {
bodyTableElem.style.transform = `translate(${reactData.scrollXLeft || 0}px, ${scrollYTop}px)`;
}
if (bodyChartWrapperElem) {
bodyChartWrapperElem.style.transform = `translateY(${scrollYTop}px)`;
}
const bodyYSpaceElem = getRefElem(elemStore['main-body-ySpace']);
if (bodyYSpaceElem) {
bodyYSpaceElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
}
const scrollYSpaceEl = refScrollYSpaceElem.value;
if (scrollYSpaceEl) {
scrollYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
}
const beforeWrapper = getRefElem(elemStore['main-chart-before-wrapper']);
const beforeSvgElem = beforeWrapper ? beforeWrapper.firstElementChild : null;
if (beforeSvgElem) {
beforeSvgElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
}
const afterWrapper = getRefElem(elemStore['main-chart-after-wrapper']);
const afterSvgElem = afterWrapper ? afterWrapper.firstElementChild : null;
if (afterSvgElem) {
afterSvgElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
}
const nowLineElem = getRefElem(elemStore['main-chart-now-line']);
if (nowLineElem) {
nowLineElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
}
reactData.scrollYTop = scrollYTop;
reactData.scrollYHeight = scrollYHeight;
reactData.isScrollYBig = isScrollYBig;
calcScrollbar();
return nextTick().then(() => {
updateStyle();
});
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const checkLastSyncScroll = (isRollX, isRollY) => {
const { lcsTimeout } = internalData;
reactData.lazScrollLoading = true;
if (lcsTimeout) {
clearTimeout(lcsTimeout);
}
internalData.lcsTimeout = setTimeout(() => {
internalData.lcsRunTime = Date.now();
internalData.lcsTimeout = undefined;
internalData.intoRunScroll = false;
internalData.inVirtualScroll = false;
internalData.inWheelScroll = false;
internalData.inHeaderScroll = false;
internalData.inBodyScroll = false;
internalData.inFooterScroll = false;
reactData.lazScrollLoading = false;
}, 200);
};
const handleScrollData = (isRollY, isRollX, scrollTop, scrollLeft) => {
if (isRollX) {
internalData.lastScrollLeft = scrollLeft;
}
if (isRollY) {
internalData.lastScrollTop = scrollTop;
}
reactData.lastScrollTime = Date.now();
checkLastSyncScroll();
};
const handleScrollEvent = (evnt, isRollY, isRollX, scrollTop, scrollLeft) => {
const $xeTable = internalData.xeTable;
const { lastScrollLeft, lastScrollTop } = internalData;
const xHandleEl = refScrollXHandleElem.value;
const yHandleEl = refScrollYHandleElem.value;
if (!xHandleEl || !yHandleEl) {
return;
}
if (!$xeTable) {
return;
}
const { computeScrollXThreshold, computeScrollYThreshold } = $xeTable.getComputeMaps();
const bodyHeight = yHandleEl.clientHeight;
const bodyWidth = xHandleEl.clientWidth;
const scrollHeight = yHandleEl.scrollHeight;
const scrollWidth = xHandleEl.scrollWidth;
let isTop = false;
let isBottom = false;
let isLeft = false;
let isRight = false;
let direction = '';
let isTopBoundary = false;
let isBottomBoundary = false;
let isLeftBoundary = false;
let isRightBoundary = false;
if (isRollX) {
const xThreshold = computeScrollXThreshold.value;
isLeft = scrollLeft <= 0;
if (!isLeft) {
isRight = scrollLeft + bodyWidth >= scrollWidth - 1;
}
if (scrollLeft > lastScrollLeft) {
direction = 'right';
if (scrollLeft + bodyWidth >= scrollWidth - xThreshold) {
isRightBoundary = true;
}
}
else {
direction = 'left';
if (scrollLeft <= xThreshold) {
isLeftBoundary = true;
}
}
}
if (isRollY) {
const yThreshold = computeScrollYThreshold.value;
isTop = scrollTop <= 0;
if (!isTop) {
isBottom = scrollTop + bodyHeight >= scrollHeight - 1;
}
if (scrollTop > lastScrollTop) {
direction = 'bottom';
if (scrollTop + bodyHeight >= scrollHeight - yThreshold) {
isBottomBoundary = true;
}
}
else {
direction = 'top';
if (scrollTop <= yThreshold) {
isTopBoundary = true;
}
}
}
handleScrollData(isRollY, isRollX, scrollTop, scrollLeft);
const evntParams = {
source: sourceType,
scrollTop,
scrollLeft,
bodyHeight,
bodyWidth,
scrollHeight,
scrollWidth,
isX: isRollX,
isY: isRollY,
isTop,
isBottom,
isLeft,
isRight,
direction
};
if (isBottomBoundary || isTopBoundary || isRightBoundary || isLeftBoundary) {
$xeGantt.dispatchEvent('scroll-boundary', evntParams, evnt);
}
$xeGantt.dispatchEvent('scroll', evntParams, evnt);
};
const ganttViewMethods = {
refreshData() {
handleUpdateData();
handleRecalculateStyle();
return nextTick().then(() => {
const $xeTable = internalData.xeTable;
handleRecalculateStyle();
if ($xeTable) {
return $xeTable.recalculate();
}
});
},
updateViewData(force) {
const $xeTable = internalData.xeTable;
if ($xeTable) {
const tableReactData = $xeTable.reactData;
const { tableData } = tableReactData;
reactData.tableData = tableData;
if (force) {
ganttReactData.currLeftSpacing = 0;
ganttReactData.currRightSpacing = 0;
handleUpdateData();
}
handleRecalculateStyle();
}
return nextTick();
},
connectUpdate({ $table }) {
if ($table) {
internalData.xeTable = $table;
}
return nextTick();
}
};
/**
* 同步表格滚动
*/
const syncTableScrollTop = (scrollTop) => {
const $xeTable = internalData.xeTable;
if ($xeTable) {
const tableInternalData = $xeTable.internalData;
const { elemStore: tableElemStore } = tableInternalData;
const tableBodyScrollElem = getRefElem(tableElemStore['main-body-scroll']);
if (tableBodyScrollElem) {
tableBodyScrollElem.scrollTop = scrollTop;
}
}
};
const ganttViewPrivateMethods = {
handleUpdateStyle: updateStyle,
handleLazyRecalculate,
handleUpdateCurrentRow(row) {
const $xeTable = internalData.xeTable;
const el = refElem.value;
if ($xeTable && el) {
if (row) {
const tableProps = $xeTable.props;
const { computeRowOpts } = $xeTable.getComputeMaps();
const rowOpts = computeRowOpts.value;
if (rowOpts.isCurrent || tableProps.highlightCurrentRow) {
XEUtils.arrayEach(el.querySelectorAll(`.vxe-gantt-view--body-row[rowid="${$xeTable.getRowid(row)}"]`), elem => addClass(elem, 'row--current'));
}
}
else {
XEUtils.arrayEach(el.querySelectorAll('.vxe-gantt-view--body-row.row--current'), elem => removeClass(elem, 'row--current'));
}
}
},
handleUpdateHoverRow(row) {
const $xeTable = internalData.xeTable;
const el = refElem.value;
if ($xeTable && el) {
if (row) {
XEUtils.arrayEach(el.querySelectorAll(`.vxe-gantt-view--body-row[rowid="${$xeTable.getRowid(row)}"]`), elem => addClass(elem, 'row--hover'));
}
else {
XEUtils.arrayEach(el.querySelectorAll('.vxe-gantt-view--body-row.row--hover'), elem => removeClass(elem, 'row--hover'));
}
}
},
triggerHeaderScrollEvent(evnt) {
const { elemStore, inVirtualScroll, inBodyScroll, inFooterScroll } = internalData;
if (inVirtualScroll) {
return;
}
if (inBodyScroll || inFooterScroll) {
return;
}
const wrapperEl = evnt.currentTarget;
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
const xHandleEl = refScrollXHandleElem.value;
if (bodyScrollElem && wrapperEl) {
const isRollX = true;
const isRollY = false;
const currLeftNum = wrapperEl.scrollLeft;
internalData.inHeaderScroll = true;
setScrollLeft(xHandleEl, currLeftNum);
setScrollLeft(bodyScrollElem, currLeftNum);
handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum);
}
},
triggerBodyScrollEvent(evnt) {
const { scrollXLoad } = reactData;
const { elemStore, inVirtualScroll, inHeaderScroll, inFooterScroll, lastScrollLeft, lastScrollTop } = internalData;
if (inVirtualScroll) {
return;
}
if (inHeaderScroll || inFooterScroll) {
return;
}
const wrapperEl = evnt.currentTarget;
const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
const xHandleEl = refScrollXHandleElem.value;
const yHandleEl = refScrollYHandleElem.value;
const scrollLeft = wrapperEl.scrollLeft;
const scrollTop = wrapperEl.scrollTop;
const isRollX = scrollLeft !== lastScrollLeft;
const isRollY = scrollTop !== lastScrollTop;
internalData.inBodyScroll = true;
internalData.scrollRenderType = '';
if (isRollY) {
setScrollTop(yHandleEl, scrollTop);
syncTableScrollTop(scrollTop);
}
if (isRollX) {
internalData.inBodyScroll = true;
setScrollLeft(xHandleEl, scrollLeft);
setScrollLeft(headerScrollElem, scrollLeft);
if (scrollXLoad) {
triggerScrollXEvent();
}
}
if (isRollY) {
handleScrollData(isRollY, isRollX, wrapperEl.scrollTop, scrollLeft);
}
if (isRollX) {
handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, scrollLeft);
}
},
// triggerFooterScrollEvent (evnt) {
// const { inVirtualScroll, inHeaderScroll, inBodyScroll } = internalData
// if (inVirtualScroll) {
// return
// }
// if (inHeaderScroll || inBodyScroll) {
// return
// }
// const wrapperEl = evnt.currentTarget as HTMLDivElement
// if (wrapperEl) {
// const isRollX = true
// const isRollY = false
// const currLeftNum = wrapperEl.scrollLeft
// handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
// }
// },
triggerVirtualScrollXEvent(evnt) {
const { scrollXLoad } = reactData;
const { elemStore, inHeaderScroll, inBodyScroll } = internalData;
if (inHeaderScroll || inBodyScroll) {
return;
}
const wrapperEl = evnt.currentTarget;
const headerScrollElem = getRefElem(elemStore['main-header-scroll']);
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (wrapperEl) {
const isRollY = false;
const isRollX = true;
const currLeftNum = wrapperEl.scrollLeft;
internalData.inVirtualScroll = true;
setScrollLeft(headerScrollElem, currLeftNum);
setScrollLeft(bodyScrollElem, currLeftNum);
if (scrollXLoad) {
triggerScrollXEvent();
}
handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum);
}
},
triggerVirtualScrollYEvent(evnt) {
const { elemStore, inHeaderScroll, inBodyScroll } = internalData;
if (inHeaderScroll || inBodyScroll) {
return;
}
const wrapperEl = evnt.currentTarget;
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (wrapperEl) {
const isRollY = true;
const isRollX = false;
const currTopNum = wrapperEl.scrollTop;
internalData.inVirtualScroll = true;
setScrollTop(bodyScrollElem, currTopNum);
syncTableScrollTop(currTopNum);
handleScrollData(isRollY, isRollX, currTopNum, wrapperEl.scrollLeft);
}
},
handleUpdateSXSpace() {
return updateScrollXSpace();
},
handleUpdateSYSpace() {
return updateScrollYSpace();
},
handleUpdateSYStatus(sYLoad) {
reactData.scrollYLoad = sYLoad;
}
};
const handleGlobalResizeEvent = () => {
handleLazyRecalculate();
};
Object.assign($xeGanttView, ganttViewMethods, ganttViewPrivateMethods);
const renderScrollX = () => {
return h('div', {
key: 'vsx',
ref: refScrollXVirtualElem,
class: 'vxe-gantt-view--scroll-x-virtual'
}, [
h('div', {
ref: refScrollXLeftCornerElem,
class: 'vxe-gantt-view--scroll-x-left-corner'
}),
h('div', {
ref: refScrollXWrapperElem,
class: 'vxe-gantt-view--scroll-x-wrapper'
}, [
h('div', {
ref: refScrollXHandleElem,
class: 'vxe-gantt-view--scroll-x-handle',
onScroll: $xeGanttView.triggerVirtualScrollXEvent
}, [
h('div', {
ref: refScrollXSpaceElem,
class: 'vxe-gantt-view--scroll-x-space'
})
]),
h('div', {
class: 'vxe-gantt-view--scroll-x-handle-appearance'
})
]),
h('div', {
ref: refScrollXRightCornerElem,
class: 'vxe-gantt-view--scroll-x-right-corner'
})
]);
};
const renderScrollY = () => {
return h('div', {
ref: refScrollYVirtualElem,
class: 'vxe-gantt-view--scroll-y-virtual'
}, [
h('div', {
ref: refScrollYTopCornerElem,
class: 'vxe-gantt-view--scroll-y-top-corner'
}),
h('div', {
ref: refScrollYWrapperElem,
class: 'vxe-gantt-view--scroll-y-wrapper'
}, [
h('div', {
ref: refScrollYHandleElem,
class: 'vxe-gantt-view--scroll-y-handle',
onScroll: $xeGanttView.triggerVirtualScrollYEvent
}, [
h('div', {
ref: refScrollYSpaceElem,
class: 'vxe-gantt-view--scroll-y-space'
})
]),
h('div', {
class: 'vxe-gantt-view--scroll-y-handle-appearance'
})
]),
h('div', {
ref: refScrollYBottomCornerElem,
class: 'vxe-gantt-view--scroll-y-bottom-corner'
})
]);
};
const renderViewport = () => {
return h('div', {
class: 'vxe-gantt-view--viewport-wrapper'
}, [
h(GanttViewHeaderComponent),
h(GanttViewBodyComponent),
h(GanttViewFooterComponent)
]);
};
const renderBody = () => {
const scrollbarYToLeft = computeScrollbarYToLeft.value;
return h('div', {
class: 'vxe-gantt-view--layout-wrapper'
}, scrollbarYToLeft
? [
renderScrollY(),
renderViewport()
]
: [
renderViewport(),
renderScrollY()
]);
};
const renderVN = () => {
const { overflowX, overflowY, scrollXLoad, scrollYLoad } = reactData;
const scrollbarXToTop = computeScrollbarXToTop.value;
return h('div', {
ref: refElem,
class: ['vxe-gantt-view', {
'is--scroll-y': overflowY,
'is--scroll-x': overflowX,
'is--virtual-x': scrollXLoad,
'is--virtual-y': scrollYLoad
}]
}, [
h('div', {
class: 'vxe-gantt-view--render-wrapper'
}, scrollbarXToTop
? [
renderScrollX(),
renderBody()
]
: [
renderBody(),
renderScrollX()
]),
h('div', {
class: 'vxe-gantt-view--render-vars'
}, [
h('div', {
ref: refColInfoElem,
class: 'vxe-gantt-view--column-info'
})
])
]);
};
onMounted(() => {
globalEvents$1.on($xeGanttView, 'resize', handleGlobalResizeEvent);
});
onBeforeUnmount(() => {
XEUtils.assign(reactData, createReactData$1());
XEUtils.assign(internalData, createInternalData$1());
});
onUnmounted(() => {
globalEvents$1.off($xeGanttView, 'keydown');
});
$xeGanttView.renderVN = renderVN;
provide('$xeGanttView', $xeGanttView);
return $xeGanttView;
},
render() {
return this.renderVN();
}
});
const { warnLog, errLog } = createComponentLog('gantt');
const { getConfig, getIcon, getI18n, commands, hooks, useFns, createEvent, globalEvents, GLOBAL_EVENT_KEYS, renderEmptyElement } = VxeUI;
const tableProps = VxeTable.props;
const tableComponentPropKeys = Object.keys(tableProps);
const tableComponentMethodKeys = ['clearAll', 'syncData', 'updateData', 'loadData', 'reloadData', 'reloadRow', 'loadColumn', 'reloadColumn', 'getRowNode', 'getColumnNode', 'getRowIndex', 'getVTRowIndex', 'getVMRowIndex', 'getColumnIndex', 'getVTColumnIndex', 'getVMColumnIndex', 'setRow', 'createData', 'createRow', 'revertData', 'clearData', 'isRemoveByRow', 'isInsertByRow', 'isUpdateByRow', 'getColumns', 'getColumnById', 'getColumnByField', 'getTableColumn', 'getFullColumns', 'getData', 'getCheckboxRecords', 'getParentRow', 'getTreeRowChildren', 'getTreeRowLevel', 'getTreeParentRow', 'getRowSeq', 'getRowById', 'getRowid', 'getTableData', 'getFullData', 'setColumnFixed', 'clearColumnFixed', 'setColumnWidth', 'getColumnWidth', 'recalcRowHeight', 'setRowHeightConf', 'getRowHeightConf', 'setRowHeight', 'getRowHeight', 'hideColumn', 'showColumn', 'resetColumn', 'refreshColumn', 'refreshScroll', 'recalculate', 'closeTooltip', 'isAllCheckboxChecked', 'isAllCheckboxIndeterminate', 'getCheckboxIndeterminateRecords', 'setCheckboxRow', 'setCheckboxRowKey', 'isCheckedByCheckboxRow', 'isCheckedByCheckboxRowKey', 'isIndeterminateByCheckboxRow', 'isIndeterminateByCheckboxRowKey', 'toggleCheckboxRow', 'setAllCheckboxRow', 'getRadioReserveRecord', 'clearRadioReserve', 'getCheckboxReserveRecords', 'clearCheckboxReserve', 'toggleAllCheckboxRow', 'clearCheckboxRow', 'setCurrentRow', 'isCheckedByRadioRow', 'isCheckedByRadioRowKey', 'setRadioRow', 'setRadioRowKey', 'clearCurrentRow', 'clearRadioRow', 'getCurrentRecord', 'getRadioRecord', 'getCurrentColumn', 'setCurrentColumn', 'clearCurrentColumn', 'setPendingRow', 'togglePendingRow', 'hasPendingByRow', 'isPendingByRow', 'getPendingRecords', 'clearPendingRow', 'setFilterByEvent', 'sort', 'setSort', 'setSortByEvent', 'clearSort', 'clearSortByEvent', 'isSort', 'getSortColumns', 'closeFilter', 'isFilter', 'clearFilterByEvent', 'isActiveFilterByColumn', 'isRowExpandLoaded', 'clearRowExpandLoaded', 'reloadRowExpand', 'reloadRowExpand', 'toggleRowExpand', 'setAllRowExpand', 'setRowExpand', 'isExpandByRow', 'isRowExpandByRow', 'clearRowExpand', 'clearRowExpandReserve', 'getRowExpandRecords', 'getTreeExpandRecords', 'isTreeExpandLoaded', 'clearTreeExpandLoaded', 'reloadTreeExpand', 'reloadTreeChilds', 'toggleTreeExpand', 'setAllTreeExpand', 'setTreeExpand', 'isTreeExpandByRow', 'clearTreeExpand', 'clearTreeExpandReserve', 'getScroll', 'scrollTo', 'scrollToStartRow', 'scrollToEndRow', 'scrollToRow', 'scrollToStartColumn', 'scrollToEndColumn', 'scrollToColumn', 'clearScroll', 'updateFooter', 'updateStatus', 'setMergeCells', 'removeInsertRow', 'removeMergeCells', 'getMergeCells', 'clearMergeCells', 'setMergeFooterItems', 'removeMergeFooterItems', 'getMergeFooterItems', 'clearMergeFooterItems', 'getCustomStoreData', 'setRowGroupExpand', 'setRowGroupExpandByField', 'setAllRowGroupExpand', 'clearRowGroupExpand', 'isRowGroupExpandByRow', 'isRowGroupRecord', 'isAggregateRecord', 'isAggregateExpandByRow', 'getAggregateContentByRow', 'getAggregateRowChildren', 'setRowGroups', 'clearRowGroups', 'openTooltip', 'moveColumnTo', 'moveRowTo', 'getCellLabel', 'undo', 'redo', 'getCellElement', 'focus', 'blur', 'connect'];
const defaultLayouts = [['Form'], ['Toolbar', 'Top', 'Gantt', 'Bottom', 'Pager']];
function createInternalData() {
return {
linkFromConfMaps: {},
linkToConfMaps: {},
linkUniqueMaps: {},
uFoot: false,
resizeTableWidth: 0,
// barTipTimeout: null,
// dragBarRow: null,
// dragLineRow: null,
dragLinkToStore: {
rowid: null,
type: 0
},
// 关键路径
criticalRowList: [],
criticalRowMaps: new Map(),
criticalLinkKeyMaps: new Map()
};
}
function createReactData() {
var _a;
return {
tableLoading: false,
proxyInited: false,
// 是否存在纵向滚动条
overflowY: false,
// 是否存在横向滚动条
overflowX: false,
// 纵向滚动条的宽度
scrollbarWidth: 0,
// 横向滚动条的高度
scrollbarHeight: 0,
isZMax: false,
tableLinks: [],
tableData: [],
filterData: [],
formData: {},
sortData: [],
footerData: [],
tZindex: 0,
tablePage: {
total: 0,
pageSize: ((_a = getConfig().pager) === null || _a === void 0 ? void 0 : _a.pageSize) || 10,
currentPage: 1
},
showLeftView: true,
showRightView: true,
taskScaleList: [],
barTipStore: {
row: null,
content: '',
visible: false,
params: null
},
dragLinkFromStore: {
rowid: null,
type: 0
},
activeBarRowid: null,
activeLink: null,
isActiveCeLe: false,
linkList: [],
upLinkFlag: 0,
showSplitAnimat: false,
nowTime: 0,
currLeftSpacing: 0,
currRightSpacing: 0,
// 关键路径
criticalLinks: [],
criticalRowIds: [],
criticalPathFlag: 0
};
}
const viewTypeLevelMaps = {
year: 19,
quarter: 17,
month: 15,
week: 13,
day: 11,
date: 9,
hour: 7,
minute: 5,
second: 3
};
function getViewTypeLevel(type) {
return viewTypeLevelMaps[type || 'date'] || viewTypeLevelMaps.date;
}
var VxeGanttComponent = defineVxeComponent({
name: 'VxeGantt',
mixins: [],
props: Object.assign(Object.assign({}, tableProps), { columns: Array, pagerConfig: Object, proxyConfig: Object, toolbarConfig: Object, formConfig: Object, zoomConfig: Object, links: Array, layouts: Array, taskConfig: Object, taskViewScaleConfig: Object, taskNowLineConfig: Object, taskViewConfig: Object, taskLinkConfig: Object, taskBarConfig: Object, taskBarMilestoneConfig: Object, taskCriticalPathConfig: Object, taskBarSubviewConfig: Object, taskBarTooltipConfig: Object, taskSplitConfig: Object, taskBarResizeConfig: Object, taskBarResizeTooltipConfig: Object, taskBarMoveConfig: Object, taskBarMoveTooltipConfig: Object, size: {
type: String,
default: () => getConfig().gantt.size || getConfig().size
} }),
emits: ganttEmits,
setup(props, context) {
const { slots, emit } = context;
const xID = XEUtils.uniqueId();
// 使用已安装的组件,如果未安装则不渲染
const VxeUIFormComponent = VxeUI.getComponent('VxeForm');
const VxeUIPagerComponent = VxeUI.getComponent('VxePager');
const VxeTableComponent = VxeUI.getComponent('VxeTable');
const VxeToolbarComponent = VxeUI.getComponent('VxeToolbar');
const VxeUITooltipComponent = VxeUI.getComponent('VxeTooltip');
const { computeSize } = useFns.useSize(props);
const reactData = reactive(createReactData());
const internalData = createInternalData();
const refElem = ref();
const refTable = ref();
const refForm = ref();
const refToolbar = ref();
const refPager = ref();
const refGanttContainerElem = ref();
const refClassifyWrapperElem = ref();
const refGanttView = ref();
const refPopupContainerElem = ref();
const refFormWrapper = ref();
const refToolbarWrapper = ref();
const refTopWrapper = ref();
const refBottomWrapper = ref();
const refPagerWrapper = ref();
const refTableWrapper = ref();
const refGanttWrapper = ref();
const refTooltip = ref();
const refResizableSplitTip = ref();
const extendTableMethods = (methodKeys) => {
const funcs = {};
methodKeys.forEach(name => {
funcs[name] = (...args) => {
const $xeTable = refTable.value;
if ($xeTable && $xeTable[name]) {
return $xeTable[name](...args);
}
};
});
return funcs;
};
const ganttExtendTableMethods = extendTableMethods(tableComponentMethodKeys);
tableComponentMethodKeys.forEach(name => {
ganttExtendTableMethods[name] = (...args) => {
const $xeTable = refTable.value;
if ($xeTable && $xeTable[name]) {
return $xeTable && $xeTable[name](...args);
}
};
});
const computeProxyOpts = computed(() => {
return XEUtils.merge({}, XEUtils.clone(getConfig().gantt.proxyConfig, true), props.proxyConfig);
});
const computeIsRespMsg = computed(() => {
const proxyOpts = computeProxyOpts.value;
return !!(XEUtils.isBoolean(proxyOpts.message) ? proxyOpts.message : proxyOpts.showResponseMsg);
});
const computeIsActiveMsg = computed(() => {
const proxyOpts = computeProxyOpts.value;
return XEUtils.isBoolean(proxyOpts.showActionMsg) ? proxyOpts.showActionMsg : !!proxyOpts.showActiveMsg;
});
const computePagerOpts = computed(() => {
return Object.assign({}, getConfig().gantt.pagerConfig, props.pagerConfig);
});
const computeFormOpts = computed(() => {
return Object.assign({}, getConfig().gantt.formConfig, props.formConfig);
});
const computeToolbarOpts = computed(() => {
return Object.assign({}, getConfig().gantt.toolbarConfig, props.toolbarConfig);
});
const computeZoomOpts = computed(() => {
return Object.assign({}, getConfig().gantt.zoomConfig, props.zoomConfig);
});
const computeTaskOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskConfig, props.taskConfig);
});
const computeTaskViewScaleOpts = computed(() => {
return XEUtils.merge({}, getConfig().gantt.taskViewScaleConfig, props.taskViewScaleConfig);
});
const computeTaskNowLineOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskNowLineConfig, props.taskNowLineConfig);
});
const computeTaskViewOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskViewConfig, props.taskViewConfig);
});
const computeTaskBarOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarConfig, props.taskBarConfig);
});
const computeTaskBarMoveOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarMoveConfig, props.taskBarMoveConfig);
});
const computeTaskBarMoveTooltipOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarMoveTooltipConfig, props.taskBarMoveTooltipConfig);
});
const computeTaskBarResizeOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarResizeConfig, props.taskBarResizeConfig);
});
const computeTaskBarResizeTooltipOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarResizeTooltipConfig, props.taskBarResizeTooltipConfig);
});
const computeTaskSplitOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskSplitConfig, props.taskSplitConfig);
});
const computeTaskBarMilestoneOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarMilestoneConfig, props.taskBarMilestoneConfig);
});
const computeTaskCriticalPathOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskCriticalPathConfig, props.taskCriticalPathConfig);
});
const computeTaskBarSubviewOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarSubviewConfig, props.taskBarSubviewConfig);
});
const computeTaskBarTooltipOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskBarTooltipConfig, props.taskBarTooltipConfig);
});
const computeTaskLinkOpts = computed(() => {
return Object.assign({}, getConfig().gantt.taskLinkConfig, props.taskLinkConfig);
});
const computeDateFormat = computed(() => {
const taskOpts = computeTaskOpts.value;
const { dateFormat } = taskOpts;
return dateFormat || '';
});
const computeScaleUnit = computed(() => {
const minScale = computeMinScale.value;
return minScale ? minScale.type : 'date';
});
const computeMinScale = computed(() => {
const { taskScaleList } = reactData;
return XEUtils.last(taskScaleList);
});
const computeScaleStep = computed(() => {
const minScale = computeMinScale.value;
const { step } = minScale;
return XEUtils.toNumber(step || 1) || 1;
});
const computeWeekScale = computed(() => {
const { taskScaleList } = reactData;
return taskScaleList.find(item => item.type === 'week');
});
const computeTaskViewScales = computed(() => {
const taskViewOpts = computeTaskViewOpts.value;
const { scales } = taskViewOpts;
return scales;
});
const computeTaskLinkStyle = computed(() => {
const { lineType, lineWidth, lineStatus, lineColor } = computeTaskLinkOpts.value;
return `${lineType || ''}_${lineWidth || ''}_${lineStatus || ''}_${lineColor || ''}`;
});
const computeTitleField = computed(() => {
const taskOpts = computeTaskOpts.value;
return taskOpts.titleField || 'title';
});
const computeStartField = computed(() => {
const taskOpts = computeTaskOpts.value;
return taskOpts.startField || 'start';
});
const computeEndField = computed(() => {
const taskOpts = computeTaskOpts.value;
return taskOpts.endField || 'end';
});
const computeTypeField = computed(() => {
const taskOpts = computeTaskOpts.value;
return taskOpts.typeField || 'type';
});
const computeProgressField = computed(() => {
const taskOpts = computeTaskOpts.value;
return taskOpts.progressField || 'progress';
});
const computeScrollbarOpts = computed(() => {
return Object.assign({}, getConfig().gantt.scrollbarConfig, props.scrollbarConfig);
});
const computeScrollbarXToTop = computed(() => {
const scrollbarOpts = computeScrollbarOpts.value;
return !!(scrollbarOpts.x && scrollbarOpts.x.position === 'top');
});
const computeScrollbarYToLeft = computed(() => {
const scrollbarOpts = computeScrollbarOpts.value;
return !!(scrollbarOpts.y && scrollbarOpts.y.position === 'left');
});
const computeCriticalPathVisible = computed(() => {
const taskBarOpts = computeTaskBarOpts.value;
return taskBarOpts.showCriticalPath;
});
const computeWrapperStyle = computed(() => {
const { height, maxHeight, taskBarSubviewConfig } = props;
const { isZMax, tZindex, overflowY, scrollbarWidth } = reactData;
const taskViewOpts = computeTaskViewOpts.value;
const { viewStyle, tableStyle } = taskViewOpts;
const taskBarOpts = computeTaskBarOpts.value;
const { barStyle } = taskBarOpts;
const taskCriticalPathOpts = computeTaskCriticalPathOpts.value;
const { lineColor: cpLineColor } = taskCriticalPathOpts;
const taskBarSubviewOpts = computeTaskBarSubviewOpts.value;
const taskNowLineOpts = computeTaskNowLineOpts.value;
const { fontColor: nlfColor, bgColor: nlbgColor, width: nlWidth } = taskNowLineOpts;
const stys = {
'--vxe-ui-gantt-scrollbar-width': (overflowY && scrollbarWidth ? scrollbarWidth : 0) + 'px'
};
if (cpLineColor) {
stys['--vxe-ui-gantt-view-bar-critical-path-line-color'] = cpLineColor;
}
if (isZMax) {
stys.zIndex = tZindex;
}
else {
if (height) {
stys.height = height === 'auto' || height === '100%' ? '100%' : toCssUnit(height);
}
if (maxHeight) {
stys.maxHeight = maxHeight === 'auto' || maxHeight === '100%' ? '100%' : toCssUnit(maxHeight);
}
}
if (barStyle && !XEUtils.isFunction(barStyle)) {
const { bgColor, completedBgColor, overviewBgColor } = barStyle;
if (bgColor) {
stys['--vxe-ui-gantt-view-task-bar-background-color'] = bgColor;
}
if (completedBgColor) {
stys['--vxe-ui-gantt-view-task-bar-completed-background-color'] = completedBgColor;
}
if (overviewBgColor && hasEnableConf(taskBarSubviewConfig, taskBarSubviewOpts)) {
stys['--vxe-ui-gantt-view-task-bar-overview-background-color'] = overviewBgColor;
}
}
if (nlfColor) {
stys['--vxe-ui-gantt-view-task-now-line-color'] = nlfColor;
}
if (nlbgColor) {
stys['--vxe-ui-gantt-view-task-now-line-background-color'] = nlbgColor;
}
if (nlWidth) {
stys['--vxe-ui-gantt-view-task-now-line-width'] = toCssUnit(nlWidth);
}
if (viewStyle) {
const { cellWidth } = viewStyle;
if (cellWidth) {
stys['--vxe-ui-gantt-view-default-cell-width'] = toCssUnit(cellWidth);
}
}
if (tableStyle) {
const { width: defTbWidth } = tableStyle;
if (defTbWidth) {
stys['--vxe-ui-gantt-view-table-default-width'] = toCssUnit(defTbWidth);
}
}
return stys;
});
const computeTableExtendProps = computed(() => {
const rest = {};
const ganttProps = props;
tableComponentPropKeys.forEach((key) => {
if (ganttProps[key] !== undefined) {
rest[key] = ganttProps[key];
}
});
return rest;
});
const computeTableProps = computed(() => {
const { showFooter, seqConfig, pagerConfig, editConfig, proxyConfig } = props;
const { isZMax, tablePage, footerData } = reactData;
const taskViewOpts = computeTaskViewOpts.value;
const { tableStyle } = taskViewOpts;
const tableExtendProps = computeTableExtendProps.value;
const proxyOpts = computeProxyOpts.value;
const pagerOpts = computePagerOpts.value;
const isLoading = computeIsLoading.value;
const tProps = Object.assign({}, tableExtendProps, {
// 不支持修改的属性
showOverflow: true,
showHeaderOverflow: true,
showFooterOverflow: true
});
if (tableStyle) {
const { border } = tableStyle;
if (!XEUtils.eqNull(border)) {
tProps.border = border;
}
}
if (showFooter && !tProps.footerData) {
// 如果未设置自己的标位数据,则使用代理的
tProps.footerData = footerData;
}
else if (proxyOpts.footer && footerData.length) {
// 如果代理标为数据,且未请求到数据,则用自己的
tProps.footerData = footerData;
}
if (isZMax) {
if (tProps.maxHeight) {
tProps.maxHeight = '100%';
}
else {
tProps.height = '100%';
}
}
if (proxyConfig && isEnableConf(proxyOpts)) {
tProps.loading = isLoading;
if (pagerConfig && proxyOpts.seq && isEnableConf(pagerOpts)) {
tProps.seqConfig = Object.assign({}, seqConfig, { startIndex: (tablePage.currentPage - 1) * tablePage.pageSize });
}
}
if (editConfig) {
tProps.editConfig = Object.assign({}, editConfig);
}
return tProps;
});
const computeCurrLayoutConf = computed(() => {
const { layouts } = props;
let confs = [];
if (layouts && layouts.length) {
confs = layouts;
}
else {
confs = getConfig().gantt.layouts || defaultLayouts;
}
let headKeys = [];
let bodyKeys = [];
let footKeys = [];
if (confs.length) {
if (XEUtils.isArray(confs[0])) {
headKeys = confs[0];
bodyKeys = (confs[1] || []);
footKeys = (confs[2] || []);
}
else {
bodyKeys = confs;
}
}
return {
headKeys,
bodyKeys,
footKeys
};
});
const computeCustomCurrentPageFlag = computed(() => {
const pagerOpts = computePagerOpts.value;
return pagerOpts.currentPage;
});
const computeCustomPageSizeFlag = computed(() => {
const pagerOpts = computePagerOpts.value;
return pagerOpts.pageSize;
});
const computeCustomTotalFlag = computed(() => {
const pagerOpts = computePagerOpts.value;
return pagerOpts.total;
});
const computePageCount = computed(() => {
const { tablePage } = reactData;
return Math.max(Math.ceil(tablePage.total / tablePage.pageSize), 1);
});
const computeIsLoading = computed(() => {
const { loading, proxyConfig } = props;
const { tableLoading } = reactData;
const proxyOpts = computeProxyOpts.value;
const { showLoading } = proxyOpts;
return loading || (tableLoading && showLoading && proxyConfig && isEnableConf(proxyOpts));
});
const computeTableBorder = computed(() => {
let { border } = props;
const taskViewOpts = computeTaskViewOpts.value;
const { viewStyle } = taskViewOpts;
if (viewStyle) {
if (!XEUtils.eqNull(viewStyle.border)) {
border = viewStyle.border;
}
}
if (border === true) {
return 'full';
}
if (border) {
return border;
}
return 'default';
});
const refMaps = {
refElem,
refTable,
refForm,
refToolbar,
refPager,
refGanttView,
refGanttContainerElem,
refClassifyWrapperElem,
refPopupContainerElem
};
const computeMaps = {
computeProxyOpts,
computePagerOpts,
computeFormOpts,
computeToolbarOpts,
computeZoomOpts,
computeTaskOpts,
computeTaskViewScaleOpts,
computeTaskNowLineOpts,
computeTaskViewOpts,
computeTaskBarOpts,
computeTaskBarMoveOpts,
computeTaskBarMoveTooltipOpts,
computeTaskBarResizeOpts,
computeTaskBarResizeTooltipOpts,
computeTaskSplitOpts,
computeTaskBarMilestoneOpts,
computeTaskCriticalPathOpts,
computeTaskBarSubviewOpts,
computeTaskBarTooltipOpts,
computeTaskLinkOpts,
computeTaskViewScales,
computeScaleUnit,
computeDateFormat,
computeMinScale,
computeScaleStep,
computeWeekScale,
computeTitleField,
computeStartField,
computeEndField,
computeTypeField,
computeProgressField,
computeScrollbarOpts,
computeScrollbarXToTop,
computeScrollbarYToLeft
};
computeMaps.computeTaskScaleConfs = computeTaskViewScales;
const $xeGantt = {
xID,
props: props,
context,
reactData,
internalData,
getRefMaps: () => refMaps,
getComputeMaps: () => computeMaps
};
const handleTaskScaleConfig = () => {
const taskScaleConfs = computeTaskViewScales.value;
const taskViewScaleOpts = computeTaskViewScaleOpts.value;
const scaleConfs = [];
const keyMaps = {};
const scaleList = (taskScaleConfs && taskScaleConfs.length ? taskScaleConfs : ['month', 'date']);
scaleList.forEach(conf => {
const sConf = !conf || XEUtils.isString(conf) ? { type: conf } : conf;
const type = sConf.type;
const level = getViewTypeLevel(type);
if (!type || !viewTypeLevelMaps[type]) {
errLog('vxe.error.errProp', [`type=${type}`, XEUtils.keys(viewTypeLevelMaps).join(',')]);
return;
}
if (keyMaps[type]) {
errLog('vxe.error.repeatProp', ['type', type]);
return;
}
const scaleObj = Object.assign({}, type ? (taskViewScaleOpts[type] || {}) : {}, sConf, { level });
keyMaps[type] = true;
scaleConfs.push(scaleObj);
});
reactData.taskScaleList = XEUtils.orderBy(scaleConfs, { field: 'level', order: 'desc' });
};
const initToolbar = () => {
const toolbarOpts = computeToolbarOpts.value;
if (props.toolbarConfig && isEnableConf(toolbarOpts)) {
nextTick(() => {
const $xeTable = refTable.value;
const $xeToolbar = refToolbar.value;
if ($xeTable && $xeToolbar) {
$xeTable.connectToolbar($xeToolbar);
}
});
}
};
const initGanttView = () => {
const $xeTable = refTable.value;
const $ganttView = refGanttView.value;
if ($xeTable && $ganttView) {
$xeTable.handleConnectGanttView($ganttView);
}
};
const getFormData = () => {
const { proxyConfig } = props;
const { formData } = reactData;
const proxyOpts = computeProxyOpts.value;
const formOpts = computeFormOpts.value;
return proxyConfig && isEnableConf(proxyOpts) && proxyOpts.form ? formData : formOpts.data;
};
const initPages = (propKey) => {
const { tablePage } = reactData;
const { pagerConfig } = props;
const pagerOpts = computePagerOpts.value;
if (pagerConfig && isEnableConf(pagerOpts)) {
if (propKey) {
if (pagerOpts[propKey]) {
tablePage[propKey] = XEUtils.toNumber(pagerOpts[propKey]);
}
}
else {
const { currentPage, pageSize, total } = pagerOpts;
if (currentPage) {
tablePage.currentPage = currentPage;
}
if (pageSize) {
tablePage.pageSize = pageSize;
}
if (total) {
tablePage.total = total;
}
}
}
};
const triggerPendingEvent = (code) => {
const isActiveMsg = computeIsActiveMsg.value;
const $xeTable = refTable.value;
const selectRecords = $xeTable ? $xeTable.getCheckboxRecords() : [];
if (selectRecords.length) {
if ($xeTable) {
$xeTable.togglePendingRow(selectRecords);
}
$xeGantt.clearCheckboxRow();
}
else {
if (isActiveMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' });
}
}
}
};
const getRespMsg = (rest, defaultMsg) => {
const proxyOpts = computeProxyOpts.value;
const resConfigs = proxyOpts.response || proxyOpts.props || {};
const messageProp = resConfigs.message;
const $xeTable = refTable.value;
let msg;
if (rest && messageProp) {
msg = XEUtils.isFunction(messageProp) ? messageProp({ data: rest, $table: $xeTable, $grid: null, $gantt: $xeGantt }) : XEUtils.get(rest, messageProp);
}
return msg || getI18n(defaultMsg);
};
const handleDeleteRow = (code, alertKey, callback) => {
const isActiveMsg = computeIsActiveMsg.value;
const selectRecords = $xeGantt.getCheckboxRecords();
if (isActiveMsg) {
if (selectRecords.length) {
if (VxeUI.modal) {
return VxeUI.modal.confirm({ id: `cfm_${code}`, content: getI18n(alertKey), escClosable: true }).then((type) => {
if (type === 'confirm') {
return callback();
}
});
}
}
else {
if (VxeUI.modal) {
VxeUI.modal.message({ id: `msg_${code}`, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' });
}
}
}
else {
if (selectRecords.length) {
callback();
}
}
return Promise.resolve();
};
const pageChangeEvent = (params) => {
const { proxyConfig } = props;
const { tablePage } = reactData;
const { $event, currentPage, pageSize } = params;
const proxyOpts = computeProxyOpts.value;
tablePage.currentPage = currentPage;
tablePage.pageSize = pageSize;
$xeGantt.dispatchEvent('page-change', params, $event);
if (proxyConfig && isEnableConf(proxyOpts)) {
$xeGantt.commitProxy('query').then((rest) => {
$xeGantt.dispatchEvent('proxy-query', rest, $event);
});
}
};
const handleSortEvent = (params) => {
const $xeTable = refTable.value;
const { proxyConfig } = props;
if (!$xeTable) {
return;
}
const { computeSortOpts } = $xeTable.getComputeMaps();
const proxyOpts = computeProxyOpts.value;
const sortOpts = computeSortOpts.value;
// 如果是服务端排序
if (sortOpts.remote) {
reactData.sortData = params.sortList;
if (proxyConfig && isEnableConf(proxyOpts)) {
reactData.tablePage.currentPage = 1;
$xeGantt.commitProxy('query').then((rest) => {
$xeGantt.dispatchEvent('proxy-query', rest, params.$event);
});
}
}
};
const sortChangeEvent = (params) => {
handleSortEvent(params);
$xeGantt.dispatchEvent('sort-change', params, params.$event);
};
const clearAllSortEvent = (params) => {
handleSortEvent(params);
$xeGantt.dispatchEvent('clear-all-sort', params, params.$event);
};
const handleFilterEvent = (params) => {
const $xeTable = refTable.value;
const { proxyConfig } = props;
if (!$xeTable) {
return;
}
const { computeFilterOpts } = $xeTable.getComputeMaps();
const proxyOpts = computeProxyOpts.value;
const filterOpts = computeFilterOpts.value;
// 如果是服务端过滤
if (filterOpts.remote) {
reactData.filterData = params.filterList;
if (proxyConfig && isEnableConf(proxyOpts)) {
reactData.tablePage.currentPage = 1;
internalData.uFoot = true;
$xeGantt.commitProxy('query').then((rest) => {
$xeGantt.dispatchEvent('proxy-query', rest, params.$event);
});
internalData.uFoot = false;
updateQueryFooter();
}
}
};
const filterChangeEvent = (params) => {
handleFilterEvent(params);
$xeGantt.dispatchEvent('filter-change', params, params.$event);
};
const clearAllFilterEvent = (params) => {
handleFilterEvent(params);
$xeGantt.dispatchEvent('clear-all-filter', params, params.$event);
};
const submitFormEvent = (params) => {
const { proxyConfig } = props;
const proxyOpts = computeProxyOpts.value;
if (reactData.tableLoading) {
return;
}
if (proxyConfig && isEnableConf(proxyOpts)) {
internalData.uFoot = true;
$xeGantt.commitProxy('reload').then((rest) => {
$xeGantt.dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isReload: true }), params.$event);
});
internalData.uFoot = false;
updateQueryFooter();
}
$xeGantt.dispatchEvent('form-submit', params, params.$event);
};
const resetFormEvent = (params) => {
const $xeTable = refTable.value;
const { proxyConfig } = props;
const { $event } = params;
const proxyOpts = computeProxyOpts.value;
if (proxyConfig && isEnableConf(proxyOpts)) {
if ($xeTable) {
$xeTable.clearScroll();
}
internalData.uFoot = true;
$xeGantt.commitProxy('reload').then((rest) => {
$xeGantt.dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isReload: true }), $event);
});
internalData.uFoot = false;
updateQueryFooter();
}
$xeGantt.dispatchEvent('form-reset', params, $event);
};
const submitInvalidEvent = (params) => {
$xeGantt.dispatchEvent('form-submit-invalid', params, params.$event);
};
const collapseEvent = (params) => {
const { $event } = params;
$xeGantt.dispatchEvent('form-toggle-collapse', params, $event);
$xeGantt.dispatchEvent('form-collapse', params, $event);
};
const handleZoom = (isMax) => {
const { isZMax } = reactData;
if (isMax ? !isZMax : isZMax) {
reactData.isZMax = !isZMax;
if (reactData.tZindex < getLastZIndex()) {
reactData.tZindex = nextZIndex();
}
}
return nextTick()
.then(() => $xeGantt.recalculate(true))
.then(() => {
setTimeout(() => $xeGantt.recalculate(true), 15);
return reactData.isZMax;
});
};
const getFuncSlot = (optSlots, slotKey) => {
const funcSlot = optSlots[slotKey];
if (funcSlot) {
if (XEUtils.isString(funcSlot)) {
if (slots[funcSlot]) {
return slots[funcSlot];
}
else {
errLog('vxe.error.notSlot', [funcSlot]);
}
}
else {
return funcSlot;
}
}
return null;
};
const getConfigSlot = (slotConfigs) => {
const slotConf = {};
XEUtils.objectMap(slotConfigs, (slotFunc, slotKey) => {
if (slotFunc) {
if (XEUtils.isString(slotFunc)) {
if (slots[slotFunc]) {
slotConf[slotKey] = slots[slotFunc];
}
else {
errLog('vxe.error.notSlot', [slotFunc]);
}
}
else {
slotConf[slotKey] = slotFunc;
}
}
});
return slotConf;
};
const dragSplitEvent = (evnt) => {
const el = refElem.value;
if (!el) {
return;
}
const ganttContainerEl = refGanttContainerElem.value;
if (!ganttContainerEl) {
return;
}
const tableWrapperEl = refTableWrapper.value;
if (!tableWrapperEl) {
return;
}
const rsSplitLineEl = refResizableSplitTip.value;
if (!rsSplitLineEl) {
return;
}
const taskViewOpts = computeTaskViewOpts.value;
const containerRect = ganttContainerEl.getBoundingClientRect();
const rsSplitTipEl = rsSplitLineEl.children[0];
const disX = evnt.clientX;
const ganttWidth = ganttContainerEl.clientWidth;
const tableWidth = tableWrapperEl.clientWidth;
const tableMinWidth = (taskViewOpts.tableStyle && XEUtils.toNumber(taskViewOpts.tableStyle.minWidth)) || 80;
let targetTableWidth = tableWidth;
let offsetLeft = -1;
addClass(el, 'is--split-drag');
const handleReStyle = (evnt) => {
const rsNumLeftEl = rsSplitTipEl.children[0];
const rsNumRightEl = rsSplitTipEl.children[1];
let tipHeight = 0;
if (rsNumLeftEl) {
if (offsetLeft < 0) {
rsNumLeftEl.style.display = 'none';
}
else {
rsNumLeftEl.textContent = `${targetTableWidth}px`;
rsNumLeftEl.style.display = 'block';
tipHeight = rsNumLeftEl.offsetHeight;
}
}
if (rsNumRightEl) {
if (offsetLeft < 0) {
rsNumRightEl.textContent = `${Math.floor(containerRect.width - targetTableWidth)}px`;
rsNumRightEl.style.display = 'block';
tipHeight = rsNumRightEl.offsetHeight;
}
else {
rsNumRightEl.style.display = 'none';
}
}
const tipTop = evnt.clientY - containerRect.top - tipHeight / 2;
rsSplitLineEl.style.left = `${targetTableWidth}px`;
rsSplitTipEl.style.top = `${Math.min(containerRect.height - tipHeight - 1, Math.max(1, tipTop))}px`;
};
document.onmousemove = (evnt) => {
evnt.preventDefault();
offsetLeft = (evnt.clientX - disX);
targetTableWidth = Math.min(ganttWidth - 80, Math.max(tableMinWidth, tableWidth + offsetLeft));
handleReStyle(evnt);
};
document.onmouseup = () => {
document.onmousemove = null;
document.onmouseup = null;
rsSplitLineEl.style.display = '';
tableWrapperEl.style.width = `${targetTableWidth}px`;
removeClass(el, 'is--split-drag');
const $xeTable = refTable.value;
if ($xeTable) {
$xeTable.recalculate(true);
}
};
rsSplitLineEl.style.display = 'block';
handleReStyle(evnt);
};
const handleSplitAnimat = () => {
const taskSplitOpts = computeTaskSplitOpts.value;
const { animation } = taskSplitOpts;
if (animation) {
const { _taTime } = internalData;
if (_taTime) {
clearTimeout(_taTime);
}
reactData.showSplitAnimat = true;
internalData._taTime = setTimeout(() => {
reactData.showSplitAnimat = false;
internalData._taTime = null;
}, 350);
}
};
const handleSplitLeftViewEvent = () => {
handleSplitAnimat();
reactData.showLeftView = !reactData.showLeftView;
};
const handleSplitRightViewEvent = () => {
handleSplitAnimat();
reactData.showRightView = !reactData.showRightView;
};
const tableCompEvents = {};
tableEmits.forEach(name => {
const type = XEUtils.camelCase(`on-${name}`);
tableCompEvents[type] = (...args) => emit(name, ...args);
});
const getDefaultFormData = () => {
const formOpts = computeFormOpts.value;
if (formOpts.items) {
const fData = {};
formOpts.items.forEach(item => {
const { field, itemRender } = item;
if (field) {
let itemValue = null;
if (itemRender) {
const { startField, endField, defaultValue } = itemRender;
if (XEUtils.isFunction(defaultValue)) {
itemValue = defaultValue({ item });
}
else if (!XEUtils.isUndefined(defaultValue)) {
itemValue = defaultValue;
}
if (startField && endField) {
XEUtils.set(fData, startField, null);
XEUtils.set(fData, endField, null);
}
}
fData[field] = itemValue;
}
});
return fData;
}
return {};
};
const initProxy = () => {
const { proxyConfig, formConfig } = props;
const { proxyInited } = reactData;
const proxyOpts = computeProxyOpts.value;
const formOpts = computeFormOpts.value;
if (proxyConfig && isEnableConf(proxyOpts)) {
if (formConfig && isEnableConf(formOpts) && proxyOpts.form && formOpts.items) {
reactData.formData = getDefaultFormData();
}
if (!proxyInited) {
reactData.proxyInited = true;
if (proxyOpts.autoLoad !== false) {
nextTick().then(() => {
internalData.uFoot = true;
const rest = $xeGantt.commitProxy('initial');
internalData.uFoot = false;
updateQueryFooter();
return rest;
}).then((rest) => {
dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isInited: true }), new Event('initial'));
});
}
}
}
};
const updateQueryFooter = () => {
const proxyOpts = computeProxyOpts.value;
const { ajax } = proxyOpts;
if (ajax && ajax.queryFooter) {
return $xeGantt.commitProxy('queryFooter');
}
};
const handleGlobalKeydownEvent = (evnt) => {
const zoomOpts = computeZoomOpts.value;
const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
if (isEsc && reactData.isZMax && zoomOpts.escRestore !== false) {
$xeGantt.triggerZoomEvent(evnt);
}
};
const dispatchEvent = (type, params, evnt) => {
emit(type, createEvent(evnt, { $grid: null, $gantt: $xeGantt }, params));
};
const handleTargetEnterEvent = (isClear) => {
const $tooltip = refTooltip.value;
clearTimeout(internalData.barTipTimeout);
if (isClear) {
$xeGantt.closeTaskBarTooltip();
}
else {
if ($tooltip && $tooltip.setActived) {
$tooltip.setActived(true);
}
}
};
const ganttMethods = {
dispatchEvent,
getEl() {
return refElem.value;
},
/**
* 提交指令,支持 code 或 button
* @param {String/Object} code 字符串或对象
*/
commitProxy(proxyTarget, ...args) {
const { showFooter, proxyConfig, toolbarConfig, pagerConfig, editRules, validConfig } = props;
const { tablePage } = reactData;
const isActiveMsg = computeIsActiveMsg.value;
const isRespMsg = computeIsRespMsg.value;
const proxyOpts = computeProxyOpts.value;
const pagerOpts = computePagerOpts.value;
const toolbarOpts = computeToolbarOpts.value;
const { beforeQuery: oldBeforeQuery, afterQuery: oldAfterQuery, beforeQueryFooter: oldBeforeQueryFooter, afterQueryFooter: oldAfterQueryFooter, beforeDelete: oldBeforeDelete, afterDelete: oldAfterDelete, beforeSave: oldBeforeSave, afterSave: oldAfterSave, ajax = {} } = proxyOpts;
const resConfigs = (proxyOpts.response || proxyOpts.props || {});
const $xeTable = refTable.value;
if (!$xeTable) {
return nextTick();
}
let formData = getFormData();
let button = null;
let code = null;
if (XEUtils.isString(proxyTarget)) {
const { buttons } = toolbarOpts;
const matchObj = toolbarConfig && isEnableConf(toolbarOpts) && buttons ? XEUtils.findTree(buttons, (item) => item.code === proxyTarget, { children: 'dropdowns' }) : null;
button = matchObj ? matchObj.item : null;
code = proxyTarget;
}
else {
button = proxyTarget;
code = button.code;
}
const btnParams = button ? button.params : null;
switch (code) {
case 'insert':
return $xeTable.insert({});
case 'insert_edit':
return $xeTable.insert({}).then(({ row }) => $xeTable.setEditRow(row, true));
// 已废弃
case 'insert_actived':
return $xeTable.insert({}).then(({ row }) => $xeTable.setEditRow(row, true));
// 已废弃
case 'mark_cancel':
triggerPendingEvent(code);
break;
case 'remove':
return handleDeleteRow(code, 'vxe.grid.removeSelectRecord', () => $xeTable.removeCheckboxRow());
case 'import':
$xeTable.importData(btnParams);
break;
case 'open_import':
$xeTable.openImport(btnParams);
break;
case 'export':
$xeTable.exportData(btnParams);
break;
case 'open_export':
$xeTable.openExport(btnParams);
break;
case 'reset_custom':
return $xeTable.resetCustom(true);
case 'initial':
case 'reload':
case 'query': {
const bqMethod = ajax.beforeQuery;
const qMethod = ajax.query;
const aqMethod = ajax.afterQuery;
const qsMethod = ajax.querySuccess;
const qeMethod = ajax.queryError;
if (qMethod) {
const isInited = code === 'initial';
const isReload = code === 'reload';
if (!isInited && reactData.tableLoading) {
return nextTick();
}
let operPromise = null;
let sortList = [];
let filterList = [];
let pageParams = {};
if (pagerConfig) {
if (isInited || isReload) {
// 重置分页
tablePage.currentPage = 1;
}
if (isEnableConf(pagerOpts)) {
pageParams = Object.assign({}, tablePage);
}
}
if (isInited) {
// 重置代理表单数据
if (proxyConfig && isEnableConf(proxyOpts) && proxyOpts.form) {
formData = getDefaultFormData();
reactData.formData = formData;
}
if ($xeTable) {
const tableInternalData = $xeTable.internalData;
const { tableFullColumn, fullColumnFieldData } = tableInternalData;
const { computeSortOpts } = $xeTable.getComputeMaps();
const sortOpts = computeSortOpts.value;
let defaultSort = sortOpts.defaultSort;
tableFullColumn.forEach((column) => {
column.order = null;
});
// 如果使用默认排序
if (defaultSort) {
if (!XEUtils.isArray(defaultSort)) {
defaultSort = [defaultSort];
}
sortList = defaultSort.map((item) => {
const { field, order } = item;
const colRest = fullColumnFieldData[field];
if (colRest) {
const column = colRest.column;
if (column) {
column.order = order;
}
}
return {
field,
property: field,
order
};
});
}
filterList = $xeTable.getCheckedFilters();
}
}
else {
if ($xeTable) {
if (isReload) {
operPromise = $xeTable.clearAll();
}
else {
sortList = $xeTable.getSortColumns();
filterList = $xeTable.getCheckedFilters();
}
}
}
const commitParams = {
$table: $xeTable,
$grid: null,
$gantt: $xeGantt,
code,
button,
isInited,
isReload,
page: pageParams,
sort: sortList.length ? sortList[0] : {},
sorts: sortList,
filters: filterList,
form: formData,
options: qMethod
};
const handleQuery = () => {
reactData.sortData = sortList;
reactData.filterData = filterList;
reactData.tableLoading = true;
return Promise.all([
Promise.resolve((oldBeforeQuery || qMethod)(commitParams, ...args)),
operPromise
]).then(([rest]) => {
reactData.tableLoading = false;
if (aqMethod) {
aqMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'success' }), ...args);
}
else {
let tableData = [];
if (rest) {
const reParams = { data: rest, $table: $xeTable, $grid: null, $gantt: $xeGantt };
if (pagerConfig && isEnableConf(pagerOpts)) {
const totalProp = resConfigs.total;
const total = (XEUtils.isFunction(totalProp) ? totalProp(reParams) : XEUtils.get(rest, totalProp || 'page.total')) || 0;
tablePage.total = XEUtils.toNumber(total);
const resultProp = resConfigs.result;
tableData = (XEUtils.isFunction(resultProp) ? resultProp(reParams) : XEUtils.get(rest, resultProp || 'result')) || [];
// 检验当前页码,不能超出当前最大页数
const pageCount = Math.max(Math.ceil(total / tablePage.pageSize), 1);
if (tablePage.currentPage > pageCount) {
tablePage.currentPage = pageCount;
}
}
else {
const listProp = resConfigs.list;
if (XEUtils.isArray(rest)) {
tableData = rest;
}
else if (listProp) {
tableData = (XEUtils.isFunction(listProp) ? listProp(reParams) : XEUtils.get(rest, listProp)) || [];
}
}
if (showFooter) {
const fdProp = resConfigs.footerData;
const footerList = fdProp ? (XEUtils.isFunction(fdProp) ? fdProp(reParams) : XEUtils.get(rest, fdProp)) : [];
if (XEUtils.isArray(footerList)) {
reactData.footerData = footerList;
}
}
}
if ($xeTable) {
$xeTable.loadData(tableData);
}
else {
nextTick(() => {
const $xeTable = refTable.value;
if ($xeTable) {
$xeTable.loadData(tableData);
}
});
}
if (oldAfterQuery) {
oldAfterQuery(Object.assign(Object.assign({}, commitParams), { response: rest }), ...args);
}
}
if (qsMethod) {
qsMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: true };
}).catch((rest) => {
reactData.tableLoading = false;
if (aqMethod) {
aqMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'error' }), ...args);
}
if (qeMethod) {
qeMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: false };
});
};
if (bqMethod) {
return Promise.resolve(bqMethod(commitParams, ...args)).then(status => {
if (status !== false) {
return handleQuery();
}
});
}
return handleQuery();
}
else {
errLog('vxe.error.notFunc', ['proxy-config.ajax.query']);
}
break;
}
case 'queryFooter': {
const bqfMethod = ajax.beforeQueryFooter;
const qfMethod = ajax.queryFooter;
const aqfMethod = ajax.afterQueryFooter;
const qfSuccessMethod = ajax.queryFooterSuccess;
const qfErrorMethod = ajax.queryFooterError;
if (qfMethod) {
let filterList = [];
if ($xeTable) {
filterList = $xeTable.getCheckedFilters();
}
let pageParams = {};
if (pagerConfig) {
if (isEnableConf(pagerOpts)) {
pageParams = Object.assign({}, tablePage);
}
}
const commitParams = {
$table: $xeTable,
$grid: null,
$gantt: $xeGantt,
code,
button,
page: pageParams,
filters: filterList,
form: formData,
options: qfMethod
};
const handleQueryFooter = () => {
return Promise.resolve((oldBeforeQueryFooter || qfMethod)(commitParams, ...args)).then(rest => {
if (aqfMethod) {
aqfMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'success' }), ...args);
}
else {
reactData.footerData = XEUtils.isArray(rest) ? rest : [];
if (oldAfterQueryFooter) {
oldAfterQueryFooter(Object.assign(Object.assign({}, commitParams), { response: rest }), ...args);
}
}
if (qfSuccessMethod) {
qfSuccessMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: true };
}).catch((rest) => {
if (aqfMethod) {
aqfMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'error' }), ...args);
}
if (qfErrorMethod) {
qfErrorMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: false };
});
};
if (bqfMethod) {
return Promise.resolve(bqfMethod(commitParams, ...args)).then(status => {
if (status !== false) {
return handleQueryFooter();
}
});
}
return handleQueryFooter();
}
else {
errLog('vxe.error.notFunc', ['proxy-config.ajax.queryFooter']);
}
break;
}
case 'delete': {
const bdMethod = ajax.beforeDelete;
const dMethod = ajax.delete;
const adMethod = ajax.afterDelete;
const deleteSuccessMethods = ajax.deleteSuccess;
const deleteErrorMethods = ajax.deleteError;
if (dMethod) {
const selectRecords = $xeGantt.getCheckboxRecords();
const removeRecords = selectRecords.filter(row => !$xeTable.isInsertByRow(row));
const body = { removeRecords };
const commitParams = {
$table: $xeTable,
$grid: null,
$gantt: $xeGantt,
code,
button,
body,
form: formData,
options: dMethod
};
if (selectRecords.length) {
return handleDeleteRow(code, 'vxe.grid.deleteSelectRecord', () => {
if (!removeRecords.length) {
return $xeTable.remove(selectRecords);
}
const handleDelete = () => {
reactData.tableLoading = true;
return Promise.resolve((oldBeforeDelete || dMethod)(commitParams, ...args))
.then(rest => {
reactData.tableLoading = false;
if (adMethod) {
adMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'success' }), ...args);
}
else {
$xeTable.setPendingRow(removeRecords, false);
if (isRespMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ content: getRespMsg(rest, 'vxe.grid.delSuccess'), status: 'success' });
}
}
if (oldAfterDelete) {
oldAfterDelete(Object.assign(Object.assign({}, commitParams), { response: rest }), ...args);
}
else {
internalData.uFoot = true;
$xeGantt.commitProxy('query');
internalData.uFoot = false;
updateQueryFooter();
}
}
if (deleteSuccessMethods) {
deleteSuccessMethods(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: true };
})
.catch(rest => {
reactData.tableLoading = false;
if (adMethod) {
adMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'error' }), ...args);
}
else {
if (isRespMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ id: code, content: getRespMsg(rest, 'vxe.grid.operError'), status: 'error' });
}
}
}
if (deleteErrorMethods) {
deleteErrorMethods(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: false };
});
};
if (bdMethod) {
return Promise.resolve(bdMethod(commitParams, ...args)).then(status => {
if (status !== false) {
return handleDelete();
}
});
}
return handleDelete();
});
}
else {
if (isActiveMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' });
}
}
}
}
else {
errLog('vxe.error.notFunc', ['proxy-config.ajax.delete']);
}
break;
}
case 'save': {
const bSaveMethod = ajax.beforeSave;
const sMethod = ajax.save;
const aSaveMethod = ajax.afterSave;
const sSuccessMethod = ajax.saveSuccess;
const sErrorMethod = ajax.saveError;
if (sMethod) {
const body = $xeTable.getRecordset();
const { insertRecords, removeRecords, updateRecords, pendingRecords } = body;
const commitParams = {
$table: $xeTable,
$grid: null,
$gantt: $xeGantt,
code,
button,
body,
form: formData,
options: sMethod
};
// 排除掉新增且标记为删除的数据
if (insertRecords.length) {
body.pendingRecords = pendingRecords.filter((row) => $xeTable.findRowIndexOf(insertRecords, row) === -1);
}
// 排除已标记为删除的数据
if (pendingRecords.length) {
body.insertRecords = insertRecords.filter((row) => $xeTable.findRowIndexOf(pendingRecords, row) === -1);
}
let restPromise = Promise.resolve();
if (editRules) {
// 只校验新增和修改的数据
restPromise = $xeTable[validConfig && validConfig.msgMode === 'full' ? 'fullValidate' : 'validate'](body.insertRecords.concat(updateRecords));
}
return restPromise.then((errMap) => {
if (errMap) {
// 如果校验不通过
return;
}
if (body.insertRecords.length || removeRecords.length || updateRecords.length || body.pendingRecords.length) {
const handleSave = () => {
reactData.tableLoading = true;
return Promise.resolve((oldBeforeSave || sMethod)(commitParams, ...args))
.then(rest => {
reactData.tableLoading = false;
if (aSaveMethod) {
aSaveMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'success' }), ...args);
}
else {
$xeTable.clearPendingRow();
if (isRespMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ content: getRespMsg(rest, 'vxe.grid.saveSuccess'), status: 'success' });
}
}
if (oldAfterSave) {
oldAfterSave(Object.assign(Object.assign({}, commitParams), { response: rest }), ...args);
}
else {
internalData.uFoot = true;
$xeGantt.commitProxy('query');
internalData.uFoot = false;
updateQueryFooter();
}
}
if (sSuccessMethod) {
sSuccessMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: true };
})
.catch(rest => {
reactData.tableLoading = false;
if (aSaveMethod) {
aSaveMethod(Object.assign(Object.assign({}, commitParams), { response: rest, status: 'error' }), ...args);
}
else {
if (isRespMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ id: code, content: getRespMsg(rest, 'vxe.grid.operError'), status: 'error' });
}
}
}
if (sErrorMethod) {
sErrorMethod(Object.assign(Object.assign({}, commitParams), { response: rest }));
}
return { status: false };
});
};
if (bSaveMethod) {
return Promise.resolve(bSaveMethod(commitParams, ...args)).then(status => {
if (status !== false) {
return handleSave();
}
});
}
return handleSave();
}
else {
if (isActiveMsg) {
if (VxeUI.modal) {
VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.dataUnchanged'), status: 'info' });
}
}
}
});
}
else {
errLog('vxe.error.notFunc', ['proxy-config.ajax.save']);
}
break;
}
default: {
const gCommandOpts = commands.get(code);
if (gCommandOpts) {
const tCommandMethod = gCommandOpts.tableCommandMethod || gCommandOpts.commandMethod;
if (tCommandMethod) {
tCommandMethod({ code, button, $table: $xeTable, $grid: null, $gantt: $xeGantt }, ...args);
}
else {
errLog('vxe.error.notCommands', [code]);
}
}
}
}
return nextTick();
},
getParams() {
return props.params;
},
zoom() {
if (reactData.isZMax) {
return $xeGantt.revert();
}
return $xeGantt.maximize();
},
isMaximized() {
return reactData.isZMax;
},
maximize() {
return handleZoom(true);
},
revert() {
return handleZoom();
},
getFormData,
/**
* 已废弃,被 getFormFlatItems 替换
* @deprecated
*/
getFormItems(itemIndex) {
const formOpts = computeFormOpts.value;
const { formConfig } = props;
const { items } = formOpts;
const itemList = [];
XEUtils.eachTree(formConfig && isEnableConf(formOpts) && items ? items : [], item => {
itemList.push(item);
}, { children: 'children' });
// errLog('vxe.error.delFunc', ['getFormItems', 'getFormFlatItems'])
return XEUtils.isUndefined(itemIndex) ? itemList : itemList[itemIndex];
},
getFormFlatItems() {
const $form = refForm.value;
if ($form) {
return $form.getFlatItems();
}
return [];
},
getFormNestedItems() {
const $form = refForm.value;
if ($form) {
return $form.getNestedItems();
}
return [];
},
getFormItemByField(field) {
const $form = refForm.value;
if ($form) {
return $form.getItemByField(field);
}
return null;
},
resetForm() {
const $form = refForm.value;
if ($form) {
return $form.reset();
}
return nextTick();
},
validateForm() {
const $form = refForm.value;
if ($form) {
return $form.validate();
}
return nextTick();
},
validateFormField(field) {
const $form = refForm.value;
if ($form) {
return $form.validateField(field);
}
return nextTick();
},
clearFormValidate(field) {
const $form = refForm.value;
if ($form) {
return $form.clearValidate(field);
}
return nextTick();
},
homePage() {
const { tablePage } = reactData;
tablePage.currentPage = 1;
return nextTick();
},
homePageByEvent(evnt) {
const $pager = refPager.value;
if ($pager) {
$pager.homePageByEvent(evnt);
}
},
endPage() {
const { tablePage } = reactData;
const pageCount = computePageCount.value;
tablePage.currentPage = pageCount;
return nextTick();
},
endPageByEvent(evnt) {
const $pager = refPager.value;
if ($pager) {
$pager.endPageByEvent(evnt);
}
},
getCurrentPage() {
const { tablePage } = reactData;
return tablePage.currentPage;
},
setCurrentPage(currentPage) {
const { tablePage } = reactData;
const pageCount = computePageCount.value;
tablePage.currentPage = Math.min(pageCount, Math.max(1, XEUtils.toNumber(currentPage)));
return nextTick();
},
setCurrentPageByEvent(evnt, currentPage) {
const $pager = refPager.value;
if ($pager) {
$pager.setCurrentPageByEvent(evnt, currentPage);
}
},
getPageSize() {
const { tablePage } = reactData;
return tablePage.pageSize;
},
setPageSize(pageSize) {
const { tablePage } = reactData;
tablePage.pageSize = Math.max(1, XEUtils.toNumber(pageSize));
return nextTick();
},
setPageSizeByEvent(evnt, pageSize) {
const $pager = refPager.value;
if ($pager) {
$pager.setPageSizeByEvent(evnt, pageSize);
}
},
getProxyInfo() {
const $xeTable = refTable.value;
if (props.proxyConfig) {
const { sortData } = reactData;
return {
data: $xeTable ? $xeTable.getFullData() : [],
filter: reactData.filterData,
form: getFormData(),
sort: sortData.length ? sortData[0] : {},
sorts: sortData,
pager: reactData.tablePage,
pendingRecords: $xeTable ? $xeTable.getPendingRecords() : []
};
}
return null;
},
getCustomPagerData() {
const { pagerConfig } = props;
const { tablePage } = reactData;
const pagerOpts = computePagerOpts.value;
if (pagerConfig && isEnableConf(pagerOpts)) {
return {
pSize: tablePage.pageSize
};
}
return {};
},
// setProxyInfo (options) {
// if (props.proxyConfig && options) {
// const { pager, form } = options
// const proxyOpts = computeProxyOpts.value
// if (pager) {
// if (pager.currentPage) {
// reactData.tablePage.currentPage = Number(pager.currentPage)
// }
// if (pager.pageSize) {
// reactData.tablePage.pageSize = Number(pager.pageSize)
// }
// }
// if (proxyOpts.form && form) {
// Object.assign(reactData.formData, form)
// }
// }
// return nextTick()
// },
refreshTaskView() {
const $ganttView = refGanttView.value;
if ($ganttView) {
return $ganttView.refreshData();
}
return nextTick();
},
hasTableViewVisible() {
return reactData.showLeftView;
},
showTableView() {
reactData.showLeftView = true;
return nextTick();
},
hideTableView() {
reactData.showLeftView = false;
// 至少显示一个
if (!reactData.showRightView) {
reactData.showRightView = true;
}
return nextTick();
},
hasTaskViewVisible() {
return reactData.showRightView;
},
showTaskView() {
reactData.showRightView = true;
return nextTick();
},
hideTaskView() {
reactData.showRightView = false;
// 至少显示一个
if (!reactData.showLeftView) {
reactData.showLeftView = true;
}
return nextTick();
},
/**
* 关闭 bar tooltip
*/
closeTaskBarTooltip() {
const { barTipStore } = reactData;
const $tooltip = refTooltip.value;
if (barTipStore.visible) {
Object.assign(barTipStore, {
row: null,
content: null,
visible: false,
params: {}
});
if ($tooltip && $tooltip.close) {
$tooltip.close();
}
}
return nextTick();
},
scrollToDateView(colDate) {
const $ganttView = refGanttView.value;
if ($ganttView) {
const ganttViewReactData = $ganttView.reactData;
const ganttViewInternalData = $ganttView.internalData;
const { viewCellWidth } = ganttViewReactData;
const { visibleColumn, elemStore } = ganttViewInternalData;
const currDate = XEUtils.toStringDate(colDate);
const currTime = currDate.getTime();
const colIndex = XEUtils.findIndexOf(visibleColumn, column => currTime === column.dateObj.date.getTime());
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (colIndex > -1 && bodyScrollElem) {
bodyScrollElem.scrollLeft = XEUtils.floor(colIndex * viewCellWidth);
}
}
return nextTick();
},
scrollToTaskView(rowOrRowid) {
const $xeTable = refTable.value;
if ($xeTable) {
const rowid = XEUtils.isString(rowOrRowid) || XEUtils.isNumber(rowOrRowid) ? rowOrRowid : $xeTable.getRowid(rowOrRowid);
return $xeTable.scrollToRow(rowOrRowid).then(() => {
const $ganttView = refGanttView.value;
if ($ganttView) {
const ganttViewReactData = $ganttView.reactData;
const ganttViewInternalData = $ganttView.internalData;
const { viewCellWidth } = ganttViewReactData;
const { chartMaps, elemStore } = ganttViewInternalData;
const chartRest = rowid ? chartMaps[rowid] : null;
if (chartRest) {
const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
if (bodyScrollElem) {
bodyScrollElem.scrollLeft = XEUtils.floor(chartRest.oLeftSize * viewCellWidth);
}
}
}
});
}
return nextTick();
},
getCriticalPath() {
const { criticalRowIds, criticalLinks } = reactData;
const { criticalRowMaps } = internalData;
return {
rowIds: criticalRowIds.slice(0),
rows: Array.from(criticalRowMaps.values()),
links: criticalLinks.slice(0)
};
}
};
const ganttPrivateMethods = {
extendTableMethods,
callSlot(slotFunc, params) {
if (slotFunc) {
if (XEUtils.isString(slotFunc)) {
slotFunc = slots[slotFunc] || null;
}
if (XEUtils.isFunction(slotFunc)) {
return getSlotVNs(slotFunc(params));
}
}
return [];
},
/**
* 获取需要排除的高度
*/
getExcludeHeight() {
const { height } = props;
const { isZMax } = reactData;
const el = refElem.value;
if (el) {
const formWrapper = refFormWrapper.value;
const toolbarWrapper = refToolbarWrapper.value;
const topWrapper = refTopWrapper.value;
const bottomWrapper = refBottomWrapper.value;
const pagerWrapper = refPagerWrapper.value;
const parentEl = el.parentElement;
let parentPaddingSize = 0;
if (parentEl && (height === '100%' || height === 'auto')) {
parentPaddingSize = isZMax ? 0 : getPaddingTopBottomSize(parentEl);
}
return parentPaddingSize + getPaddingTopBottomSize(el) + getOffsetHeight(formWrapper) + getOffsetHeight(toolbarWrapper) + getOffsetHeight(topWrapper) + getOffsetHeight(bottomWrapper) + getOffsetHeight(pagerWrapper);
}
return 0;
},
getParentElem() {
const el = refElem.value;
if (!el) {
return null;
}
let parentEl = el.parentElement;
// 如果是虚拟滚动条
if (parentEl && hasClass(parentEl, 'vxe-scrollbar--view-inner')) {
parentEl = parentEl.parentElement;
}
return parentEl;
},
getParentHeight() {
const el = refElem.value;
if (el) {
const parentEl = $xeGantt.getParentElem();
return (reactData.isZMax ? getDomNode().visibleHeight : (parentEl ? XEUtils.toNumber(getComputedStyle(parentEl).height) : 0)) - ganttPrivateMethods.getExcludeHeight();
}
return 0;
},
triggerToolbarCommitEvent(params, evnt) {
const { code } = params;
if (code) {
const isUf = ['reload', 'delete', 'save'].includes(code);
if (isUf) {
internalData.uFoot = true;
}
const rest = $xeGantt.commitProxy(params, evnt).then((rest) => {
if (rest && rest.status && ['query', 'reload', 'delete', 'save'].includes(code)) {
$xeGantt.dispatchEvent(code === 'delete' || code === 'save' ? `proxy-${code}` : 'proxy-query', Object.assign(Object.assign({}, rest), { isReload: code === 'reload' }), evnt);
}
});
internalData.uFoot = false;
if (isUf) {
updateQueryFooter();
}
return rest;
}
return nextTick();
},
triggerToolbarBtnEvent(button, evnt) {
$xeGantt.triggerToolbarCommitEvent(button, evnt);
$xeGantt.dispatchEvent('toolbar-button-click', { code: button.code, button }, evnt);
},
triggerToolbarTolEvent(tool, evnt) {
$xeGantt.triggerToolbarCommitEvent(tool, evnt);
$xeGantt.dispatchEvent('toolbar-tool-click', { code: tool.code, tool }, evnt);
},
triggerZoomEvent(evnt) {
$xeGantt.zoom();
$xeGantt.dispatchEvent('zoom', { type: reactData.isZMax ? 'max' : 'revert' }, evnt);
},
handleTaskCellClickEvent(evnt, params) {
const $xeTable = refTable.value;
if ($xeTable) {
const tableProps = $xeTable.props;
const { highlightCurrentRow } = tableProps;
const tableReactData = $xeTable.reactData;
const { radioColumn, checkboxColumn } = tableReactData;
const { computeRadioOpts, computeCheckboxOpts, computeRowOpts } = $xeTable.getComputeMaps();
const radioOpts = computeRadioOpts.value;
const checkboxOpts = computeCheckboxOpts.value;
const rowOpts = computeRowOpts.value;
const { row } = params;
// 如果是当前行
if (rowOpts.isCurrent || highlightCurrentRow) {
$xeTable.triggerCurrentRowEvent(evnt, Object.assign({
$table: $xeTable,
rowIndex: $xeTable.getRowIndex(row),
$rowIndex: $xeTable.getVMRowIndex(row)
}, params));
}
// 如果是单选框
if ((radioColumn && radioOpts.trigger === 'row')) {
$xeTable.triggerRadioRowEvent(evnt, params);
}
// 如果是复选框
if ((checkboxColumn && checkboxOpts.trigger === 'row')) {
$xeTable.handleToggleCheckRowEvent(evnt, params);
}
}
reactData.isActiveCeLe = false;
reactData.activeBarRowid = null;
reactData.activeLink = null;
$xeGantt.dispatchEvent('task-cell-click', params, evnt);
},
handleTaskCellDblclickEvent(evnt, params) {
$xeGantt.dispatchEvent('task-cell-dblclick', params, evnt);
},
handleTaskBarClickEvent(evnt, params) {
const $xeTable = refTable.value;
const taskBarOpts = computeTaskBarOpts.value;
const { linkCreatable } = taskBarOpts;
const { row } = params;
reactData.isActiveCeLe = !!linkCreatable;
reactData.activeBarRowid = $xeTable ? $xeTable.getRowid(row) : row;
reactData.activeLink = null;
$xeGantt.dispatchEvent('task-bar-click', params, evnt);
},
handleTaskBarDblclickEvent(evnt, params) {
$xeGantt.dispatchEvent('task-bar-dblclick', params, evnt);
},
triggerTaskBarTooltipEvent(evnt, params) {
const { barTipStore, activeLink } = reactData;
const { dragBarRow, dragLineRow } = internalData;
if (dragBarRow || dragLineRow) {
return;
}
if (activeLink) {
return;
}
const taskBarTooltipOpts = computeTaskBarTooltipOpts.value;
const titleField = computeTitleField.value;
const { contentMethod } = taskBarTooltipOpts;
const { row } = params;
let content = formatText(XEUtils.get(row, titleField));
if (contentMethod) {
const customContnet = contentMethod(params);
if (!XEUtils.eqNull(customContnet)) {
content = `${customContnet}`;
}
}
handleTargetEnterEvent(barTipStore.row !== row);
const tipContent = formatText(content);
Object.assign(barTipStore, {
row,
visible: true,
content: tipContent,
params
});
nextTick(() => {
const $tooltip = refTooltip.value;
if ($tooltip) {
if ($tooltip.openByEvent) {
$tooltip.openByEvent(evnt, evnt.currentTarget, tipContent);
}
else if ($tooltip.open) {
$tooltip.open(evnt.currentTarget, tipContent);
}
}
});
},
handleTaskBarTooltipLeaveEvent() {
const taskBarTooltipOpts = computeTaskBarTooltipOpts.value;
let $tooltip = refTooltip.value;
if ($tooltip && $tooltip.setActived) {
$tooltip.setActived(false);
}
if (taskBarTooltipOpts.enterable) {
internalData.barTipTimeout = setTimeout(() => {
$tooltip = refTooltip.value;
if ($tooltip && $tooltip.isActived && !$tooltip.isActived()) {
$xeGantt.closeTaskBarTooltip();
}
}, taskBarTooltipOpts.leaveDelay);
}
else {
$xeGantt.closeTaskBarTooltip();
}
},
handleTaskHeaderContextmenuEvent(evnt, params) {
const $xeTable = refTable.value;
if ($xeTable) {
const tableProps = $xeTable.props;
const { menuConfig } = tableProps;
if (isEnableConf(menuConfig)) {
evnt.stopPropagation();
$xeTable.handleOpenMenuEvent(evnt, 'header', params);
$xeTable.dispatchEvent('header-cell-menu', params, evnt);
}
}
},
handleTaskBodyContextmenuEvent(evnt, params) {
const $xeTable = refTable.value;
if ($xeTable) {
const tableProps = $xeTable.props;
const { menuConfig } = tableProps;
if (isEnableConf(menuConfig)) {
evnt.stopPropagation();
$xeTable.handleOpenMenuEvent(evnt, 'body', params);
$xeTable.dispatchEvent('cell-menu', params, evnt);
}
}
},
handleTaskFooterContextmenuEvent(evnt, params) {
const $xeTable = refTable.value;
if ($xeTable) {
const tableProps = $xeTable.props;
const { menuConfig } = tableProps;
if (isEnableConf(menuConfig)) {
evnt.stopPropagation();
$xeTable.handleOpenMenuEvent(evnt, 'footer', params);
$xeTable.dispatchEvent('footer-cell-menu', params, evnt);
}
}
},
handleTaskBarContextmenuEvent(evnt, params) {
const $xeTable = refTable.value;
if ($xeTable) {
const tableProps = $xeTable.props;
const { menuConfig } = tableProps;
if (isEnableConf(menuConfig)) {
evnt.stopPropagation();
$xeTable.handleOpenMenuEvent(evnt, 'body', params);
$xeTable.dispatchEvent('cell-menu', params, evnt);
}
}
}
};
Object.assign($xeGantt, ganttExtendTableMethods, ganttMethods, ganttPrivateMethods, {
loadColumn(columns) {
const $xeTable = refTable.value;
// 检查插槽
XEUtils.eachTree(columns, (column) => {
const { type } = column;
if (column.slots) {
XEUtils.each(column.slots, (func) => {
if (!XEUtils.isFunction(func)) {
if (!slots[func]) {
errLog('vxe.error.notSlot', [func]);
}
}
});
}
if (type === 'expand') {
errLog('vxe.error.errProp', ['type=expand', 'type=seq,radio,checkbox,html']);
}
});
reactData.currLeftSpacing = 0;
reactData.currRightSpacing = 0;
if ($xeTable) {
return $xeTable.loadColumn(columns);
}
return nextTick();
},
reloadColumn(columns) {
$xeGantt.clearAll();
return $xeGantt.loadColumn(columns);
}
});
/**
* 渲染表单
*/
const renderForm = () => {
const { formConfig, proxyConfig } = props;
const { formData } = reactData;
const proxyOpts = computeProxyOpts.value;
const formOpts = computeFormOpts.value;
if ((formConfig && isEnableConf(formOpts)) || slots.form) {
let slotVNs = [];
if (slots.form) {
slotVNs = slots.form({ $grid: null, $gantt: $xeGantt });
}
else {
if (formOpts.items) {
const formSlots = {};
if (!formOpts.inited) {
formOpts.inited = true;
const beforeItem = proxyOpts.beforeItem;
if (proxyOpts && beforeItem) {
formOpts.items.forEach((item) => {
beforeItem({ $grid: null, $gantt: $xeGantt, item });
});
}
}
// 处理插槽
formOpts.items.forEach((item) => {
XEUtils.each(item.slots, (func) => {
if (func && !XEUtils.isFunction(func)) {
if (slots[func]) {
formSlots[func] = slots[func];
}
}
});
});
if (VxeUIFormComponent) {
slotVNs.push(h(VxeUIFormComponent, Object.assign(Object.assign({ ref: refForm }, Object.assign({}, formOpts, {
data: proxyConfig && isEnableConf(proxyOpts) && proxyOpts.form ? formData : formOpts.data
})), { onSubmit: submitFormEvent, onReset: resetFormEvent, onSubmitInvalid: submitInvalidEvent, onCollapse: collapseEvent }), formSlots));
}
}
}
return h('div', {
ref: refFormWrapper,
key: 'form',
class: 'vxe-gantt--form-wrapper'
}, slotVNs);
}
return renderEmptyElement($xeGantt);
};
/**
* 渲染工具栏
*/
const renderToolbar = () => {
const { toolbarConfig } = props;
const toolbarOpts = computeToolbarOpts.value;
const toolbarSlot = slots.toolbar;
if ((toolbarConfig && isEnableConf(toolbarOpts)) || toolbarSlot) {
let slotVNs = [];
if (slots.toolbar) {
slotVNs = slots.toolbar({ $grid: null, $gantt: $xeGantt });
}
else {
const toolbarOptSlots = toolbarOpts.slots;
const toolbarSlots = {};
if (toolbarOptSlots) {
const buttonsSlot = getFuncSlot(toolbarOptSlots, 'buttons');
const buttonPrefixSlot = getFuncSlot(toolbarOptSlots, 'buttonPrefix');
const buttonSuffixSlot = getFuncSlot(toolbarOptSlots, 'buttonSuffix');
const toolsSlot = getFuncSlot(toolbarOptSlots, 'tools');
const toolPrefixSlot = getFuncSlot(toolbarOptSlots, 'toolPrefix');
const toolSuffixSlot = getFuncSlot(toolbarOptSlots, 'toolSuffix');
if (buttonsSlot) {
toolbarSlots.buttons = buttonsSlot;
}
if (buttonPrefixSlot) {
toolbarSlots.buttonPrefix = buttonPrefixSlot;
}
if (buttonSuffixSlot) {
toolbarSlots.buttonSuffix = buttonSuffixSlot;
}
if (toolsSlot) {
toolbarSlots.tools = toolsSlot;
}
if (toolPrefixSlot) {
toolbarSlots.toolPrefix = toolPrefixSlot;
}
if (toolSuffixSlot) {
toolbarSlots.toolSuffix = toolSuffixSlot;
}
}
slotVNs.push(h(VxeToolbarComponent, Object.assign(Object.assign({ ref: refToolbar }, toolbarOpts), { slots: undefined }), toolbarSlots));
}
return h('div', {
ref: refToolbarWrapper,
key: 'toolbar',
class: 'vxe-gantt--toolbar-wrapper'
}, slotVNs);
}
return renderEmptyElement($xeGantt);
};
/**
* 渲染表格顶部区域
*/
const renderTop = () => {
const topSlot = slots.top;
if (topSlot) {
return h('div', {
ref: refTopWrapper,
key: 'top',
class: 'vxe-gantt--top-wrapper'
}, topSlot({ $grid: null, $gantt: $xeGantt }));
}
return renderEmptyElement($xeGantt);
};
const renderTableLeft = () => {
const leftSlot = slots.left;
if (leftSlot) {
return h('div', {
class: 'vxe-gantt--left-wrapper'
}, leftSlot({ $grid: null, $gantt: $xeGantt }));
}
return renderEmptyElement($xeGantt);
};
const renderTableRight = () => {
const rightSlot = slots.right;
if (rightSlot) {
return h('div', {
class: 'vxe-gantt--right-wrapper'
}, rightSlot({ $grid: null, $gantt: $xeGantt }));
}
return renderEmptyElement($xeGantt);
};
/**
* 渲染表格
*/
const renderTable = () => {
const { proxyConfig } = props;
const tableProps = computeTableProps.value;
const proxyOpts = computeProxyOpts.value;
const tableOns = Object.assign({}, tableCompEvents);
const emptySlot = slots.empty;
const loadingSlot = slots.loading;
const rowDragIconSlot = slots.rowDragIcon || slots['row-drag-icon'];
const columnDragIconSlot = slots.columnDragIcon || slots['column-drag-icon'];
const headerTooltipSlot = slots.headerTooltip || slots['header-tooltip'];
const tooltipSlot = slots.tooltip;
const footerTooltipSlot = slots.footerTooltip || slots['footer-tooltip'];
if (proxyConfig && isEnableConf(proxyOpts)) {
if (proxyOpts.sort) {
tableOns.onSortChange = sortChangeEvent;
tableOns.onClearAllSort = clearAllSortEvent;
}
if (proxyOpts.filter) {
tableOns.onFilterChange = filterChangeEvent;
tableOns.onClearAllFilter = clearAllFilterEvent;
}
}
const slotObj = {};
if (emptySlot) {
slotObj.empty = emptySlot;
}
if (loadingSlot) {
slotObj.loading = loadingSlot;
}
if (rowDragIconSlot) {
slotObj.rowDragIcon = rowDragIconSlot;
}
if (columnDragIconSlot) {
slotObj.columnDragIcon = columnDragIconSlot;
}
if (headerTooltipSlot) {
slotObj.headerTooltip = headerTooltipSlot;
}
if (tooltipSlot) {
slotObj.tooltip = tooltipSlot;
}
if (footerTooltipSlot) {
slotObj.footerTooltip = footerTooltipSlot;
}
return h('div', {
ref: refTableWrapper,
class: 'vxe-gantt--table-wrapper'
}, [
h(VxeTableComponent, Object.assign(Object.assign({ ref: refTable }, tableProps), tableOns), slotObj)
]);
};
/**
* 渲染表格底部区域
*/
const renderBottom = () => {
if (slots.bottom) {
return h('div', {
ref: refBottomWrapper,
key: 'bottom',
class: 'vxe-gantt--bottom-wrapper'
}, slots.bottom({ $grid: null, $gantt: $xeGantt }));
}
return renderEmptyElement($xeGantt);
};
/**
* 渲染分页
*/
const renderPager = () => {
const { proxyConfig, pagerConfig } = props;
const proxyOpts = computeProxyOpts.value;
const pagerOpts = computePagerOpts.value;
const pagerSlot = slots.pager;
if ((pagerConfig && isEnableConf(pagerOpts)) || slots.pager) {
return h('div', {
ref: refPagerWrapper,
key: 'pager',
class: 'vxe-gantt--pager-wrapper'
}, pagerSlot
? pagerSlot({ $grid: null, $gantt: $xeGantt })
: [
VxeUIPagerComponent
? h(VxeUIPagerComponent, Object.assign(Object.assign(Object.assign({ ref: refPager }, pagerOpts), (proxyConfig && isEnableConf(proxyOpts) ? reactData.tablePage : {})), { onPageChange: pageChangeEvent }), getConfigSlot(pagerOpts.slots))
: renderEmptyElement($xeGantt)
]);
}
return renderEmptyElement($xeGantt);
};
/**
* 渲染任务视图
*/
const renderTaskView = () => {
return h('div', {
ref: refGanttWrapper,
class: 'vxe-gantt--view-wrapper'
}, [
h(GanttViewComponent, {
ref: refGanttView
})
]);
};
const renderSplitBar = () => {
const { showLeftView, showRightView } = reactData;
const taskSplitOpts = computeTaskSplitOpts.value;
const { enabled, resize, showCollapseTableButton, showCollapseTaskButton } = taskSplitOpts;
if (!enabled) {
return renderEmptyElement($xeGantt);
}
const isResize = resize && showLeftView && showRightView;
const ons = {};
if (isResize) {
ons.onMousedown = dragSplitEvent;
}
return h('div', {
class: ['vxe-gantt--view-split-bar', {
'is--resize': isResize
}]
}, [
h('div', Object.assign({ class: 'vxe-gantt--view-split-bar-handle' }, ons)),
showCollapseTableButton || showCollapseTaskButton
? h('div', {
class: 'vxe-gantt--view-split-bar-btn-wrapper'
}, [
showCollapseTableButton && showRightView
? h('div', {
class: ['vxe-gantt--view-split-bar-action-btn', showLeftView ? 'is--prev' : 'is--next'],
onClick: handleSplitLeftViewEvent
}, [
h('i', {
class: showLeftView ? getIcon().GANTT_VIEW_LEFT_OPEN : getIcon().GANTT_VIEW_LEFT_CLOSE
})
])
: renderEmptyElement($xeGantt),
showCollapseTaskButton && showLeftView
? h('div', {
class: ['vxe-gantt--view-split-bar-action-btn', showRightView ? 'is--next' : 'is--prev'],
onClick: handleSplitRightViewEvent
}, [
h('i', {
class: showRightView ? getIcon().GANTT_VIEW_RIGHT_OPEN : getIcon().GANTT_VIEW_RIGHT_CLOSE
})
])
: renderEmptyElement($xeGantt)
])
: renderEmptyElement($xeGantt)
]);
};
const renderChildLayout = (layoutKeys) => {
const { showLeftView, showRightView } = reactData;
const taskSplitOpts = computeTaskSplitOpts.value;
const scrollbarXToTop = computeScrollbarXToTop.value;
const scrollbarYToLeft = computeScrollbarYToLeft.value;
const { autoHideCollapseButton } = taskSplitOpts;
const childVNs = [];
layoutKeys.forEach(key => {
switch (key) {
case 'Form':
childVNs.push(renderForm());
break;
case 'Toolbar':
childVNs.push(renderToolbar());
break;
case 'Top':
childVNs.push(renderTop());
break;
case 'Gantt':
childVNs.push(h('div', {
ref: refGanttContainerElem,
key: 'tv',
class: ['vxe-gantt--gantt-container', `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`, `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`, {
'show--left': showLeftView,
'hide--left': !showLeftView,
'show--right': showRightView,
'hide--right': !showRightView,
'is--ah-split-btn': autoHideCollapseButton
}]
}, [
renderTableLeft(),
renderTable(),
renderSplitBar(),
renderTaskView(),
renderTableRight(),
h('div', {
ref: refClassifyWrapperElem
}),
h('div', {
ref: refResizableSplitTip,
class: 'vxe-gantt--resizable-split-tip'
}, [
h('div', {
class: 'vxe-gantt--resizable-split-tip-number'
}, [
h('div', {
class: 'vxe-gantt--resizable-split-number-left'
}),
h('div', {
class: 'vxe-gantt--resizable-split-number-right'
})
])
]),
h('div', {
class: 'vxe-gantt--border-line'
})
]));
break;
case 'Bottom':
childVNs.push(renderBottom());
break;
case 'Pager':
childVNs.push(renderPager());
break;
default:
errLog('vxe.error.notProp', [`layouts -> ${key}`]);
break;
}
});
return childVNs;
};
const renderLayout = () => {
const { barTipStore } = reactData;
const currLayoutConf = computeCurrLayoutConf.value;
const { headKeys, bodyKeys, footKeys } = currLayoutConf;
const taskBarTooltipOpts = computeTaskBarTooltipOpts.value;
const asideLeftSlot = slots.asideLeft || slots['aside-left'];
const asideRightSlot = slots.asideRight || slots['aside-right'];
const taskBarTooltipSlot = slots.taskBarTooltip || slots['task-bar-tooltip'];
return [
h('div', {
class: 'vxe-gantt--layout-header-wrapper'
}, renderChildLayout(headKeys)),
h('div', {
class: 'vxe-gantt--layout-body-wrapper'
}, [
asideLeftSlot
? h('div', {
class: 'vxe-gantt--layout-aside-left-wrapper'
}, asideLeftSlot({}))
: renderEmptyElement($xeGantt),
h('div', {
class: 'vxe-gantt--layout-body-content-wrapper'
}, renderChildLayout(bodyKeys)),
asideRightSlot
? h('div', {
class: 'vxe-gantt--layout-aside-right-wrapper'
}, asideRightSlot({}))
: renderEmptyElement($xeGantt)
]),
h('div', {
class: 'vxe-gantt--layout-footer-wrapper'
}, renderChildLayout(footKeys)),
h('div', {
ref: refPopupContainerElem
}),
h('div', {}, [
/**
* 任务条提示
*/
h(VxeUITooltipComponent, {
key: 'gtp',
ref: refTooltip,
theme: taskBarTooltipOpts.theme,
enterable: taskBarTooltipOpts.enterable,
enterDelay: taskBarTooltipOpts.enterDelay,
leaveDelay: taskBarTooltipOpts.leaveDelay,
useHtml: XEUtils.isBoolean(taskBarTooltipOpts.useHtml) ? taskBarTooltipOpts.useHtml : taskBarTooltipOpts.useHTML,
width: taskBarTooltipOpts.width,
height: taskBarTooltipOpts.height,
minWidth: taskBarTooltipOpts.minWidth,
minHeight: taskBarTooltipOpts.minHeight,
maxWidth: taskBarTooltipOpts.maxWidth,
maxHeight: taskBarTooltipOpts.maxHeight,
isArrow: false
}, taskBarTooltipSlot
? {
content: () => {
const { row, content: tooltipContent } = barTipStore;
if (row) {
return h('div', {}, taskBarTooltipSlot(Object.assign({ tooltipContent, $gantt: $xeGantt }, barTipStore.params)));
}
return renderEmptyElement($xeGantt);
}
}
: {})
])
];
};
const renderVN = () => {
const { showLeftView, showRightView, overflowY, overflowX, showSplitAnimat } = reactData;
const vSize = computeSize.value;
const wrapperStyle = computeWrapperStyle.value;
const isLoading = computeIsLoading.value;
const taskSplitOpts = computeTaskSplitOpts.value;
const tableBorder = computeTableBorder.value;
const scrollbarXToTop = computeScrollbarXToTop.value;
const scrollbarYToLeft = computeScrollbarYToLeft.value;
return h('div', {
ref: refElem,
class: ['vxe-gantt', `border--${tableBorder}`, `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`, `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`, {
[`size--${vSize}`]: vSize,
'is--round': props.round,
'show--animat': taskSplitOpts.animation,
'is--maximize': reactData.isZMax,
'is--loading': isLoading,
'is--animat': showSplitAnimat,
'show--left': showLeftView,
'hide--left': !showLeftView,
'show--right': showRightView,
'hide--right': !showRightView,
'is--scroll-y': overflowY,
'is--scroll-x': overflowX
}],
style: wrapperStyle
}, renderLayout());
};
const columnFlag = ref(0);
watch(() => props.columns ? props.columns.length : -1, () => {
columnFlag.value++;
});
watch(() => props.columns, () => {
columnFlag.value++;
});
watch(columnFlag, () => {
nextTick(() => $xeGantt.loadColumn(props.columns || []));
});
watch(() => props.toolbarConfig, () => {
initToolbar();
});
watch(computeCustomCurrentPageFlag, () => {
initPages('currentPage');
});
watch(computeCustomPageSizeFlag, () => {
initPages('pageSize');
});
watch(computeCustomTotalFlag, () => {
initPages('total');
});
watch(() => props.proxyConfig, () => {
initProxy();
});
const reViewFlag = ref(0);
watch(computeTaskViewScales, () => {
handleTaskScaleConfig();
reViewFlag.value++;
});
watch(computeCriticalPathVisible, () => {
reViewFlag.value++;
});
watch(reViewFlag, () => {
$xeGantt.refreshTaskView();
});
watch(computeTaskLinkStyle, () => {
if ($xeGantt.handleUpTaskLinkData) {
$xeGantt.handleUpTaskLinkData();
}
});
hooks.forEach((options) => {
const { setupGantt } = options;
if (setupGantt) {
const hookRest = setupGantt($xeGantt);
if (hookRest && XEUtils.isObject(hookRest)) {
Object.assign($xeGantt, hookRest);
}
}
});
if ($xeGantt.handleTaskLoadLinks) {
if (props.links) {
$xeGantt.handleTaskLoadLinks(props.links);
}
}
handleTaskScaleConfig();
initPages();
onMounted(() => {
const taskBarSubviewOpts = computeTaskBarSubviewOpts.value;
const { barStyle } = taskBarSubviewOpts;
if (barStyle) {
if (barStyle.top) {
warnLog('vxe.error.delProp', ['task-bar-subview-config.barStyle.top', 'task-bar-subview-config.barStyle.style.top']);
}
if (barStyle.backgroundColor) {
warnLog('vxe.error.delProp', ['task-bar-subview-config.barStyle.backgroundColor', 'task-bar-subview-config.barStyle.style.backgroundColor']);
}
}
if (!$xeGantt.handleUpTaskLinkData) {
if (props.links) {
warnLog('vxe.error.notProp', ['links']);
}
if (props.taskLinkConfig) {
warnLog('vxe.error.notProp', ['task-link-config']);
}
}
nextTick(() => {
const { columns } = props;
const proxyOpts = computeProxyOpts.value;
if (props.formConfig) {
if (!VxeUIFormComponent) {
errLog('vxe.error.reqComp', ['vxe-form']);
}
}
if (props.pagerConfig) {
if (!VxeUIPagerComponent) {
errLog('vxe.error.reqComp', ['vxe-pager']);
}
}
if (props.treeConfig && props.links) {
const $xeTable = refTable.value;
if ($xeTable) {
const { computeTreeOpts } = $xeTable.getComputeMaps();
const treeOpts = computeTreeOpts.value;
if (!treeOpts.transform) {
errLog('vxe.error.notSupportProp', ['links', 'tree-config.transform=false', 'tree-config.transform=true']);
}
}
}
// const { data, columns, proxyConfig } = props
// const formOpts = computeFormOpts.value
// if (isEnableConf(proxyConfig) && (data || (proxyOpts.form && formOpts.data))) {
// errLog('vxe.error.errConflicts', ['grid.data', 'grid.proxy-config'])
// }
if (proxyOpts.props) {
warnLog('vxe.error.delProp', ['proxy-config.props', 'proxy-config.response']);
}
if (props.expandConfig) {
warnLog('vxe.error.notProp', ['expand-config']);
}
if (columns && columns.length) {
$xeGantt.loadColumn(columns);
}
initToolbar();
initProxy();
});
initGanttView();
globalEvents.on($xeGantt, 'keydown', handleGlobalKeydownEvent);
});
onBeforeUnmount(() => {
XEUtils.assign(reactData, createReactData());
XEUtils.assign(internalData, createInternalData());
});
onUnmounted(() => {
globalEvents.off($xeGantt, 'keydown');
});
$xeGantt.renderVN = renderVN;
provide('$xeGrid', null);
provide('$xeGantt', $xeGantt);
return $xeGantt;
},
render() {
return this.renderVN();
}
});
const VxeGantt = Object.assign({}, VxeGanttComponent, {
install(app) {
checkDependVersion();
app.component(VxeGanttComponent.name, VxeGanttComponent);
}
});
if (VxeUI.dynamicApp) {
VxeUI.dynamicApp.use(VxeGantt);
}
VxeUI.component(VxeGanttComponent);
const Gantt = VxeGantt;
const { setConfig } = VxeUI;
const components = [
VxeGantt
];
function install(app, options) {
setConfig(options);
components.forEach(component => app.use(component));
}
var VxeUIGanttExport = /*#__PURE__*/Object.freeze({
__proto__: null,
Gantt: Gantt,
VxeGantt: VxeGantt,
get VxeGanttDependencyType () { return VxeGanttDependencyType; },
get VxeGanttTaskType () { return VxeGanttTaskType; },
VxeUI: VxeUI,
install: install
});
export { Gantt, VxeGantt, VxeGanttDependencyType, VxeGanttTaskType, VxeUIGanttExport as default, install };