UNPKG

gantt-task-react-powern

Version:

Interactive Gantt Chart for React with TypeScript.

1,466 lines (1,291 loc) 111 kB
import React, { useMemo, useRef, useState, useEffect } from 'react'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var ViewMode; (function (ViewMode) { ViewMode["Hour"] = "Hour"; ViewMode["QuarterDay"] = "Quarter Day"; ViewMode["HalfDay"] = "Half Day"; ViewMode["Day"] = "Day"; ViewMode["Week"] = "Week"; ViewMode["Month"] = "Month"; ViewMode["Quarter"] = "Quarter"; ViewMode["Year"] = "Year"; })(ViewMode || (ViewMode = {})); var intlDTCache = {}; var getCachedDateTimeFormat = function getCachedDateTimeFormat(locString, opts) { if (opts === void 0) { opts = {}; } var key = JSON.stringify([locString, opts]); var dtf = intlDTCache[key]; if (!dtf) { dtf = new Intl.DateTimeFormat(locString, opts); intlDTCache[key] = dtf; } return dtf; }; var addToDate = function addToDate(date, quantity, scale) { var newDate = new Date(date.getFullYear() + (scale === "year" ? quantity : 0), date.getMonth() + (scale === "month" ? quantity : 0), date.getDate() + (scale === "day" ? quantity : 0), date.getHours() + (scale === "hour" ? quantity : 0), date.getMinutes() + (scale === "minute" ? quantity : 0), date.getSeconds() + (scale === "second" ? quantity : 0), date.getMilliseconds() + (scale === "millisecond" ? quantity : 0)); return newDate; }; var startOfDate = function startOfDate(date, scale) { var scores = ["millisecond", "second", "minute", "hour", "day", "month", "quarter", "year"]; var shouldReset = function shouldReset(_scale) { var maxScore = scores.indexOf(scale); return scores.indexOf(_scale) <= maxScore; }; var newDate = new Date(date.getFullYear(), shouldReset("year") ? 0 : date.getMonth(), shouldReset("month") ? 1 : date.getDate(), shouldReset("day") ? 0 : date.getHours(), shouldReset("hour") ? 0 : date.getMinutes(), shouldReset("minute") ? 0 : date.getSeconds(), shouldReset("second") ? 0 : date.getMilliseconds()); return newDate; }; var ganttDateRange = function ganttDateRange(tasks, viewMode, preStepsCount) { var _tasks$, _tasks$2, _tasks$3, _tasks$4; var newStartDate = ((_tasks$ = tasks[0]) === null || _tasks$ === void 0 ? void 0 : _tasks$.start.getTime()) !== 0 ? ((_tasks$2 = tasks[0]) === null || _tasks$2 === void 0 ? void 0 : _tasks$2.start) || new Date() : new Date(); var newEndDate = ((_tasks$3 = tasks[0]) === null || _tasks$3 === void 0 ? void 0 : _tasks$3.end.getTime()) !== 0 ? ((_tasks$4 = tasks[0]) === null || _tasks$4 === void 0 ? void 0 : _tasks$4.end) || new Date() : new Date(); for (var _iterator = _createForOfIteratorHelperLoose(tasks), _step; !(_step = _iterator()).done;) { var task = _step.value; if (task.start && task.start.getTime() !== 0 && task.start < newStartDate) { newStartDate = task.start; } if (task.end && task.end.getTime() !== 0 && task.end > newEndDate) { newEndDate = task.end; } if (task.actualStart && task.actualStart.getTime() !== 0 && task.actualStart < newStartDate) { newStartDate = task.actualStart; } if (task.actualEnd && task.actualEnd.getTime() !== 0 && task.actualEnd > newEndDate) { newEndDate = task.actualEnd; } } switch (viewMode) { case ViewMode.Year: newStartDate = addToDate(newStartDate, -1, "year"); newStartDate = startOfDate(newStartDate, "year"); newEndDate = addToDate(newEndDate, 1, "year"); newEndDate = startOfDate(newEndDate, "year"); break; case ViewMode.Quarter: newStartDate = addToDate(newStartDate, -1 * preStepsCount, "year"); newStartDate = startOfDate(newStartDate, "year"); newEndDate = addToDate(newEndDate, 1, "year"); newEndDate = startOfDate(newEndDate, "quarter"); break; case ViewMode.Month: newStartDate = addToDate(newStartDate, -1 * preStepsCount, "month"); newStartDate = startOfDate(newStartDate, "month"); newEndDate = addToDate(newEndDate, 1, "year"); newEndDate = startOfDate(newEndDate, "year"); break; case ViewMode.Week: newStartDate = startOfDate(newStartDate, "day"); newStartDate = addToDate(getMonday(newStartDate), -7 * preStepsCount, "day"); newEndDate = startOfDate(newEndDate, "day"); newEndDate = addToDate(newEndDate, 1.5, "month"); break; case ViewMode.Day: newStartDate = startOfDate(newStartDate, "day"); newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day"); newEndDate = startOfDate(newEndDate, "day"); newEndDate = addToDate(newEndDate, 19, "day"); break; case ViewMode.QuarterDay: newStartDate = startOfDate(newStartDate, "day"); newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day"); newEndDate = startOfDate(newEndDate, "day"); newEndDate = addToDate(newEndDate, 66, "hour"); break; case ViewMode.HalfDay: newStartDate = startOfDate(newStartDate, "day"); newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day"); newEndDate = startOfDate(newEndDate, "day"); newEndDate = addToDate(newEndDate, 108, "hour"); break; case ViewMode.Hour: newStartDate = startOfDate(newStartDate, "hour"); newStartDate = addToDate(newStartDate, -1 * preStepsCount, "hour"); newEndDate = startOfDate(newEndDate, "day"); newEndDate = addToDate(newEndDate, 1, "day"); break; } return [newStartDate, newEndDate]; }; var seedDates = function seedDates(startDate, endDate, viewMode) { var currentDate = new Date(startDate); var dates = [currentDate]; while (currentDate < endDate) { switch (viewMode) { case ViewMode.Year: currentDate = addToDate(currentDate, 1, "year"); break; case ViewMode.Quarter: currentDate = addToDate(currentDate, 3, "month"); break; case ViewMode.Month: currentDate = addToDate(currentDate, 1, "month"); break; case ViewMode.Week: currentDate = addToDate(currentDate, 7, "day"); break; case ViewMode.Day: currentDate = addToDate(currentDate, 1, "day"); break; case ViewMode.HalfDay: currentDate = addToDate(currentDate, 12, "hour"); break; case ViewMode.QuarterDay: currentDate = addToDate(currentDate, 6, "hour"); break; case ViewMode.Hour: currentDate = addToDate(currentDate, 1, "hour"); break; } dates.push(currentDate); } return dates; }; var getLocaleMonth = function getLocaleMonth(date, locale) { var bottomValue = getCachedDateTimeFormat(locale, { month: "long" }).format(date); bottomValue = bottomValue.replace(bottomValue[0], bottomValue[0].toLocaleUpperCase()); return bottomValue; }; var getLocalDayOfWeek = function getLocalDayOfWeek(date, locale, format) { var bottomValue = getCachedDateTimeFormat(locale, { weekday: format }).format(date); bottomValue = bottomValue.replace(bottomValue[0], bottomValue[0].toLocaleUpperCase()); return bottomValue; }; var getMonday = function getMonday(date) { var day = date.getDay(); var diff = date.getDate() - day + (day === 0 ? -6 : 1); return new Date(date.setDate(diff)); }; var getWeekNumberISO8601 = function getWeekNumberISO8601(date) { var tmpDate = new Date(date.valueOf()); var dayNumber = (tmpDate.getDay() + 6) % 7; tmpDate.setDate(tmpDate.getDate() - dayNumber + 3); var firstThursday = tmpDate.valueOf(); tmpDate.setMonth(0, 1); if (tmpDate.getDay() !== 4) { tmpDate.setMonth(0, 1 + (4 - tmpDate.getDay() + 7) % 7); } var weekNumber = (1 + Math.ceil((firstThursday - tmpDate.valueOf()) / 604800000)).toString(); if (weekNumber.length === 1) { return "0" + weekNumber; } else { return weekNumber; } }; var getDaysInMonth = function getDaysInMonth(month, year) { return new Date(year, month + 1, 0).getDate(); }; var styles = {"ganttTable":"_3_ygE","ganttTable_Header":"_1nBOt","ganttTable_HeaderSeparator":"_2eZzQ","ganttTable_HeaderItem":"_WuQ0f"}; var TaskListHeaderDefault = function TaskListHeaderDefault(_ref) { var headerHeight = _ref.headerHeight, fontFamily = _ref.fontFamily, fontSize = _ref.fontSize, rowWidth = _ref.rowWidth, allSelected = _ref.allSelected, onSelectAll = _ref.onSelectAll; return React.createElement("div", { className: styles.ganttTable, style: { fontFamily: fontFamily, fontSize: fontSize } }, React.createElement("div", { className: styles.ganttTable_Header, style: { height: headerHeight - 2 } }, onSelectAll && React.createElement("div", null, React.createElement("div", { className: styles.ganttTable_HeaderItem, style: { minWidth: parseInt(rowWidth) * 0.3, maxWidth: parseInt(rowWidth) * 0.3 } }, React.createElement("input", { type: "checkbox", checked: allSelected, onChange: function onChange(e) { return onSelectAll(e.target.checked); } }))), React.createElement("div", { className: styles.ganttTable_HeaderItem, style: { minWidth: parseInt(rowWidth) * 0.8, maxWidth: parseInt(rowWidth) * 0.8 } }, "WBS"), React.createElement("div", { className: styles.ganttTable_HeaderSeparator, style: { height: headerHeight * 0.5, marginTop: headerHeight * 0.2 } }), React.createElement("div", { className: styles.ganttTable_HeaderItem, style: { minWidth: parseInt(rowWidth) * 1.8, maxWidth: parseInt(rowWidth) * 1.8 } }, "Task"), React.createElement("div", { className: styles.ganttTable_HeaderSeparator, style: { height: headerHeight * 0.5, marginTop: headerHeight * 0.2 } }), React.createElement("div", { className: styles.ganttTable_HeaderItem, style: { minWidth: parseInt(rowWidth) * 0.7 }, title: "Planned Start" }, "Planned Start"), React.createElement("div", { className: styles.ganttTable_HeaderSeparator, style: { height: headerHeight * 0.5, marginTop: headerHeight * 0.25 } }), React.createElement("div", { className: styles.ganttTable_HeaderItem, style: { minWidth: parseInt(rowWidth) * 0.7 }, title: "Planned End" }, "Planned End"))); }; var styles$1 = {"taskListWrapper":"_3ZbQT","taskListTableRow":"_34SS0","taskListLookAheadRow":"_GzvG4","taskListMilestoneRow":"_3Ykml","taskListCell":"_3lLk3","taskListNameWrapper":"_nI1Xw","taskListExpander":"_2QjE6","taskListExpanderPlaceholder":"_1fnLB","taskListEmptyExpander":"_2TfEi","taskListText":"_2ZvXU"}; var localeDateStringCache = {}; var toLocaleDateStringFactory = function toLocaleDateStringFactory(locale) { return function (date, dateTimeOptions) { if (!date || date.getTime() === 0) return ""; var key = date.toString(); var lds = localeDateStringCache[key]; if (!lds) { lds = date.toLocaleDateString(locale, dateTimeOptions); localeDateStringCache[key] = lds; } return lds; }; }; var dateTimeOptions = { year: "numeric", month: "numeric", day: "numeric" }; var TaskListTableDefault = function TaskListTableDefault(_ref) { var rowHeight = _ref.rowHeight, rowWidth = _ref.rowWidth, tasks = _ref.tasks, scheduleType = _ref.scheduleType, leafTasks = _ref.leafTasks, fontFamily = _ref.fontFamily, fontSize = _ref.fontSize, locale = _ref.locale, onExpanderClick = _ref.onExpanderClick, _ref$selectedTasks = _ref.selectedTasks, selectedTasks = _ref$selectedTasks === void 0 ? [] : _ref$selectedTasks, onTaskSelect = _ref.onTaskSelect, _ref$taskLabelRendere = _ref.taskLabelRenderer, taskLabelRenderer = _ref$taskLabelRendere === void 0 ? function (t) { return " " + t.name; } : _ref$taskLabelRendere; var toLocaleDateString = useMemo(function () { return toLocaleDateStringFactory(locale); }, [locale]); var leafTaskIds = useMemo(function () { return new Set(leafTasks.map(function (t) { return t.id; })); }, [leafTasks]); return React.createElement("div", { className: styles$1.taskListWrapper, style: { fontFamily: fontFamily, fontSize: fontSize } }, tasks.map(function (t) { var expanderSymbol = ""; if (!leafTaskIds.has(t.id)) { if (t.hideChildren === false) { expanderSymbol = "▼"; } else if (t.hideChildren === true) { expanderSymbol = "►"; } } var isSelected = selectedTasks.includes(t.id); return React.createElement("div", { className: t.type === "milestone" ? styles$1.taskListMilestoneRow : scheduleType === "lookAhead" ? styles$1.taskListLookAheadRow : styles$1.taskListTableRow, style: { height: rowHeight }, key: t.id + "row" }, onTaskSelect && React.createElement("div", { className: styles$1.taskListCell, style: { minWidth: parseInt(rowWidth) * 0.3, maxWidth: parseInt(rowWidth) * 0.3 } }, React.createElement("div", { className: styles$1.taskListText, style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", paddingLeft: "0", paddingRight: "0" } }, React.createElement("input", { type: "checkbox", checked: isSelected, onChange: function onChange(e) { return onTaskSelect(t.id, e.target.checked); } }))), React.createElement("div", { className: styles$1.taskListCell, style: { minWidth: parseInt(rowWidth) * 0.8, maxWidth: parseInt(rowWidth) * 0.8 }, title: t.id }, React.createElement("div", { className: styles$1.taskListNameWrapper, style: { paddingLeft: t.depth * 4 + "px" } }, !leafTaskIds.has(t.id) ? React.createElement("div", { className: styles$1.taskListExpander, onClick: function onClick() { return onExpanderClick(t); } }, expanderSymbol) : React.createElement("div", { className: styles$1.taskListExpanderPlaceholder }), React.createElement("div", { className: styles$1.taskListText }, t.id, " ", t.actualEnd.getTime() > 0 && t.actualEnd.getTime() < Date.now() ? React.createElement("span", { title: "Task Complete", style: { color: "limegreen", fontSize: "16px" } }, "\u2714") : ""))), React.createElement("div", { className: styles$1.taskListCell, style: { minWidth: parseInt(rowWidth) * 2, maxWidth: parseInt(rowWidth) * 2 }, title: t.name }, React.createElement("div", { className: styles$1.taskListText }, taskLabelRenderer(t))), React.createElement("div", { className: styles$1.taskListCell, style: { minWidth: parseInt(rowWidth) * 0.6, maxWidth: parseInt(rowWidth) * 0.6 } }, React.createElement("div", { className: styles$1.taskListText }, "\xA0", toLocaleDateString(t.start, dateTimeOptions))), React.createElement("div", { className: styles$1.taskListCell, style: { minWidth: parseInt(rowWidth) * 0.6, maxWidth: parseInt(rowWidth) * 0.6 } }, React.createElement("div", { className: styles$1.taskListText }, "\xA0", toLocaleDateString(t.end, dateTimeOptions)))); })); }; var styles$2 = {"tooltipDefaultContainer":"_3T42e","tooltipDefaultContainerParagraph":"_29NTg","tooltipDetailsContainer":"_25P-K","tooltipDetailsContainerHidden":"_3gVAq"}; var Tooltip = function Tooltip(_ref) { var task = _ref.task, type = _ref.type, rowHeight = _ref.rowHeight, rtl = _ref.rtl, svgContainerHeight = _ref.svgContainerHeight, svgContainerWidth = _ref.svgContainerWidth, scrollX = _ref.scrollX, scrollY = _ref.scrollY, arrowIndent = _ref.arrowIndent, fontSize = _ref.fontSize, fontFamily = _ref.fontFamily, headerHeight = _ref.headerHeight, taskListWidth = _ref.taskListWidth, TooltipContent = _ref.TooltipContent; var tooltipRef = useRef(null); var _useState = useState(0), relatedY = _useState[0], setRelatedY = _useState[1]; var _useState2 = useState(0), relatedX = _useState2[0], setRelatedX = _useState2[1]; useEffect(function () { if (tooltipRef.current) { var tooltipHeight = tooltipRef.current.offsetHeight * 1.1; var tooltipWidth = tooltipRef.current.offsetWidth * 1.1; var newRelatedY = task.index * rowHeight - scrollY + headerHeight; var newRelatedX; if (rtl) { newRelatedX = task.x1 - arrowIndent * 1.5 - tooltipWidth - scrollX; if (newRelatedX < 0) { newRelatedX = task.x2 + arrowIndent * 1.5 - scrollX; } var tooltipLeftmostPoint = tooltipWidth + newRelatedX; if (tooltipLeftmostPoint > svgContainerWidth) { newRelatedX = svgContainerWidth - tooltipWidth; newRelatedY += rowHeight; } } else { newRelatedX = type == "planned" ? task.x2 + arrowIndent * 1.5 + taskListWidth - scrollX : task.actualx2 + arrowIndent * 1.5 + taskListWidth - scrollX; var _tooltipLeftmostPoint = tooltipWidth + newRelatedX; var fullChartWidth = taskListWidth + svgContainerWidth; if (_tooltipLeftmostPoint > fullChartWidth) { newRelatedX = type == "planned" ? task.x1 + taskListWidth - arrowIndent * 1.5 - scrollX - tooltipWidth : task.actualx1 + taskListWidth - arrowIndent * 1.5 - scrollX - tooltipWidth; } if (newRelatedX < taskListWidth) { newRelatedX = svgContainerWidth + taskListWidth - tooltipWidth; newRelatedY += rowHeight; } } var tooltipLowerPoint = tooltipHeight + newRelatedY - scrollY; if (tooltipLowerPoint > svgContainerHeight - scrollY) { newRelatedY = svgContainerHeight - tooltipHeight; } setRelatedY(newRelatedY); setRelatedX(newRelatedX); } }, [tooltipRef, task, arrowIndent, scrollX, scrollY, headerHeight, taskListWidth, rowHeight, svgContainerHeight, svgContainerWidth, rtl]); return React.createElement("div", { ref: tooltipRef, className: relatedX ? styles$2.tooltipDetailsContainer : styles$2.tooltipDetailsContainerHidden, style: { left: relatedX, top: relatedY } }, React.createElement(TooltipContent, { task: task, fontSize: fontSize, fontFamily: fontFamily, type: type })); }; var StandardTooltipContent = function StandardTooltipContent(_ref2) { var task = _ref2.task, fontSize = _ref2.fontSize, fontFamily = _ref2.fontFamily, type = _ref2.type; var style = { fontSize: fontSize, fontFamily: fontFamily }; if (type == "planned") return React.createElement("div", { className: styles$2.tooltipDefaultContainer, style: style }, React.createElement("b", { style: { fontSize: fontSize + 6 } }, task.name + ": Planned dates: "), React.createElement("b", null, task.start.getMonth() + 1 + "/" + task.start.getDate() + "/" + task.start.getFullYear() + " - " + (task.end.getMonth() + 1) + "/" + task.end.getDate() + "/" + task.end.getFullYear()), task.end.getTime() - task.start.getTime() !== 0 && React.createElement("p", { className: styles$2.tooltipDefaultContainerParagraph }, "Duration: " + ~~((task.end.getTime() - task.start.getTime()) / (1000 * 60 * 60 * 24)) + " day(s)"), React.createElement("p", { className: styles$2.tooltipDefaultContainerParagraph }, !!task.progress && "Progress: " + task.progress + " %"));else return React.createElement("div", { className: styles$2.tooltipDefaultContainer, style: style }, React.createElement("b", { style: { fontSize: fontSize + 6 } }, task.name + ": Actual dates: "), React.createElement("b", null, task.actualStart.getMonth() + 1 + "/" + task.actualStart.getDate() + "/" + task.actualStart.getFullYear() + " - " + (task.actualEnd.getMonth() + 1) + "/" + task.actualEnd.getDate() + "/" + task.actualEnd.getFullYear()), task.actualEnd.getTime() - task.actualStart.getTime() !== 0 && React.createElement("p", { className: styles$2.tooltipDefaultContainerParagraph }, "Duration: " + ~~((task.actualEnd.getTime() - task.actualStart.getTime()) / (1000 * 60 * 60 * 24)) + " day(s)"), React.createElement("p", { className: styles$2.tooltipDefaultContainerParagraph }, !!task.progress && "Progress: " + task.progress + " %")); }; var styles$3 = {"scroll":"_1eT-t"}; var VerticalScroll = function VerticalScroll(_ref) { var scroll = _ref.scroll, ganttHeight = _ref.ganttHeight, ganttFullHeight = _ref.ganttFullHeight, headerHeight = _ref.headerHeight, rtl = _ref.rtl, onScroll = _ref.onScroll; var scrollRef = useRef(null); useEffect(function () { if (scrollRef.current) { scrollRef.current.scrollTop = scroll; } }, [scroll]); return React.createElement("div", { style: { height: ganttHeight, marginTop: headerHeight, marginLeft: rtl ? "" : "-1rem", marginRight: "1rem" }, className: styles$3.scroll, onScroll: onScroll, ref: scrollRef }, React.createElement("div", { style: { height: ganttFullHeight, width: 1 } })); }; var TaskList = function TaskList(_ref) { var headerHeight = _ref.headerHeight, fontFamily = _ref.fontFamily, fontSize = _ref.fontSize, rowWidth = _ref.rowWidth, rowHeight = _ref.rowHeight, scrollY = _ref.scrollY, tasks = _ref.tasks, scheduleType = _ref.scheduleType, leafTasks = _ref.leafTasks, selectedTask = _ref.selectedTask, setSelectedTask = _ref.setSelectedTask, onExpanderClick = _ref.onExpanderClick, locale = _ref.locale, ganttHeight = _ref.ganttHeight, taskListRef = _ref.taskListRef, horizontalContainerClass = _ref.horizontalContainerClass, TaskListHeader = _ref.TaskListHeader, TaskListTable = _ref.TaskListTable, taskLabelRenderer = _ref.taskLabelRenderer, onMultiSelect = _ref.onMultiSelect; var horizontalContainerRef = useRef(null); var _useState = useState([]), selectedTasks = _useState[0], setSelectedTasks = _useState[1]; var prevSelectedTasksRef = useRef([]); useEffect(function () { if (horizontalContainerRef.current) { horizontalContainerRef.current.scrollTop = scrollY; } }, [scrollY]); useEffect(function () { if (onMultiSelect && JSON.stringify(prevSelectedTasksRef.current) !== JSON.stringify(selectedTasks)) { var selectedTaskObjects = tasks.filter(function (task) { return selectedTasks.includes(task.id); }); prevSelectedTasksRef.current = [].concat(selectedTasks); onMultiSelect(selectedTaskObjects); } }, [selectedTasks, tasks, onMultiSelect]); var handleTaskSelect = function handleTaskSelect(taskId, selected) { if (selected) { setSelectedTasks(function (prev) { return [].concat(prev, [taskId]); }); } else { setSelectedTasks(function (prev) { return prev.filter(function (id) { return id !== taskId; }); }); } }; var handleSelectAll = function handleSelectAll(selected) { if (selected) { setSelectedTasks(tasks.map(function (task) { return task.id; })); } else { setSelectedTasks([]); } }; var headerProps = { headerHeight: headerHeight, fontFamily: fontFamily, fontSize: fontSize, rowWidth: rowWidth, allSelected: tasks.length > 0 && selectedTasks.length === tasks.length, onSelectAll: onMultiSelect ? handleSelectAll : undefined }; var selectedTaskId = selectedTask ? selectedTask.id : ""; var tableProps = { rowHeight: rowHeight, rowWidth: rowWidth, fontFamily: fontFamily, fontSize: fontSize, tasks: tasks, leafTasks: leafTasks, scheduleType: scheduleType, locale: locale, selectedTaskId: selectedTaskId, setSelectedTask: setSelectedTask, onExpanderClick: onExpanderClick, selectedTasks: onMultiSelect ? selectedTasks : undefined, onTaskSelect: onMultiSelect ? handleTaskSelect : undefined, taskLabelRenderer: taskLabelRenderer }; return React.createElement("div", { ref: taskListRef }, React.createElement(TaskListHeader, Object.assign({}, headerProps)), React.createElement("div", { ref: horizontalContainerRef, className: horizontalContainerClass, style: ganttHeight ? { height: ganttHeight } : {} }, React.createElement(TaskListTable, Object.assign({}, tableProps)))); }; var styles$4 = {"gridRow":"_2dZTy","gridRowLookAhead":"_2RRca","gridRowLine":"_3rUKi","gridTick":"_RuwuK","darkerGridRow":"_2M-tt"}; const GridBody = _ref => { let { tasks, scheduleType, dates, rowHeight, svgWidth, columnWidth, todayColor, weekendColor, rtl } = _ref; let y = 0; const gridRows = []; const rowLines = [React.createElement("line", { key: "RowLineFirst", x: "0", y1: 0, x2: svgWidth, y2: 0, className: styles$4.gridRowLine })]; for (const task of tasks) { const isDarkerRow = task.type === "milestone"; gridRows.push(React.createElement("rect", { key: "Row" + task.id, x: "0", y: y, width: svgWidth, height: rowHeight, className: isDarkerRow ? styles$4.darkerGridRow : scheduleType === "lookAhead" ? styles$4.gridRowLookAhead : styles$4.gridRow })); rowLines.push(React.createElement("line", { key: "RowLine" + task.id, x: "0", y1: y + rowHeight, x2: svgWidth, y2: y + rowHeight, className: styles$4.gridRowLine })); y += rowHeight; } const now = new Date(); let tickX = 0; const ticks = []; let today = React.createElement("rect", null); let weekend = []; for (let i = 0; i < dates.length; i++) { const date = dates[i]; ticks.push(React.createElement("line", { key: date.getTime(), x1: tickX, y1: 0, x2: tickX, y2: y, className: styles$4.gridTick })); if (i + 1 !== dates.length && date.getTime() < now.getTime() && dates[i + 1].getTime() >= now.getTime() || i !== 0 && i + 1 === dates.length && date.getTime() < now.getTime() && addToDate(date, date.getTime() - dates[i - 1].getTime(), "millisecond").getTime() >= now.getTime()) { today = React.createElement("rect", { x: tickX, y: 0, width: columnWidth, height: y, fill: todayColor }); } if (date.getDay() === 6 || date.getDay() === 0) { weekend.push(React.createElement("rect", { x: tickX, y: 0, width: columnWidth, height: y, fill: weekendColor })); } if (rtl && i + 1 !== dates.length && date.getTime() >= now.getTime() && dates[i + 1].getTime() < now.getTime()) { today = React.createElement("rect", { x: tickX + columnWidth, y: 0, width: columnWidth, height: y, fill: todayColor }); } tickX += columnWidth; } return React.createElement("g", { className: "gridBody" }, React.createElement("g", { className: "rows" }, gridRows), React.createElement("g", { className: "rowLines" }, rowLines), React.createElement("g", { className: "ticks" }, ticks), scheduleType === "lookAhead" && React.createElement("g", { className: "weekend" }, weekend), React.createElement("g", { className: "today" }, today)); }; const Grid = props => { return React.createElement("g", { className: "grid" }, React.createElement(GridBody, Object.assign({}, props))); }; var styles$5 = {"calendarBottomText":"_9w8d5","calendarTopTick":"_1rLuZ","calendarTopText":"_2q1Kt","calendarHeader":"_35nLX","textAnchorStart":"_2Shd-","textAnchorMiddle":"_2XXW4","textAnchorEnd":"_3GdnC"}; const TopPartOfCalendar = _ref => { let { value, x1Line, y1Line, y2Line, xText, yText, textAnchor = "middle" } = _ref; const textAnchorClass = textAnchor === "start" ? styles$5.textAnchorStart : textAnchor === "middle" ? styles$5.textAnchorMiddle : styles$5.textAnchorEnd; return React.createElement("g", { className: "calendarTop" }, React.createElement("line", { x1: x1Line, y1: y1Line, x2: x1Line, y2: y2Line, className: styles$5.calendarTopTick, key: value + "line" }), React.createElement("text", { key: value + "text", y: yText, x: xText, className: `${styles$5.calendarTopText} ${textAnchorClass}` }, value)); }; const Calendar = _ref => { let { dateSetup, locale, viewMode, rtl, headerHeight, columnWidth, fontFamily, fontSize } = _ref; const getCalendarValuesForYear = () => { const topValues = []; const bottomValues = []; const topDefaultHeight = headerHeight * 0.5; for (let i = 0; i < dateSetup.dates.length; i++) { const date = dateSetup.dates[i]; const bottomValue = date.getFullYear(); bottomValues.push(React.createElement("text", { key: date.getFullYear(), y: headerHeight * 0.8, x: columnWidth * i + columnWidth * 0.5, className: styles$5.calendarBottomText }, bottomValue)); if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) { const topValue = date.getFullYear().toString(); let xText; if (rtl) { xText = (6 + i + date.getFullYear() + 1) * columnWidth; } else { xText = (6 + i - date.getFullYear()) * columnWidth; } topValues.push(React.createElement(TopPartOfCalendar, { key: topValue, value: topValue, x1Line: columnWidth * i, y1Line: 0, y2Line: headerHeight, xText: xText, yText: topDefaultHeight * 0.9 })); } } return [topValues, bottomValues]; }; const getCalendarValuesForQuarter = () => { const topValues = []; const bottomValues = []; const topDefaultHeight = headerHeight * 0.5; for (let i = 0; i < dateSetup.dates.length; i++) { const date = dateSetup.dates[i]; const quarter = Math.floor(date.getMonth() / 3) + 1; const bottomValue = `Q${quarter}`; bottomValues.push(React.createElement("text", { key: `${bottomValue}-${date.getFullYear()}`, y: headerHeight * 0.8, x: columnWidth * i + columnWidth * 0.5, className: styles$5.calendarBottomText }, bottomValue)); if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) { const topValue = date.getFullYear().toString(); let xText; if (rtl) { xText = (3 + i + quarter) * columnWidth; } else { xText = (3 + i - quarter) * columnWidth; } topValues.push(React.createElement(TopPartOfCalendar, { key: topValue, value: topValue, x1Line: columnWidth * i, y1Line: 0, y2Line: headerHeight, xText: xText, yText: topDefaultHeight * 0.9 })); } } return [topValues, bottomValues]; }; const getCalendarValuesForMonth = () => { const topValues = []; const bottomValues = []; const topDefaultHeight = headerHeight * 0.5; for (let i = 0; i < dateSetup.dates.length; i++) { const date = dateSetup.dates[i]; const bottomValue = date.toLocaleString(locale, { month: "short" }); bottomValues.push(React.createElement("text", { key: bottomValue + date.getFullYear(), y: headerHeight * 0.8, x: columnWidth * i + columnWidth * 0.5, className: `${styles$5.calendarTopText} ${styles$5.textAnchorEnd}` }, bottomValue)); if (i === 0 || date.getFullYear() !== dateSetup.dates[i - 1].getFullYear()) { const topValue = date.getFullYear().toString(); let xText; if (rtl) { xText = (6 + i + date.getMonth() + 1) * columnWidth; } else { xText = (6 + i - date.getMonth()) * columnWidth; } console.log(xText); topValues.push(React.createElement(TopPartOfCalendar, { key: topValue, value: topValue, x1Line: columnWidth * i, y1Line: 0, y2Line: topDefaultHeight, xText: xText, yText: topDefaultHeight * 0.9, textAnchor: "end" })); } } return [topValues, bottomValues]; }; const getCalendarValuesForWeek = () => { const topValues = []; const bottomValues = []; let weeksCount = 1; const topDefaultHeight = headerHeight * 0.5; const dates = dateSetup.dates; for (let i = dates.length - 1; i >= 0; i--) { const date = dates[i]; let topValue = ""; if (i === 0 || date.getMonth() !== dates[i - 1].getMonth()) { topValue = `${getLocaleMonth(date, locale)}, ${date.getFullYear()}`; } const bottomValue = `W${getWeekNumberISO8601(date)}`; bottomValues.push(React.createElement("text", { key: date.getTime(), y: headerHeight * 0.8, x: columnWidth * (i + +rtl), className: `${styles$5.calendarTopText} ${styles$5.textAnchorStart}` }, bottomValue)); if (topValue) { if (i !== dates.length - 1) { topValues.push(React.createElement(TopPartOfCalendar, { key: topValue, value: topValue, x1Line: columnWidth * i + weeksCount * columnWidth, y1Line: 0, y2Line: topDefaultHeight, xText: columnWidth * i + columnWidth * weeksCount * 0.5, yText: topDefaultHeight * 0.9, textAnchor: "start" })); } weeksCount = 0; } weeksCount++; } return [topValues, bottomValues]; }; const getCalendarValuesForDay = () => { const topValues = []; const bottomValues = []; const topDefaultHeight = headerHeight * 0.5; const dates = dateSetup.dates; for (let i = 0; i < dates.length; i++) { const date = dates[i]; const bottomValue = `${getLocalDayOfWeek(date, locale, "short")}, ${date.getDate().toString()}`; bottomValues.push(React.createElement("text", { key: date.getTime(), y: headerHeight * 0.8, x: columnWidth * i + columnWidth * 0.5, className: `${styles$5.calendarTopText} ${styles$5.textAnchorMiddle}` }, bottomValue)); if (i + 1 !== dates.length && date.getMonth() !== dates[i + 1].getMonth()) { const topValue = `${getLocaleMonth(date, locale)} ${date.getFullYear()}`; topValues.push(React.createElement(TopPartOfCalendar, { key: topValue + date.getFullYear(), value: topValue, x1Line: columnWidth * (i + 1), y1Line: 0, y2Line: topDefaultHeight, xText: columnWidth * (i + 1) - getDaysInMonth(date.getMonth(), date.getFullYear()) * columnWidth * 0.5, yText: topDefaultHeight * 0.9 })); } } return [topValues, bottomValues]; }; const getCalendarValuesForPartOfDay = () => { const topValues = []; const bottomValues = []; const ticks = viewMode === ViewMode.HalfDay ? 2 : 4; const topDefaultHeight = headerHeight * 0.5; const dates = dateSetup.dates; for (let i = 0; i < dates.length; i++) { const date = dates[i]; const bottomValue = getCachedDateTimeFormat(locale, { hour: "numeric" }).format(date); bottomValues.push(React.createElement("text", { key: date.getTime(), y: headerHeight * 0.8, x: columnWidth * (i + +rtl), className: `${styles$5.calendarTopText} ${styles$5.textAnchorMiddle}`, fontFamily: fontFamily }, bottomValue)); if (i === 0 || date.getDate() !== dates[i - 1].getDate()) { const topValue = `${getLocalDayOfWeek(date, locale, "short")}, ${date.getDate()} ${getLocaleMonth(date, locale)}`; topValues.push(React.createElement(TopPartOfCalendar, { key: topValue + date.getFullYear(), value: topValue, x1Line: columnWidth * i + ticks * columnWidth, y1Line: 0, y2Line: topDefaultHeight, xText: columnWidth * i + ticks * columnWidth * 0.5, yText: topDefaultHeight * 0.9 })); } } return [topValues, bottomValues]; }; const getCalendarValuesForHour = () => { const topValues = []; const bottomValues = []; const topDefaultHeight = headerHeight * 0.5; const dates = dateSetup.dates; for (let i = 0; i < dates.length; i++) { const date = dates[i]; const bottomValue = getCachedDateTimeFormat(locale, { hour: "numeric" }).format(date); bottomValues.push(React.createElement("text", { key: date.getTime(), y: headerHeight * 0.8, x: columnWidth * (i + +rtl), className: styles$5.calendarBottomText, fontFamily: fontFamily }, bottomValue)); if (i !== 0 && date.getDate() !== dates[i - 1].getDate()) { const displayDate = dates[i - 1]; const topValue = `${getLocalDayOfWeek(displayDate, locale, "long")}, ${displayDate.getDate()} ${getLocaleMonth(displayDate, locale)}`; const topPosition = (date.getHours() - 24) / 2; topValues.push(React.createElement(TopPartOfCalendar, { key: topValue + displayDate.getFullYear(), value: topValue, x1Line: columnWidth * i, y1Line: 0, y2Line: topDefaultHeight, xText: columnWidth * (i + topPosition), yText: topDefaultHeight * 0.9 })); } } return [topValues, bottomValues]; }; let topValues = []; let bottomValues = []; switch (dateSetup.viewMode) { case ViewMode.Year: [topValues, bottomValues] = getCalendarValuesForYear(); break; case ViewMode.Quarter: [topValues, bottomValues] = getCalendarValuesForQuarter(); break; case ViewMode.Month: [topValues, bottomValues] = getCalendarValuesForMonth(); break; case ViewMode.Week: [topValues, bottomValues] = getCalendarValuesForWeek(); break; case ViewMode.Day: [topValues, bottomValues] = getCalendarValuesForDay(); break; case ViewMode.QuarterDay: case ViewMode.HalfDay: [topValues, bottomValues] = getCalendarValuesForPartOfDay(); break; case ViewMode.Hour: [topValues, bottomValues] = getCalendarValuesForHour(); } return React.createElement("g", { className: "calendar", fontSize: fontSize, fontFamily: fontFamily, width: columnWidth * dateSetup.dates.length }, React.createElement("rect", { x: 0, y: 0, width: columnWidth * dateSetup.dates.length, height: headerHeight, className: styles$5.calendarHeader }), bottomValues, " ", topValues); }; // A type of promise-like that resolves synchronously and supports only one observer const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator"; const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator"; // Asynchronously call a function and send errors to recovery continuation function _catch(body, recover) { try { var result = body(); } catch(e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } const Arrow = _ref => { let { taskFrom, taskTo, rowHeight, taskHeight, arrowIndent, rtl, arrowColor } = _ref; let path; let trianglePoints; if (rtl) { [path, trianglePoints] = drownPathAndTriangleRTL(taskFrom, taskTo, rowHeight, taskHeight, arrowIndent); } else { [path, trianglePoints] = drownPathAndTriangle(taskFrom, taskTo, rowHeight, taskHeight, arrowIndent); } return React.createElement("g", { className: "arrow" }, React.createElement("path", { strokeWidth: "1.5", d: path, fill: "none", stroke: arrowColor }), React.createElement("polygon", { points: trianglePoints, fill: arrowColor })); }; const drownPathAndTriangle = (taskFrom, taskTo, rowHeight, taskHeight, arrowIndent) => { let taskToStart, taskFromEnd; if (taskTo.x1 > 0 && taskTo.actualx1 > 0) { taskToStart = Math.min(taskTo.x1, taskTo.actualx1); } else if (taskTo.x1 > 0) taskToStart = taskTo.x1;else if (taskTo.actualx1 > 0) taskToStart = taskTo.actualx1;else taskToStart = 0; if (taskFrom.x2 > 0 && taskFrom.actualx2 > 0) { taskFromEnd = Math.max(taskFrom.x2, taskFrom.actualx2); } else if (taskFrom.x2 > 0) taskFromEnd = taskFrom.x2;else if (taskFrom.actualx2 > 0) taskFromEnd = taskFrom.actualx2;else taskFromEnd = 0; const indexCompare = taskFrom.index > taskTo.index ? -1 : 1; const taskToEndPosition = taskTo.y + taskHeight / 2; const taskFromEndPosition = taskFromEnd + arrowIndent * 2; const taskFromHorizontalOffsetValue = taskFromEndPosition < taskToStart ? "" : `H ${taskToStart - arrowIndent}`; const taskToHorizontalOffsetValue = taskFromEndPosition > taskToStart ? arrowIndent : taskToStart - taskFromEnd - arrowIndent; const path = `M ${taskFromEnd} ${taskFrom.y + taskHeight / 2} h ${arrowIndent} v ${indexCompare * rowHeight / 2} ${taskFromHorizontalOffsetValue} V ${taskToEndPosition} h ${taskToHorizontalOffsetValue}`; const trianglePoints = `${taskToStart},${taskToEndPosition} ${taskToStart - 5},${taskToEndPosition - 5} ${taskToStart - 5},${taskToEndPosition + 5}`; return [path, trianglePoints]; }; const drownPathAndTriangleRTL = (taskFrom, taskTo, rowHeight, taskHeight, arrowIndent) => { const indexCompare = taskFrom.index > taskTo.index ? -1 : 1; const taskToEndPosition = taskTo.y + taskHeight / 2; const taskFromEndPosition = taskFrom.x1 - arrowIndent * 2; const taskFromHorizontalOffsetValue = taskFromEndPosition > taskTo.x2 ? "" : `H ${taskTo.x2 + arrowIndent}`; const taskToHorizontalOffsetValue = taskFromEndPosition < taskTo.x2 ? -arrowIndent : taskTo.x2 - taskFrom.x1 + arrowIndent; const path = `M ${taskFrom.x1} ${taskFrom.y + taskHeight / 2} h ${-arrowIndent} v ${indexCompare * rowHeight / 2} ${taskFromHorizontalOffsetValue} V ${taskToEndPosition} h ${taskToHorizontalOffsetValue}`; const trianglePoints = `${taskTo.x2},${taskToEndPosition} ${taskTo.x2 + 5},${taskToEndPosition + 5} ${taskTo.x2 + 5},${taskToEndPosition - 5}`; return [path, trianglePoints]; }; var convertToBarTasks = function convertToBarTasks(tasks, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor) { var barTasks = tasks.map(function (t, i) { return convertToBarTask(t, i, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor); }); barTasks = barTasks.map(function (task) { var dependencies = task.dependencies || []; var _loop = function _loop(j) { var dependence = barTasks.findIndex(function (value) { return value.id === dependencies[j]; }); if (dependence !== -1 && task.start.getTime() > 0 && task.end.getTime() > 0) barTasks[dependence].barChildren.push(task); }; for (var j = 0; j < dependencies.length; j++) { _loop(j); } return task; }); return barTasks; }; var convertToBarTask = function convertToBarTask(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor, milestoneBackgroundColor, milestoneBackgroundSelectedColor) { var barTask; switch (task.type) { case "milestone": barTask = convertToMilestone(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, milestoneBackgroundColor, milestoneBackgroundSelectedColor); break; case "project": barTask = convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, projectProgressColor, projectProgressSelectedColor, projectBackgroundColor, projectBackgroundSelectedColor); break; default: barTask = convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor); break; } return barTask; }; var convertToBar = function convertToBar(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, rtl, barProgressColor, barProgressSelectedColor, barBackgroundColor, barBackgroundSelectedColor) { var x1; var x2; var actualx1; var actualx2; var progressStartWidth; var progressEndWidth; if (rtl) { x2 = task.start ? taskXCoordinateRTL(task.start, dates, columnWidth) : -1; x1 = task.end ? taskXCoordinateRTL(task.end, dates, columnWidth) : -1; actualx1 = task.actualStart ? taskXCoordinateRTL(task.actualStart, dates, columnWidth) : -1; actualx2 = task.actualEnd ? taskXCoordinateRTL(task.actualEnd, dates, columnWidth) : -1; } else { x1 = task.start ? taskXCoordinate(task.start, dates, columnWidth) : -1; x2 = task.end ? taskXCoordinate(task.end, dates, columnWidth) : -1; actualx1 = task.actualStart ? taskXCoordinate(task.actualStart, dates, columnWidth) : -1; actualx2 = task.actualEnd ? taskXCoordinate(task.actualEnd, dates, columnWidth) : -1; } progressStartWidth = actualx1 && x1 ? Math.abs(actualx1 - x1) : -1; progressEndWidth = actualx2 && x2 ? Math.abs(actualx2 - x2) : -1; var typeInternal = task.type; var _progressWithByParams = progressWithByParams(actualx1, actualx2, task.progress, rtl), progressWidth = _progressWithByParams[0], progressX = _progressWithByParams[1]; var y = taskYCoordinate(index, rowHeight, taskHeight); var hideChildren = task.hideChildren || false; var styles = _extends({ backgroundColor: barBackgroundColor, backgroundSelectedColor: barBackgroundSelectedColor, progressColor: barProgressColor, progressSelectedColor: barProgressSelectedColor }, task.styles); return _extends({}, task, { typeInternal: typeInternal, x1: x1, x2: x2, actualx1: actualx1, actualx2: actualx2, progressStartWidth: progressStartWidth, progressEndWidth: progressEndWidth, y: y, index: index, progressX: progressX, progressWidth: progressWidth, barCornerRadius: barCornerRadius, handleWidth: handleWidth, hideChildren: hideChildren, height: taskHeight, barChildren: [], styles: styles }); }; var convertToMilestone = function convertToMilestone(task, index, dates, columnWidth, rowHeight, taskHeight, barCornerRadius, handleWidth, milestoneBackgroundColor, milestoneBackgroundSelectedColor) { var x = task.start && task.end ? taskXCoordinate(task.start, dates, columnWidth) : 0; var y = taskYCoordinate(index, rowHeight, taskHeight); var x1 = task.start && task.end ? x - taskHeight * 0.5 : 0; var x2 = task.start && task.end ? x + taskHeight * 0.5 : 0; var rotatedHeight = taskHeight / 1.414; var styles = _extends({ backgroundColor: milestoneBackgroundColor, backgroundSelectedColor: milestoneBackgroundSelectedColor, progressColor: "", progressSelectedColor: "" }, task.styles); return _extends({}, task, { x1: x1, x2: x2, actualx1: x1, actualx2: x2, progre