UNPKG

@syncfusion/ej2-gantt

Version:
998 lines (994 loc) 2.76 MB
import { isNullOrUndefined, extend, getValue, setValue, EventHandler, formatUnit, createElement, removeClass, addClass, closest, Browser, append, merge, remove, deleteObject, initializeCSPTemplate, Property, ChildProperty, Collection, Complex, SanitizeHtmlHelper, compile, isObject, Internationalization, L10n, KeyboardEvents, isUndefined, isObjectArray, Event, NotifyPropertyChanges, Component, classList } from '@syncfusion/ej2-base'; import { Tooltip as Tooltip$1, createSpinner, showSpinner, hideSpinner, Dialog } from '@syncfusion/ej2-popups'; import { DataManager, ODataAdaptor, ODataV4Adaptor, WebApiAdaptor, WebMethodAdaptor, CacheAdaptor, RemoteSaveAdaptor, UrlAdaptor, Query, DataUtil, Deferred } from '@syncfusion/ej2-data'; import { click, Predicate, getActualProperties, getObject, ExcelExport as ExcelExport$1, PdfExport as PdfExport$1, Print, Search, Toolbar as Toolbar$1, RowDD as RowDD$1, DetailRow, Reorder as Reorder$1, Resize as Resize$1, ContextMenu as ContextMenu$1, ColumnMenu as ColumnMenu$1, ColumnChooser, Aggregate, Edit as Edit$2, Group, Page, Sort as Sort$1, Filter as Filter$1, Grid, ForeignKey, filterAfterOpen, getFilterMenuPostion, getCustomDateFormat, setCssInGridPopUp, parentsUntil as parentsUntil$1, ValueFormatter, getForeignData } from '@syncfusion/ej2-grids'; import { TreeGrid, Edit as Edit$1, VirtualScroll as VirtualScroll$1, Toolbar as Toolbar$2, Selection as Selection$2, RowDD as RowDD$2, Reorder as Reorder$2, Resize as Resize$2, Aggregate as Aggregate$1, Page as Page$1, Sort as Sort$2, Filter as Filter$2, ContextMenu as ContextMenu$3, ExcelExport as ExcelExport$2, ColumnMenu as ColumnMenu$2 } from '@syncfusion/ej2-treegrid'; import { AutoComplete, DropDownList, ComboBox, MultiSelect, CheckBoxSelection } from '@syncfusion/ej2-dropdowns'; import { SvgRenderer } from '@syncfusion/ej2-svg-base'; import { Splitter as Splitter$1 } from '@syncfusion/ej2-layouts'; import { Tab, Toolbar as Toolbar$4, ContextMenu as ContextMenu$2 } from '@syncfusion/ej2-navigations'; import { RichTextEditor, MarkdownEditor, FormatPainter, FileManager, EmojiPicker, Table, Image, Toolbar as Toolbar$3, Link, HtmlEditor, QuickToolbar, Count } from '@syncfusion/ej2-richtexteditor'; import { MaskedTextBox, NumericTextBox, TextBox, FormValidator } from '@syncfusion/ej2-inputs'; import { CheckBox, RadioButton } from '@syncfusion/ej2-buttons'; import { DatePicker, DateTimePicker } from '@syncfusion/ej2-calendars'; import { PdfColor, PdfFontFamily, PdfPen, PdfDashStyle, PdfStringFormat, PdfBorderOverlapStyle, RectangleF, PdfLayoutBreakType, PointF, SizeF, PdfLayoutType, RowLayoutResult, ElementLayouter, PdfLayoutResult, PdfLayoutFormat, PdfLayoutElement, PdfStringLayouter, PdfStandardFont, PdfFontStyle, PdfSolidBrush, PdfImage, PdfBitmap, PdfTextWebLink, PdfTextAlignment, PdfLineCap, PdfVerticalAlignment, PdfPageTemplateElement, PdfPageNumberField, PdfPageCountField, PdfCompositeField, PdfLinearGradientBrush, PdfPath, PdfBrushes, PdfWordWrapType, PdfPage, PdfDocument, PdfPageSettings, PdfPageOrientation } from '@syncfusion/ej2-pdf-export'; /** * Common methods used in Gantt */ /** * @param {Element} elem . * @param {string} selector . * @param {boolean} isID . * @returns {Element} . * @hidden */ function parentsUntil(elem, selector, isID) { var parent = elem; while (parent) { if (isID ? parent.id === selector : parent.classList.contains(selector)) { break; } parent = parent.parentElement; } return parent; } /** * @param {ITaskData} ganttProp . * @returns {boolean} . * @hidden */ function isScheduledTask(ganttProp) { if (isNullOrUndefined(ganttProp.startDate) && isNullOrUndefined(ganttProp.endDate) && isNullOrUndefined(ganttProp.duration)) { return null; } else if (isNullOrUndefined(ganttProp.startDate) || isNullOrUndefined(ganttProp.endDate) || isNullOrUndefined(ganttProp.duration)) { return false; } else { return true; } } /** * @param {Gantt} parent . * @returns {boolean} . * @hidden */ function isCountRequired(parent) { if (parent.dataSource && !(parent.dataSource instanceof DataManager) && 'result' in parent.dataSource) { return true; } return false; } /** * @param {object} obj . * @returns {object} . * @hidden */ function getSwapKey(obj) { var temp = {}; for (var _i = 0, _a = Object.keys(obj); _i < _a.length; _i++) { var key = _a[_i]; temp[obj[key]] = key; } return temp; } /** * @param {object} obj . * @returns {boolean} . * @hidden */ function isEmptyObject(obj) { if (isNullOrUndefined(obj) || typeof obj !== 'object') { return false; } return Object.keys(obj).length === 0; } /** * @param {Date} date . * @returns {number} . * @hidden */ function getUniversalTime(date) { var year = date.getFullYear(); var month = date.getMonth(); var day = date.getDate(); var hours = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); var milliseconds = date.getMilliseconds(); return Date.UTC(year, month, day, hours, minutes, seconds, milliseconds); } /** * @param {object} dataSource . * @returns {boolean} . * @hidden */ function isRemoteData(dataSource) { if (dataSource instanceof DataManager) { var adaptor = dataSource.adaptor; return (adaptor instanceof ODataAdaptor || (adaptor instanceof ODataV4Adaptor) || (adaptor instanceof WebApiAdaptor) || (adaptor instanceof WebMethodAdaptor) || (adaptor instanceof CacheAdaptor) || (adaptor instanceof RemoteSaveAdaptor) || adaptor instanceof UrlAdaptor); } return false; } /** * @param {IGanttData[]} records . * @param {boolean} isNotExtend . * @param {ITaskAddedEventArgs} eventArgs . * @param {Gantt} parent . * @returns {object[]} . * @hidden */ function getTaskData(records, isNotExtend, eventArgs, parent) { if (eventArgs) { var result = void 0; for (var i = 0; i < records.length; i++) { var data = isNotExtend ? (records[parseInt(i.toString(), 10)].taskData) : extend({}, records[parseInt(i.toString(), 10)].taskData, {}, true); result = (data); } return result; } else { var result = []; for (var i = 0; i < records.length; i++) { if (!isNullOrUndefined(parent) && parent.timezone) { updateDates(records[i], parent); } var data = isNotExtend ? (records[parseInt(i.toString(), 10)].taskData) : extend({}, records[parseInt(i.toString(), 10)].taskData, {}, true); result.push(data); } return result; } } /** * @param {IGanttData} record . * @param {Gantt} parent . * @returns {null} . * @hidden */ function updateDates(record, parent) { // let startDate: Date = (record as IGanttData).taskData[parent.taskFields.startDate]; if (record && !isNullOrUndefined(record.ganttProperties)) { var taskData = record.taskData; var ganttProps = record.ganttProperties; // Update start date taskData[parent.taskFields.startDate] = parent.dateValidationModule.remove(ganttProps.startDate, parent.timezone); // Update end date if defined if (parent.taskFields.endDate !== null) { taskData[parent.taskFields.endDate] = parent.dateValidationModule.remove(ganttProps.endDate, parent.timezone); } // Update baseline dates if defined if (parent.taskFields.baselineStartDate || parent.taskFields.baselineEndDate) { taskData[parent.taskFields.baselineStartDate] = parent.dateValidationModule.remove(ganttProps.baselineStartDate, parent.timezone); taskData[parent.taskFields.baselineEndDate] = parent.dateValidationModule.remove(ganttProps.baselineEndDate, parent.timezone); } // Update custom date columns parent.editModule['processCustomDateColumns'](record, taskData, parent, 'remove'); } return null; } /** * @param {string} str . * @param {string[]} args . * @returns {string} . * @hidden */ function formatString(str, args) { var regx; for (var i = 0; i < args.length; i++) { // eslint-disable-next-line security/detect-non-literal-regexp regx = new RegExp('\\{' + (i) + '\\}', 'gm'); str = str.replace(regx, args[i].toString()); } return str; } /** * @param {any} value . * @param {string} key1 . * @param {any} collection . * @param {string} key2 * @returns {number} . * @hidden */ /* eslint-disable-next-line */ function getIndex(value, key1, collection, key2) { var index = -1; for (var i = 0; i < collection.length; i++) { if (getValue(key1, collection[i]) === getValue(key1, value) && isNullOrUndefined(key2) || (!isNullOrUndefined(key2) && getValue(key1, collection[i]) === getValue(key1, value) && getValue(key2, collection[i]) === getValue(key2, value))) { index = i; break; } } return index; } /** * @param {number} value . * @returns {number} . * @hidden */ function pixelToPoint(value) { return (value * 76) / 92; } /** * @param {number} value . * @returns {number} . * @hidden */ function pointToPixel(value) { return (value * 92) / 76; } var uid = 0; /** * @returns {number} . * @hidden */ function getUid() { return uid++; } /** * Defines the constraint types used for task scheduling. * * Available values: * - `0`: AsSoonAsPossible (ASAP) – Task starts as early as possible. Default for auto-scheduled tasks. * - `1`: AsLateAsPossible (ALAP) – Task finishes as late as possible without delaying dependents. * - `2`: MustStartOn (MSO) – Task must start on the specified date. * - `3`: MustFinishOn (MFO) – Task must finish on the specified date. * - `4`: StartNoEarlierThan (SNET) – Task cannot start before the specified date. * - `5`: StartNoLaterThan (SNLT) – Task must start on or before the specified date. * - `6`: FinishNoEarlierThan (FNET) – Task cannot finish before the specified date. * - `7`: FinishNoLaterThan (FNLT) – Task must finish on or before the specified date. */ var ConstraintType; (function (ConstraintType) { ConstraintType[ConstraintType["AsSoonAsPossible"] = 0] = "AsSoonAsPossible"; ConstraintType[ConstraintType["AsLateAsPossible"] = 1] = "AsLateAsPossible"; ConstraintType[ConstraintType["MustStartOn"] = 2] = "MustStartOn"; ConstraintType[ConstraintType["MustFinishOn"] = 3] = "MustFinishOn"; ConstraintType[ConstraintType["StartNoEarlierThan"] = 4] = "StartNoEarlierThan"; ConstraintType[ConstraintType["StartNoLaterThan"] = 5] = "StartNoLaterThan"; ConstraintType[ConstraintType["FinishNoEarlierThan"] = 6] = "FinishNoEarlierThan"; ConstraintType[ConstraintType["FinishNoLaterThan"] = 7] = "FinishNoLaterThan"; })(ConstraintType || (ConstraintType = {})); /** * Date processor is used to handle date of task data. */ var DateProcessor = /** @__PURE__ @class */ (function () { function DateProcessor(parent) { this.fromSegments = false; this.mondayTimeRangeLength = 0; this.tuesdayTimeRangeLength = 0; this.wednesdayTimeRangeLength = 0; this.thursdayTimeRangeLength = 0; this.fridayTimeRangeLength = 0; this.saturdayTimeRangeLength = 0; this.sundayTimeRangeLength = 0; this.parent = parent; } /** * @param {ITaskData} ganttProp . * @returns {boolean} . */ DateProcessor.prototype.isValidateNonWorkDays = function (ganttProp) { return (!isNullOrUndefined(ganttProp) && ganttProp.isAutoSchedule && (!this.parent.includeWeekend || this.parent.totalHolidayDates.length > 0)) || (isNullOrUndefined(ganttProp) && (!this.parent.includeWeekend || this.parent.totalHolidayDates.length > 0)); }; /** * Method to convert given date value as valid start date * * @param {Date} date . * @param {ITaskData} ganttProp - The Gantt properties related to the task. * @param {boolean} validateAsMilestone - Indicates whether the date should be validated as a milestone. * @param {boolean} isLoad - A flag indicating if the method is called during the loading process. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} . * @private */ DateProcessor.prototype.checkStartDate = function (date, ganttProp, validateAsMilestone, isLoad, isBaseline) { if (isNullOrUndefined(date)) { return null; } var currentDay = new Date(date.getTime()); var dayStartTime = this.parent['getCurrentDayStartTime'](currentDay); var dayEndTime = this.parent['getCurrentDayEndTime'](currentDay); var cloneStartDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneStartDate); validateAsMilestone = isNullOrUndefined(validateAsMilestone) ? !isNullOrUndefined(ganttProp) ? ganttProp.isMilestone : false : validateAsMilestone; if (hour < dayStartTime && (!validateAsMilestone || isLoad)) { this.setTime(dayStartTime, cloneStartDate); } else if (hour < dayStartTime && validateAsMilestone) { this.setTime(dayStartTime, cloneStartDate); } else if ((hour === dayEndTime && (!ganttProp || !validateAsMilestone)) || hour > dayEndTime) { cloneStartDate.setDate(cloneStartDate.getDate() + 1); dayStartTime = this.parent['getCurrentDayStartTime'](cloneStartDate); this.setTime(dayStartTime, cloneStartDate); } else if (hour > dayStartTime && hour < dayEndTime) { var workingRange = this.parent.workingTimeRanges; if (this.parent.weekWorkingTime.length > 0) { workingRange = this.parent['getWorkingRange'](cloneStartDate); } for (var index = 0; index < workingRange.length; index++) { var value = workingRange[index]; if (hour >= value.to && (workingRange[index + 1] && hour < workingRange[index + 1].from)) { // milestone can fall at end any interval time if ((hour === value.to && (!ganttProp || !validateAsMilestone)) || hour !== value.to) { this.setTime(workingRange[index + 1].from, cloneStartDate); } break; } } } var tStartDate; if (this.parent.autoCalculateDateScheduling && !(this.parent.isLoad && this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) { do { tStartDate = new Date(cloneStartDate.getTime()); var holidayLength = this.parent.totalHolidayDates.length; // check holidays and weekends if (this.isValidateNonWorkDays(ganttProp)) { dayStartTime = this.parent['getCurrentDayStartTime'](tStartDate); if (ganttProp) { if (!isBaseline) { dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : tStartDate); } else { dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.baselineEndDate ? ganttProp.baselineEndDate : tStartDate); } } var startTime = (!validateAsMilestone || isLoad) ? dayStartTime : dayEndTime; if (!this.parent.includeWeekend && !isBaseline) { var tempDate = new Date(cloneStartDate.getTime()); cloneStartDate = this.getNextWorkingDay(cloneStartDate); startTime = this.parent['getCurrentDayStartTime'](cloneStartDate); if (tempDate.getTime() !== cloneStartDate.getTime() && !validateAsMilestone) { this.setTime(startTime, cloneStartDate); } } if (!isBaseline) { for (var count = 0; count < holidayLength; count++) { var holidayFrom = this.getDateFromFormat(new Date(this.parent.totalHolidayDates[count])); var holidayTo = new Date(holidayFrom.getTime()); holidayFrom.setHours(0, 0, 0, 0); holidayTo.setHours(23, 59, 59, 59); if (cloneStartDate.getTime() >= holidayFrom.getTime() && cloneStartDate.getTime() < holidayTo.getTime()) { cloneStartDate.setDate(cloneStartDate.getDate() + 1); startTime = this.parent['getCurrentDayStartTime'](cloneStartDate); this.setTime(startTime, cloneStartDate); } } } } } while (tStartDate.getTime() !== cloneStartDate.getTime()); return new Date(cloneStartDate.getTime()); } else { return new Date(cloneStartDate.getTime()); } }; DateProcessor.prototype.getAdjustedStartDate = function (constraintDate, ganttProp) { var adjustedDate = new Date(constraintDate); adjustedDate.setDate(adjustedDate.getDate() + 1); var checkedEnd = this.parent.dateValidationModule.checkEndDate(adjustedDate); return this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); }; DateProcessor.prototype.getDateByConstraint = function (ganttData, date, validPredecessor) { var ganttProp = ganttData['ganttProperties'] ? ganttData['ganttProperties'] : ganttData; var constraintDate = new Date(ganttProp.constraintDate); var isLoad = this.parent.isLoad; if (isNullOrUndefined(validPredecessor)) { validPredecessor = true; } if ((!constraintDate || !date) && validPredecessor) { return null; } if (this.parent.editModule && this.parent.editModule.dialogModule && this.parent.editModule.dialogModule['dialogConstraintDate']) { constraintDate = new Date(this.parent.editModule.dialogModule['dialogConstraintDate']); } else { constraintDate = this.parent['assignTimeToDate'](constraintDate, this.parent['getCurrentDayStartTime'](constraintDate)); } var parentRecord = null; var record = this.parent.getRecordByID(ganttProp.taskId); if (record && record.parentItem) { parentRecord = record.parentItem; } switch (ganttProp.constraintType) { case ConstraintType.AsSoonAsPossible: if (isLoad) { return date; } else { ganttProp.constraintDate = null; if (ganttProp.predecessor && ganttProp.predecessor.length > 0) { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } else if (parentRecord) { return this.parent.getRecordByID(parentRecord.taskId).ganttProperties.startDate; } else { return this.parent.dateValidationModule.checkStartDate(new Date(this.parent.projectStartDate)); } } case ConstraintType.AsLateAsPossible: if (isLoad) { return date; } else { if (parentRecord) { var checkedEnd = this.parent.dateValidationModule.checkEndDate(this.parent.getRecordByID(parentRecord.taskId).ganttProperties.endDate); var start = this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); return start; } else { var checkedEnd = this.parent.dateValidationModule.checkEndDate(new Date(this.parent.projectEndDate)); var start = this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); return start; } } case ConstraintType.MustStartOn: { var isViolation = constraintDate.getTime() !== ganttProp.startDate.getTime(); var constraintValue = void 0; if (this.parent.editModule && this.parent.editModule.dialogModule) { constraintValue = this.parent.editModule.dialogModule['dialogConstraintValue']; } var isConstraintTypeRestricted = isNullOrUndefined(constraintValue) || constraintValue === 2 || constraintValue === 3; if (isViolation && !isLoad && isConstraintTypeRestricted) { this.parent.constraintViolationType = 'MustStartOn'; } constraintValue = null; if (isLoad) { return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } else { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } } case ConstraintType.MustFinishOn: { var isViolation = constraintDate.getTime() !== ganttProp.endDate.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'MustFinishOn'; } return this.getAdjustedStartDate(constraintDate, ganttProp); } case ConstraintType.StartNoEarlierThan: { if (constraintDate.getTime() < date.getTime() || !isLoad) { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } case ConstraintType.StartNoLaterThan: { var isViolation = constraintDate.getTime() < date.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'StartNoLaterThan'; } if (!isLoad) { var cellEditModule = this.parent.editModule && this.parent.editModule.cellEditModule; var constraintField = this.parent.taskFields && this.parent.taskFields.constraintDate; if (cellEditModule && cellEditModule.isCellEdit && cellEditModule.editedColumn && isViolation && cellEditModule.editedColumn.field === constraintField) { return constraintDate; } if (this.parent.editModule && this.parent.editModule.dialogModule && isViolation && this.parent.editModule.dialogModule['dialogConstraintDate']) { return constraintDate; } return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } if (isViolation && isLoad) { return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } else { return date; } } case ConstraintType.FinishNoEarlierThan: { var endDate = this.getEndDate(date, ganttProp.duration, ganttProp.durationUnit, ganttProp, false, false); if (endDate.getTime() < constraintDate.getTime()) { return this.getAdjustedStartDate(constraintDate, ganttProp); } else { return date; } } case ConstraintType.FinishNoLaterThan: { var endDate = this.getEndDate(date, ganttProp.duration, ganttProp.durationUnit, ganttProp, false, false); var isViolation = constraintDate.getTime() < endDate.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'FinishNoLaterThan'; } if (!isLoad) { if (isViolation) { return this.getAdjustedStartDate(constraintDate, ganttProp); } return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayEndTime'](date)); } if (isViolation) { return this.getAdjustedStartDate(constraintDate, ganttProp); } else { return date; } } default: return date; } }; /** * To update given date value to valid end date * * @param {Date} date . * @param {ITaskData} ganttProp . * @param {boolean} validateAsMilestone . * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} . * @private */ DateProcessor.prototype.checkEndDate = function (date, ganttProp, validateAsMilestone, isBaseline) { if (isNullOrUndefined(date)) { return null; } var dayStartTime; var dayEndTime; if (this.parent.weekWorkingTime.length > 0) { var currentDay = new Date(date.getTime()); if (!this.parent.includeWeekend && ganttProp && ganttProp.isAutoSchedule || (this.parent.editModule && this.parent.editModule.taskbarEditModule && this.parent.editModule.taskbarEditModule.taskBarEditRecord && !this.parent.editModule.taskbarEditModule.taskBarEditRecord.ganttProperties.isAutoSchedule)) { currentDay = this.getNextWorkingDay(currentDay); } dayStartTime = this.parent['getStartTime'](currentDay); dayEndTime = this.parent['getEndTime'](currentDay); } else { dayStartTime = this.parent.defaultStartTime; dayEndTime = this.parent.defaultEndTime; } var cloneEndDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneEndDate); if (hour > dayEndTime) { this.setTime(dayEndTime, cloneEndDate); } else if (hour <= dayStartTime && dayEndTime !== 86400 && !validateAsMilestone) { var taskfields = this.parent.taskFields; if (this.parent.editModule && this.parent.editModule['editedRecord'] && (!this.parent.editModule['editedRecord'][taskfields.startDate] && this.parent.editModule['editedRecord'][taskfields.endDate])) { cloneEndDate.setDate(cloneEndDate.getDate()); } else { cloneEndDate.setDate(cloneEndDate.getDate() - 1); } dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); this.setTime(dayEndTime, cloneEndDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var index = 0; index < this.parent.workingTimeRanges.length; index++) { var value = this.parent.workingTimeRanges[index]; if (hour > value.to && (this.parent.workingTimeRanges[index + 1] && hour <= this.parent.workingTimeRanges[index + 1].from)) { this.setTime(this.parent.workingTimeRanges[index].to, cloneEndDate); break; } } } var tempCheckDate; if (this.parent.autoCalculateDateScheduling && !(this.parent.isLoad && this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) { do { tempCheckDate = new Date(cloneEndDate.getTime()); var holidayLength = this.parent.totalHolidayDates.length; if (this.isValidateNonWorkDays(ganttProp) && !isBaseline) { if (!this.parent.includeWeekend) { var tempDate = new Date(cloneEndDate.getTime()); cloneEndDate = this.getPreviousWorkingDay(cloneEndDate); dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); if (tempDate.getTime() !== cloneEndDate.getTime()) { this.setTime(dayEndTime, cloneEndDate); } } for (var count = 0; count < holidayLength; count++) { var holidayFrom = this.getDateFromFormat(new Date(this.parent.totalHolidayDates[count])); var holidayTo = new Date(holidayFrom.getTime()); var tempHoliday = new Date(cloneEndDate.getTime()); tempHoliday.setMinutes(cloneEndDate.getMilliseconds() - 2); holidayFrom.setHours(0, 0, 0, 0); holidayTo.setHours(23, 59, 59, 59); if (cloneEndDate.getTime() >= holidayFrom.getTime() && cloneEndDate.getTime() < holidayTo.getTime() || tempHoliday.getTime() >= holidayFrom.getTime() && tempHoliday.getTime() < holidayTo.getTime()) { cloneEndDate.setDate(cloneEndDate.getDate() - 1); dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); if (!(cloneEndDate.getTime() === holidayFrom.getTime() && dayEndTime === 86400 && this.getSecondsInDecimal(cloneEndDate) === 0)) { this.setTime(dayEndTime, cloneEndDate); } } } } } while (tempCheckDate.getTime() !== cloneEndDate.getTime()); return new Date(cloneEndDate.getTime()); } else { if (!isNullOrUndefined(cloneEndDate) && this.parent.defaultEndTime !== 86400) { dayEndTime = this.parent['getCurrentDayEndTime'](date); this.setTime(dayEndTime, cloneEndDate); } return new Date(cloneEndDate.getTime()); } }; /** * To validate the baseline start date * * @param {Date} date . * @param {ITaskData} ganttProp . * @returns {Date} . * @private */ DateProcessor.prototype.checkBaselineStartDate = function (date, ganttProp) { if (isNullOrUndefined(date)) { return null; } else { var dayStartTime = this.parent['getCurrentDayStartTime'](date); var dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp ? ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : date : date); var cloneDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneDate); if (hour < dayStartTime) { this.setTime(dayStartTime, cloneDate); } else if (hour > dayEndTime) { cloneDate.setDate(cloneDate.getDate() + 1); if (this.parent.weekWorkingTime.length > 0) { dayStartTime = this.parent['getStartTime'](cloneDate); } else { dayStartTime = this.parent.defaultStartTime; } this.setTime(dayStartTime, cloneDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var i = 0; i < this.parent.workingTimeRanges.length; i++) { var value = this.parent.workingTimeRanges[i]; if (hour > value.to && (this.parent.workingTimeRanges[i + 1] && hour < this.parent.workingTimeRanges[i + 1].from)) { this.setTime(this.parent.workingTimeRanges[i + 1].from, cloneDate); break; } } } return cloneDate; } }; /** * To validate baseline end date * * @param {Date} date . * @param {ITaskData} ganttProp . * @returns {Date} . * @private */ DateProcessor.prototype.checkBaselineEndDate = function (date, ganttProp) { if (isNullOrUndefined(date)) { return null; } else { var dayEndTime = this.parent['getCurrentDayEndTime'](date); var dayStartTime = this.parent['getCurrentDayStartTime'](ganttProp ? ganttProp.startDate ? ganttProp.isAutoSchedule ? ganttProp.startDate : ganttProp.autoStartDate : date : date); var cloneDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneDate); if (hour > dayEndTime) { this.setTime(dayEndTime, cloneDate); } else if (hour < dayStartTime && !isNullOrUndefined(ganttProp) && !ganttProp.isMilestone) { cloneDate.setDate(cloneDate.getDate() - 1); dayEndTime = this.parent['getCurrentDayEndTime'](cloneDate); this.setTime(dayEndTime, cloneDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var i = 0; i < this.parent.workingTimeRanges.length; i++) { var value = this.parent.workingTimeRanges[i]; if (hour > value.to && (this.parent.workingTimeRanges[i + 1] && hour <= this.parent.workingTimeRanges[i + 1].from)) { this.setTime(this.parent.workingTimeRanges[i].to, cloneDate); break; } } } if (ganttProp && ganttProp.baselineStartDate && cloneDate && ganttProp.baselineStartDate.getTime() > cloneDate.getTime()) { cloneDate.setDate(cloneDate.getDate() + 1); } return cloneDate; } }; /** * To calculate start date value from duration and end date * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . * @private */ DateProcessor.prototype.calculateStartDate = function (ganttData, isBaseline) { var ganttProp = ganttData.ganttProperties; var tempStartDate = null; if (isBaseline) { if (!isNullOrUndefined(ganttProp.baselineEndDate) && !isNullOrUndefined(ganttProp.baselineDuration)) { tempStartDate = this.getStartDate(ganttProp.baselineEndDate, ganttProp.baselineDuration, ganttProp.durationUnit, ganttProp, undefined, true); } this.parent.setRecordValue('baselineStartDate', tempStartDate, ganttProp, true); if (this.parent.taskFields.baselineStartDate) { this.parent.dataOperation.updateMappingData(ganttData, 'baselineStartDate'); } } else { if (!isNullOrUndefined(ganttProp.endDate) && !isNullOrUndefined(ganttProp.duration)) { tempStartDate = this.getStartDate(ganttProp.endDate, ganttProp.duration, ganttProp.durationUnit, ganttProp); } this.parent.setRecordValue('startDate', tempStartDate, ganttProp, true); if (this.parent.taskFields.startDate) { this.parent.dataOperation.updateMappingData(ganttData, 'startDate'); } } }; /** * Gets task field mappings based on baseline context. * * @param {boolean} isBaseline - Flag indicating if baseline fields should be used. * @returns {{ startdateField: string, enddateField: string, durationField: string }} - Object containing field names for start date, end date, and duration. */ DateProcessor.prototype.getFieldMappings = function (isBaseline) { return { startdateField: isBaseline ? 'baselineStartDate' : 'startDate', enddateField: isBaseline ? 'baselineEndDate' : 'endDate', durationField: isBaseline ? 'baselineDuration' : 'duration' }; }; /** * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . * @public */ /* eslint-disable */ DateProcessor.prototype.calculateEndDate = function (ganttData, isBaseline) { var ganttProp = ganttData.ganttProperties; var tempEndDate = null; var dayStartTime; var dayEndTime; var _a = this.getFieldMappings(isBaseline), startdateField = _a.startdateField, enddateField = _a.enddateField, durationField = _a.durationField; if (!isNullOrUndefined(ganttProp[startdateField])) { if (!isNullOrUndefined(ganttProp[enddateField]) && isNullOrUndefined(ganttProp[durationField])) { if (this.compareDates(ganttProp[startdateField], ganttProp[enddateField]) === 1) { this.parent.setRecordValue(startdateField, new Date(ganttProp[enddateField].getTime()), ganttProp, true); dayStartTime = this.parent['getCurrentDayStartTime'](ganttProp.isAutoSchedule && !isBaseline ? ganttProp.autoStartDate : ganttProp[startdateField]); dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.isAutoSchedule && !isBaseline ? ganttProp.autoEndDate : ganttProp[enddateField]); this.setTime(dayStartTime, ganttProp[startdateField]); } this.calculateDuration(ganttData, isBaseline); } if (!isNullOrUndefined(ganttProp[durationField])) { var duration = !isBaseline && !isNullOrUndefined(ganttProp.segments) && ganttProp.segments.length > 1 ? this.totalDuration(ganttProp.segments) : ganttProp[durationField]; tempEndDate = this.getEndDate(ganttProp[startdateField], duration, ganttProp.durationUnit, ganttProp, false, isBaseline); } this.parent.setRecordValue(enddateField, tempEndDate, ganttProp, true); } else { tempEndDate = ganttData[this.parent.taskFields[enddateField]]; if (!isNullOrUndefined(tempEndDate)) { dayEndTime = this.parent['getCurrentDayEndTime'](tempEndDate); this.setTime(dayEndTime, tempEndDate); } this.parent.setRecordValue(enddateField, tempEndDate, ganttProp, true); } if (this.parent.taskFields[enddateField]) { this.parent.dataOperation.updateMappingData(ganttData, enddateField); } }; /* eslint-enable */ DateProcessor.prototype.totalDuration = function (segments) { var duration = 0; for (var i = 0; i < segments.length; i++) { duration += segments[i].duration + segments[i].offsetDuration; } return duration; }; /** * To calculate duration from start date and end date * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . */ DateProcessor.prototype.calculateDuration = function (ganttData, isBaseline) { var ganttProperties = ganttData.ganttProperties; var tDuration; if (!isBaseline && !isNullOrUndefined(ganttProperties.segments) && ganttProperties.segments.length > 0 && !isNullOrUndefined(this.parent.editModule.taskbarEditModule)) { tDuration = this.parent.editModule.taskbarEditModule.sumOfDuration(ganttProperties.segments); } else { if (!isBaseline && (!isNullOrUndefined(this.parent.taskFields.milestone)) && (!isNullOrUndefined(ganttProperties.startDate)) && !isNullOrUndefined(ganttProperties.endDate) && (ganttProperties.startDate).getTime() === (ganttProperties.endDate).getTime() && (ganttData.taskData[this.parent.taskFields.milestone] === false)) { tDuration = 1; } else { var startDate = isBaseline ? ganttProperties.baselineStartDate : ganttProperties.startDate; var endDate = isBaseline ? ganttProperties.baselineEndDate : ganttProperties.endDate; var durationUnit = ganttProperties.durationUnit; var isAutoSchedule = isBaseline ? false : ganttProperties.isAutoSchedule; var isMilestone = isBaseline ? false : ganttProperties.isMilestone; tDuration = this.getDuration(startDate, endDate, durationUnit, isAutoSchedule, isMilestone); } } var duration = isBaseline ? 'baselineDuration' : 'duration'; this.parent.setRecordValue(duration, tDuration, ganttProperties, true); var col = isBaseline ? this.parent.columnByField[this.parent.columnMapping.baselineDuration] : this.parent.columnByField[this.parent.columnMapping.duration]; if (!isNullOrUndefined(this.parent.editModule) && !isNullOrUndefined(this.parent.editModule.cellEditModule) && !this.parent.editModule.cellEditModule.isCellEdit && !isNullOrUndefined(col)) { if (!isNullOrUndefined(col.edit) && !isNullOrUndefined(col.edit.read)) { var dialog = this.parent.editModule.dialogModule.dialog; if (!isNullOrUndefined(dialog)) { var textBoxElement = isBaseline ? dialog.querySelector('#' + this.parent.element.id + 'BaselineDuration') : dialog.querySelector('#' + this.parent.element.id + 'Duration'); if (!isNullOrUndefined(textBoxElement)) { var textBox = textBoxElement.ej2_instances[0]; if (!isNullOrUndefined(textBox) && textBox.value !== tDuration.toString()) { textBox.value = tDuration.toString(); textBox.dataBind(); } } } } if (this.parent.taskFields.duration || this.parent.taskFields.baselineDuration) { this.parent.dataOperation.updateMappingData(ganttData, duration); if (this.parent.taskFields.durationUnit) { this.parent.dataOperation.updateMappingData(ganttData, 'durationUnit'); } } } }; /** * * @param {Date} sDate Method to get total nonworking time between two date values * @param {Date} eDate . * @param {boolean} isAutoSchedule . * @param {boolean} isCheckTimeZone . * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {number} . */ DateProcessor.prototype.getNonworkingTime = function (sDate, eDate, isAutoSchedule, isCheckTimeZone, isBaseline) { var parent = this.parent; isCheckTimeZone = isNullOrUndefined(isCheckTimeZone) ? true : isCheckTimeZone; var shouldCheckWeekend = (!isBaseline && !parent.includeWeekend && parent.autoCalculateDateScheduling && !(parent.isLoad && parent.treeGrid.loadChildOnDemand && parent.taskFields.hasChildMapping)) && isAutoSchedule; var weekendCount = shouldCheckWeekend ? this.getWeekendCount(sDate, eDate) : 0; var totalSeconds = this.getNumberOfSeconds(sDate, eDate, isCheckTimeZone); var shouldCheckHolidays = (isAutoSchedule && parent.autoCalculateDateScheduling && !(parent.isLoad && parent.treeGrid.loadChildOnDemand && parent.taskFields.hasChildMapping)) && !isBaseline; var holidaysCount = shouldCheckHolidays ? this.getHolidaysCount(sDate, eDate) : 0; var totalWorkDays = (totalSeconds - (weekendCount * 86400) - (holidaysCount * 86400)) / 86400; var nonWorkingSecondsOnDate = this.getNonWorkingSecondsOnDate(sDate, eDate, isAutoSchedule, isBaseline); var nonWorkingTime = parent.weekWorkingTime.length > 0 ? this.nonWorkingSeconds(sDate, eDate, isAutoSchedule, totalWorkDays) : (totalWorkDays * (86400 - parent.secondsPerDay)); return nonWorkingTime + (weekendCount * 86400) + (holidaysCount * 86400) + nonWorkingSecondsOnDate; }; DateProcessor.prototype.nonWorkingSeconds = function (sDate, eDate, isAutoSchedule, workDays, fromDuration) { var newStartDate = sDate.getTime() > eDate.getTime() ? new Date(eDate.getTime()) : new Date(sDate.getTime()); var newEndDate = sDate.getTime() > eDate.getTime() ? new Date(sDate.getTime()) : new Date(eDate.getTime()); var timeDiff = 0; var count = 0; if (fromDuration) { var dayStartTime = this.parent['getCurrentDayStartTime'](newStartDate); var dayEndTime = this.parent['getCurrentDayEndTime'](newStartDate); if (!(newStartDate.getHours() < dayEndTime / 3600 && newStartDate.getHours() >= dayStartTime / 3600)) { newStartDate.setDate(newStartDate.getDate() + 1); } } else { newStartDate.setDate(newStartDate.getDate() + 1); newStartDate.setHours(0, 0, 0, 0); newEndDate.setHours(0, 0, 0, 0); } if (workDays > 0 || isNullOrUndefined(workDays)) { while ((fromDuration && newStartDate.getTime() <= newEndDate.getTime()) || (!fromDuration && newStartDate.getTime() < newEndDate.getTime())) { if (isAutoSchedule) { if (this.isOnHolidayOrWeekEnd(newStartDate, true)) { do { newStartDate.setDate(newStartDate.getDate() + 1); } while (this.isOnHolidayOrWeekEnd(newStartDate, true)); } if (!this.parent.includeWeekend) { this.getNextWorkingDay(newStartDate); } } if (newStartDate.getTime() <= newEndDate.getTime()) { count++; var currentDaySeconds = this.parent['getSecondsPerDay'](newStartDate); if (fromDuration) { timeDiff += currentDaySeconds; } else { timeDiff += 86400 - currentDaySeconds; } newStartDate.setDate(newStartDate.getDate() + 1); if (isAutoSchedule) { if (this.isOnHolidayOrWeekEnd(newStartDate, true)) { do { newStartDate.setDate(newStartDate.getDate() + 1); } while (this.isOnHolidayOrWeekEnd(newStartDate, true)); } if (!this.parent.includeWeekend) { this.getNextWorkingDay(newStartDate); } } } } } else { return 0; } if (fromDuration) { if (timeDiff > 0) { timeDiff = timeDiff / count; } else { timeDiff = this.parent.secondsPerDay; } } return timeDiff; }; /** * * @param {Date} startDate . * @param {Date} endDate . * @param {string} durationUnit . * @param {boolean} isAutoSchedule . * @param {boolean} isMilestone . * @param {boolean} isCheckTimeZone . * @returns {number} . * @private */ DateProcessor.prototype.getDuration = function (startDate, endDate, durationUnit, isAutoSchedule, isMilestone, isCheckTimeZone) { if (isCheckTimeZone === void 0) { isCheckTimeZone = true; } if (!startDate || !endDate) { return null; } var durationValue = 0; var isSameDay = this.parent.getFormatedDate(startDate) === this.parent.getFormatedDate(endDate); var totSeconds; if (this.parent.weekWorkingTime.length > 0) { var tempStartDate = new Date(startDate); totSeconds = this.nonWorkingSeconds(startDate, endDate, isAutoSchedule, undefined, true); var totalDurationInDays = 0; while (tempStartDate <= endDate) { var currentDateString = this.parent.getFormatedDate(tempStartDate); var dayWorkingSeconds = this.parent['getSecondsPerDay'](tempStartDate); var currentStartDate = new Date(tempStartDate); var currentEndDate = new Date(tempStartDate); currentStartDate.setHours(0, 0, 0, 0); currentEndDate.setHours(0, 0, 0, 0); currentStartDate.setSeconds(this.parent['getCurrentDayStartTime'](tempStartDate)); currentEndDate.setSeconds(this.parent['getCurrentDayEndTime'](tempStartDate)); if (currentDateString === this.parent.getFormatedDate(startDate)) {