@syncfusion/ej2-gantt
Version:
Essential JS 2 Gantt Component
1,031 lines (1,028 loc) • 2.68 MB
JavaScript
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)) {
record.taskData[parent.taskFields.startDate] = parent.dateValidationModule.remove(record.ganttProperties.startDate, parent.timezone);
if (parent.taskFields.endDate !== null) {
record.taskData[parent.taskFields.endDate] = parent.dateValidationModule.remove(record.ganttProperties.endDate, parent.timezone);
}
if (parent.taskFields.baselineEndDate || parent.taskFields.baselineStartDate) {
record.taskData[parent.taskFields.baselineStartDate] = parent.dateValidationModule.remove(record.ganttProperties.baselineStartDate, parent.timezone);
record.taskData[parent.taskFields.baselineEndDate] = parent.dateValidationModule.remove(record.ganttProperties.baselineEndDate, parent.timezone);
}
}
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 .
* @param {boolean} validateAsMilestone .
* @param {boolean} isLoad .
* @returns {Date} .
* @private
*/
DateProcessor.prototype.checkStartDate = function (date, ganttProp, validateAsMilestone, isLoad) {
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) {
dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : tStartDate);
}
var startTime = (!validateAsMilestone || isLoad) ? dayStartTime : dayEndTime;
if (!this.parent.includeWeekend) {
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);
}
}
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.getDateByConstraint = function (ganttData, date, restrictConstraint, 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;
}
constraintDate = this.parent['assignTimeToDate'](constraintDate, this.parent['getCurrentDayStartTime'](constraintDate));
switch (ganttProp.constraintType) {
case ConstraintType.AsSoonAsPossible:
if (isLoad) {
return date;
}
else {
ganttProp.constraintDate = null;
var parentRecord = this.parent.getRecordByID(ganttProp.taskId).parentItem;
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 {
var parentRecord = this.parent.getRecordByID(ganttProp.taskId).parentItem;
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();
var endDate = new Date(constraintDate);
endDate.setDate(endDate.getDate() + 1);
var checkedEnd = this.parent.dateValidationModule.checkEndDate(endDate);
var start = this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp);
if (isViolation && !isLoad) {
this.parent.constraintViolationType = 'MustFinishOn';
}
if (restrictConstraint) {
return date;
}
return start;
}
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() !== ganttProp.startDate.getTime();
if (isViolation && !isLoad) {
this.parent.constraintViolationType = 'StartNoLaterThan';
}
if (!isLoad) {
return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date));
}
return (ganttProp.predecessor && ganttProp.predecessor.length > 0)
? date
: this.parent.dateValidationModule.checkStartDate(new Date(this.parent.projectStartDate));
}
case ConstraintType.FinishNoEarlierThan: {
if (constraintDate.getTime() < date.getTime()) {
return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayEndTime'](date));
}
else {
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);
}
}
case ConstraintType.FinishNoLaterThan: {
var isViolation = constraintDate.getTime() !== ganttProp.endDate.getTime();
if (isViolation && !isLoad) {
this.parent.constraintViolationType = 'FinishNoLaterThan';
}
if (!isLoad) {
return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayEndTime'](date));
}
return (ganttProp.predecessor && ganttProp.predecessor.length > 0)
? date
: this.parent.dateValidationModule.checkStartDate(new Date(this.parent.projectStartDate));
}
default:
return date;
}
};
/**
* To update given date value to valid end date
*
* @param {Date} date .
* @param {ITaskData} ganttProp .
* @param {boolean} validateAsMilestone .
* @returns {Date} .
* @private
*/
DateProcessor.prototype.checkEndDate = function (date, ganttProp, validateAsMilestone) {
if (isNullOrUndefined(date)) {
return null;
}
var dayStartTime;
var dayEndTime;
if (this.parent.weekWorkingTime.length > 0) {
var currentDay = date;
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(date);
}
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)) {
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.
* @returns {void} .
* @private
*/
DateProcessor.prototype.calculateStartDate = function (ganttData) {
var ganttProp = ganttData.ganttProperties;
var tempStartDate = null;
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');
}
};
/**
*
* @param {IGanttData} ganttData - Defines the gantt data.
* @returns {void} .
* @private
*/
DateProcessor.prototype.calculateEndDate = function (ganttData) {
var ganttProp = ganttData.ganttProperties;
var tempEndDate = null;
var dayStartTime;
var dayEndTime;
if (!isNullOrUndefined(ganttProp.startDate)) {
if (!isNullOrUndefined(ganttProp.endDate) && isNullOrUndefined(ganttProp.duration)) {
if (this.compareDates(ganttProp.startDate, ganttProp.endDate) === 1) {
this.parent.setRecordValue('startDate', new Date(ganttProp.endDate.getTime()), ganttProp, true);
dayStartTime = this.parent['getCurrentDayStartTime'](ganttProp.isAutoSchedule ? ganttProp.autoStartDate : ganttProp.startDate);
dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.isAutoSchedule ? ganttProp.autoEndDate : ganttProp.endDate);
this.setTime(dayStartTime, ganttProp.startDate);
}
this.calculateDuration(ganttData);
}
if (!isNullOrUndefined(ganttProp.duration)) {
var duration = !isNullOrUndefined(ganttProp.segments) && ganttProp.segments.length > 1 ?
this.totalDuration(ganttProp.segments) : ganttProp.duration;
tempEndDate = this.getEndDate(ganttProp.startDate, duration, ganttProp.durationUnit, ganttProp, false);
}
this.parent.setRecordValue('endDate', tempEndDate, ganttProp, true);
}
else {
tempEndDate = ganttData[this.parent.taskFields.endDate];
if (!isNullOrUndefined(tempEndDate)) {
dayEndTime = this.parent['getCurrentDayEndTime'](tempEndDate);
this.setTime(dayEndTime, tempEndDate);
}
this.parent.setRecordValue('endDate', tempEndDate, ganttProp, true);
}
if (this.parent.taskFields.endDate) {
this.parent.dataOperation.updateMappingData(ganttData, 'endDate');
}
};
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.
* @returns {void} .
*/
DateProcessor.prototype.calculateDuration = function (ganttData) {
var ganttProperties = ganttData.ganttProperties;
var tDuration;
if (!isNullOrUndefined(ganttProperties.segments) && ganttProperties.segments.length > 0 &&
!isNullOrUndefined(this.parent.editModule.taskbarEditModule)) {
tDuration = this.parent.editModule.taskbarEditModule.sumOfDuration(ganttProperties.segments);
}
else {
if ((!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 {
tDuration = this.getDuration(ganttProperties.startDate, ganttProperties.endDate, ganttProperties.durationUnit, ganttProperties.isAutoSchedule, ganttProperties.isMilestone);
}
}
this.parent.setRecordValue('duration', tDuration, ganttProperties, true);
var col = 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 textBox = dialog.querySelector('#' + this.parent.element.id + 'Duration')
.ej2_instances[0];
if (!isNullOrUndefined(textBox) && textBox.value !== tDuration.toString()) {
textBox.value = tDuration.toString();
textBox.dataBind();
}
}
}
if (this.parent.taskFields.duration) {
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 .
* @returns {number} .
*/
DateProcessor.prototype.getNonworkingTime = function (sDate, eDate, isAutoSchedule, isCheckTimeZone) {
isCheckTimeZone = isNullOrUndefined(isCheckTimeZone) ? true : isCheckTimeZone;
var weekendCount = (!this.parent.includeWeekend && this.parent.autoCalculateDateScheduling && !(this.parent.isLoad &&
this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) && isAutoSchedule ?
this.getWeekendCount(sDate, eDate) : 0;
var totalHours = this.getNumberOfSeconds(sDate, eDate, isCheckTimeZone);
var holidaysCount = (isAutoSchedule && this.parent.autoCalculateDateScheduling &&
!(this.parent.isLoad && this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) ? this.getHolidaysCount(sDate, eDate) : 0;
var totWorkDays = (totalHours - (weekendCount * 86400) - (holidaysCount * 86400)) / 86400; // working days between two dates
var nonWorkHours = this.getNonWorkingSecondsOnDate(sDate, eDate, isAutoSchedule);
var totalNonWorkTime = (this.parent.weekWorkingTime.length > 0 ?
this.nonWorkingSeconds(sDate, eDate, isAutoSchedule, totWorkDays) : (totWorkDays * (86400 - this.parent.secondsPerDay))) +
(weekendCount * 86400) + (holidaysCount * 86400) + nonWorkHours;
return totalNonWorkTime;
};
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)) {
currentStartDate.setTime(startDate.getTime());
}
if (currentDateString === this.parent.getFormatedDate(endDate)) {
currentEndDate.setTime(endDate.getTime());
}
var timeDiffSeconds = this.getTimeDifference(currentStartDate, currentEndDate, isCheckTimeZone) / 1000;
var nonWorkSeconds = this.getNonworkingTime(currentStartDate, currentEndDate, isAutoSchedule, isCheckTimeZone);
totalDurationInDays += Math.max(0, timeDiffSeconds - nonWorkSeconds) / dayWorkingSeconds;
tempStartDate.setDate(tempStartDate.getDate() + 1);
}
if (!(isMilestone && isSameDay)) {
durationValue = this.calculateDurationValue(durationUnit, totalDurationInDays, totSeconds);
}
}
else {
totSeconds = this.parent.secondsPerDay;
var timeDiff = this.getTimeDifference(startDate, endDate, isCheckTimeZone) / 1000;
var nonWorkHours = this.getNonworkingTime(startDate, endDate, isAutoSchedule, isCheckTimeZone);
var durationHours = timeDiff - nonWorkHours;
if (!(isMilestone && isSameDay)) {
durationValue = this.calculateDurationValue(durationUnit, durationHours / totSeconds, totSeconds);
}
}
return parseFloat(durationValue.toString());
};
DateProcessor.prototype.calculateDurationValue = function (durationUnit, duration, totSeconds) {
if (!durationUnit || durationUnit === 'day') {
return duration;
}
else if (durationUnit === 'minute') {
return duration * (totSeconds / 60);
}
else {
return duration * (totSeconds / 3600);
}
};
/**
*
* @param {number} duration .
* @param {string} durationUnit .
* @param {Date} date .
* @returns {number} .
*/
DateProcessor.prototype.getDurationAsSeconds = function (duration, durationUnit, date) {
var value = 0;
var totSeconds;
if (this.parent.weekWorkingTime.length > 0) {
totSeconds = this.parent['getSecondsPerDay'](date);
}
else {
totSeconds = this.parent.secondsPerDay;
}
if (!durationUnit || durationUnit.toLocaleLowerCase() === 'day') {
value = totSeconds * duration;
}
else if (durationUnit.toLocaleLowerCase() === 'hour') {
value = duration * 3600;
}
else {
value = duration * 60;
}
return value;
};
/**
* To get date from start date and duration
*
* @param {Date} startDate .
* @param {number} duration .
* @param {string} durationUnit .
* @param {ITaskData} ganttProp .
* @param {boolean} validateAsMilestone .
* @returns {Date} .
* @private
*/
DateProcessor.prototype.getEndDate = function (startDate, duration, durationUnit, ganttProp, validateAsMilestone) {
var tempStart = new Date(startDate.getTime());
var endDate = new Date(startDate.getTime());
var sDate = new Date(startDate.getTime());
var secondDuration;
if (this.parent.weekWorkingTime.length > 0 && (!durationUnit || durationUnit.toLocaleLowerCase() === 'day')) {
secondDuration = this.calculateSecondDuration(duration, sDate, secondDuration, startDate, true);
}
else {
secondDuration = this.getDurationAsSeconds(duration, durationUnit, startDate);
}
var nonWork = 0;
var workHours = 0;
while (secondDuration > 0) {
endDate.setSeconds(endDate.getSeconds() + secondDuration);
nonWork = this.getNonworkingTime(tempStart, endDate, ganttProp.isAutoSchedule, true);
workHours = secondDuration - nonWork;
secondDuration = secondDuration - workHours;
if (secondDuration > 0) {
endDate = this.checkStartDate(endDate, ganttProp, validateAsMilestone);
}
tempStart = new Date(endDate.getTime());
}
return endDate;
};
/**
* Calculate start date based on end date and duration.
*
* @param {Date} endDate - To calculate start date value from end date and duration.
* @param {number} duration - The duration value.
* @param {string} durationUnit - The unit of duration.
* @param {ITaskData} ganttProp - The Gantt task properties.
* @param {boolean} fromValidation - A flag indicating if the calculation is from validation.
* @returns {Date} The calculated start date.
* @private
*/
DateProcessor.prototype.getStartDate = function (endDate, duration, durationUnit, ganttProp, fromValidation) {
var tempEnd = new Date(endDate.getTime());
var startDate = new Date(endDate.getTime());
var secondDuration;
var eDate = new Date(tempEnd.getTime());
if (this.parent.weekWorkingTime.length > 0) {
secondDuration = this.calculateSecondDuration(duration, eDate, secondDuration, tempEnd, false);
}
else {
secondDuration = this.getDurationAsSeconds(dur