vxe-gantt
Version:
A vue based gantt component
515 lines (514 loc) • 20.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _comp = require("../../ui/src/comp");
var _core = require("@vxe-ui/core");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _util = require("./util");
var _utils = require("../../ui/src/utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
getIcon,
renderEmptyElement
} = _core.VxeUI;
const sourceType = 'gantt';
const viewType = 'chart';
var _default = exports.default = (0, _comp.defineVxeComponent)({
name: 'VxeGanttViewChart',
setup() {
const $xeGantt = (0, _vue.inject)('$xeGantt', {});
const $xeGanttView = (0, _vue.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 = (0, _vue.ref)();
const refTaskWrapperElem = (0, _vue.ref)();
const refChartBeforeWrapperElem = (0, _vue.ref)();
const refChartAfterWrapperElem = (0, _vue.ref)();
const refNowLineElem = (0, _vue.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
} = ganttReactData;
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,
row,
scaleType: scaleUnit
};
const {
showProgress,
showContent,
contentMethod,
barStyle,
moveable,
showTooltip
} = taskBarOpts;
const isBarRowStyle = _xeUtils.default.isFunction(barStyle);
const barStyObj = (barStyle ? isBarRowStyle ? barStyle(barParams) || undefined : barStyle : {}) || {};
const {
round
} = barStyObj;
const rowRest = fullAllDataRowIdData[rowid] || {};
const cellHeight = resizeHeightFlag ? (0, _util.getCellRestHeight)(rowRest, cellOpts, rowOpts, defaultRowHeight) : 0;
let title = (0, _utils.getStringValue)(_xeUtils.default.get(row, titleField));
const progressValue = showProgress ? Math.min(100, Math.max(0, _xeUtils.default.toNumber(_xeUtils.default.get(row, progressField)))) : 0;
const renderTaskType = (0, _util.getTaskType)(_xeUtils.default.get(row, typeField));
const vbStyle = {};
const vpStyle = {
width: `${progressValue || 0}%`
};
if (isBarRowStyle) {
const {
bgColor,
completedBgColor
} = barStyObj;
if (bgColor) {
vbStyle.backgroundColor = bgColor;
}
if (completedBgColor) {
vpStyle.backgroundColor = completedBgColor;
}
}
const ctParams = {
$gantt: $xeGantt,
source: sourceType,
type: viewType,
scaleType: scaleUnit,
row,
$rowIndex,
rowIndex,
_rowIndex
};
let cbVNs = [];
if ($xeGantt.renderGanttTaskBarContent) {
cbVNs = $xeGantt.renderGanttTaskBarContent(ctParams, {
$gantt: $xeGantt,
$table: $xeTable,
rowid
});
} else {
const isMilestone = !!((0, _utils.hasEnableConf)(taskBarMilestoneConfig, taskBarMilestoneOpts) && (0, _util.hasMilestoneTask)(renderTaskType));
const isSubview = !!((0, _utils.hasEnableConf)(taskBarSubviewConfig, taskBarSubviewOpts) && (0, _util.hasSubviewTask)(renderTaskType));
if (contentMethod) {
title = (0, _utils.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((0, _vue.h)('div', {
key: 'vcso',
class: 'vxe-gantt-view--chart-subview-wrapper is--overview'
}, [(0, _vue.h)('div', {
key: rowid,
rowid: rowid,
class: ['vxe-gantt-view--chart-subview-row', {
'is--progress': showProgress,
'is--round': round,
'is--move': moveable
}]
}, [(0, _vue.h)('div', {
rowid: rowid,
class: [taskBarOverviewSlot ? 'vxe-gantt-view--chart-subview-custom-bar' : 'vxe-gantt-view--chart-subview-bar', `is--${renderTaskType}`]
}, [taskBarOverviewSlot ? (0, _vue.h)('div', {
key: 'cbc',
class: 'vxe-gantt-view--chart-subview-custom-bar-content-wrapper'
}, $xeGantt.callSlot(taskBarOverviewSlot, barParams)) : (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-subview-bar-content-wrapper'
}, [showContent ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-content'
}, title) : renderEmptyElement($xeGantt)])])])]));
}
} else {
const cbcVNs = [];
_xeUtils.default.eachTree(rowChildren, childRow => {
const childBarParams = {
$gantt: $xeGantt,
row: childRow,
scaleType: scaleUnit
};
const childBarStyObj = (barStyle ? isBarRowStyle ? barStyle(childBarParams) : barStyle : {}) || {};
const {
round
} = childBarStyObj;
const childRowid = $xeTable.getRowid(childRow);
let childTitle = (0, _utils.getStringValue)(_xeUtils.default.get(childRow, titleField));
const childProgressValue = showProgress ? Math.min(100, Math.max(0, _xeUtils.default.toNumber(_xeUtils.default.get(childRow, progressField)))) : 0;
const childRenderTaskType = (0, _util.getTaskType)(_xeUtils.default.get(childRow, typeField));
const isChildSubview = !!((0, _utils.hasEnableConf)(taskBarSubviewConfig, taskBarSubviewOpts) && (0, _util.hasSubviewTask)(childRenderTaskType));
if (isChildSubview) {
return;
}
const childVbStyle = {};
const childVpStyle = {
width: `${childProgressValue || 0}%`
};
if (isBarRowStyle) {
const {
bgColor,
completedBgColor
} = childBarStyObj;
if (bgColor) {
childVbStyle.backgroundColor = bgColor;
}
if (completedBgColor) {
childVpStyle.backgroundColor = completedBgColor;
}
}
const childCtParams = _xeUtils.default.assign({}, ctParams, {
row: childRow,
rowIndex: $xeTable.getRowIndex(childRow),
$rowIndex: $xeTable.getVMRowIndex(childRow),
_rowIndex: $xeTable.getVTRowIndex(childRow)
});
if (contentMethod) {
childTitle = (0, _utils.getStringValue)(contentMethod({
row: childRow,
title: childTitle,
scaleType: scaleUnit
}));
}
cbcVNs.push((0, _vue.h)('div', {
key: childRowid,
rowid: childRowid,
class: ['vxe-gantt-view--chart-subview-row', `is--${childRenderTaskType}`, {
'is--progress': showProgress,
'is--round': round,
'is--move': moveable,
'row--pending': !!pendingRowFlag && !!pendingRowMaps[childRowid]
}]
}, [(0, _vue.h)('div', {
rowid: childRowid,
class: [taskBarSlot ? 'vxe-gantt-view--chart-subview-custom-bar' : 'vxe-gantt-view--chart-subview-bar', `is--${childRenderTaskType}`],
style: subBarStyle ? _xeUtils.default.isFunction(subBarStyle) ? subBarStyle(childCtParams) : subBarStyle : undefined,
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 ? (0, _vue.h)('div', Object.assign({
key: 'cbc',
class: 'vxe-gantt-view--chart-subview-custom-bar-content-wrapper'
}, ctOns), $xeGantt.callSlot(taskBarSlot, childCtParams)) : (0, _vue.h)('div', Object.assign({
class: 'vxe-gantt-view--chart-subview-bar-content-wrapper'
}, ctOns), [showProgress ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-progress',
style: childVpStyle
}) : renderEmptyElement($xeGantt), showContent ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-content'
}, childTitle) : renderEmptyElement($xeGantt)])])]));
}, {
children: childrenField
});
cbVNs.push((0, _vue.h)('div', {
key: 'vcsc',
class: 'vxe-gantt-view--chart-subview-wrapper is--inline'
}, cbcVNs));
}
} else {
if (taskBarSlot) {
cbVNs.push((0, _vue.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((0, _vue.h)('div', Object.assign({
key: 'vcm',
class: 'vxe-gantt-view--chart-milestone-wrapper'
}, ctOns), [(0, _vue.h)('div', {
class: ['vxe-gantt-view--chart-milestone-icon', iconStatus ? `theme--${_xeUtils.default.isFunction(iconStatus) ? iconStatus(tbmParams) : iconStatus}` : ''],
style: iconStyle ? Object.assign({}, _xeUtils.default.isFunction(iconStyle) ? iconStyle(tbmParams) : iconStyle) : undefined
}, [(0, _vue.h)('i', {
class: (icon ? _xeUtils.default.isFunction(icon) ? icon(tbmParams) : icon : '') || getIcon().GANTT_VIEW_TASK_MILESTONE
})]), showContent ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-milestone-content'
}, title) : renderEmptyElement($xeGantt)]));
} else {
cbVNs.push((0, _vue.h)('div', Object.assign({
key: 'vbc',
class: 'vxe-gantt-view--chart-bar-content-wrapper'
}, ctOns), [showProgress ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-progress',
style: vpStyle
}) : renderEmptyElement($xeGantt), showContent ? (0, _vue.h)('div', {
class: 'vxe-gantt-view--chart-content'
}, title) : renderEmptyElement($xeGantt)]));
}
}
}
return (0, _vue.h)('div', {
key: rowid,
rowid,
class: ['vxe-gantt-view--chart-row', `is--${renderTaskType}`, {
'is--progress': showProgress,
'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid],
'is--round': round,
'is--move': moveable
}],
style: {
height: `${cellHeight}px`
},
onDragstart(evnt) {
if (ganttInternalData.dragBarRow) {
evnt.preventDefault();
}
},
onContextmenu(evnt) {
$xeGantt.handleTaskBarContextmenuEvent(evnt, ctParams);
}
}, [(0, _vue.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 (0, _vue.h)('div', {
ref: refElem,
class: ['vxe-gantt-view--chart-wrapper', {
'is--cl-drag': dragLinkFromStore.rowid
}]
}, [nowLineLeft > 0 ? (0, _vue.h)('div', {
ref: refNowLineElem,
class: 'vxe-gantt-view--chart-now-line',
style: {
left: nowLineLeft + 'px'
}
}, taskNowLineSlot ? taskNowLineSlot({}) : []) : renderEmptyElement($xeGantt), $xeGantt.renderGanttTaskChartBefores ? (0, _vue.h)('div', {
ref: refChartBeforeWrapperElem,
class: ['vxe-gantt-view--chart-before-wrapper', {
'link--current': isCurrent,
'link--hover': isHover
}]
}, $xeTable && (0, _utils.isEnableConf)(taskLinkOpts) ? $xeGantt.renderGanttTaskChartBefores() : []) : renderEmptyElement($xeGantt), (0, _vue.h)('div', {
ref: refTaskWrapperElem,
class: ['vxe-gantt-view--chart-task-wrapper', {
'link--current': isCurrent,
'link--create': linkCreatable
}]
}, $xeTable ? renderTaskRows($xeTable, tableData) : []), $xeGantt.renderGanttTaskChartAfters ? (0, _vue.h)('div', {
ref: refChartAfterWrapperElem,
class: 'vxe-gantt-view--chart-after-wrapper'
}, $xeTable && (0, _utils.isEnableConf)(taskLinkOpts) ? $xeGantt.renderGanttTaskChartAfters() : []) : renderEmptyElement($xeGantt)]);
};
(0, _vue.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;
});
(0, _vue.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;
}
});