@syncfusion/ej2-gantt 19.4.55 → 20.1.47-1460716
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1072 -1047
- package/README.md +75 -75
- package/dist/ej2-gantt.umd.min.js +1 -10
- package/dist/ej2-gantt.umd.min.js.map +1 -1
- package/dist/es6/ej2-gantt.es2015.js +341 -240
- package/dist/es6/ej2-gantt.es2015.js.map +1 -1
- package/dist/es6/ej2-gantt.es5.js +713 -598
- package/dist/es6/ej2-gantt.es5.js.map +1 -1
- package/dist/global/ej2-gantt.min.js +1 -10
- package/dist/global/ej2-gantt.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/components.ts +4 -0
- package/dist/ts/gantt/actions/actions.ts +18 -0
- package/dist/ts/gantt/actions/cell-edit.ts +606 -0
- package/dist/ts/gantt/actions/chart-scroll.ts +167 -0
- package/dist/ts/gantt/actions/column-menu.ts +35 -0
- package/dist/ts/gantt/actions/column-reorder.ts +52 -0
- package/dist/ts/gantt/actions/column-resize.ts +52 -0
- package/dist/ts/gantt/actions/connector-line-edit.ts +829 -0
- package/dist/ts/gantt/actions/context-menu.ts +754 -0
- package/dist/ts/gantt/actions/day-markers.ts +80 -0
- package/dist/ts/gantt/actions/dependency.ts +692 -0
- package/dist/ts/gantt/actions/dialog-edit.ts +2208 -0
- package/dist/ts/gantt/actions/edit.ts +3499 -0
- package/dist/ts/gantt/actions/excel-export.ts +61 -0
- package/dist/ts/gantt/actions/filter.ts +302 -0
- package/dist/ts/gantt/actions/keyboard.ts +306 -0
- package/dist/ts/gantt/actions/pdf-export.ts +214 -0
- package/dist/ts/gantt/actions/rowdragdrop.ts +839 -0
- package/dist/ts/gantt/actions/selection.ts +536 -0
- package/dist/ts/gantt/actions/sort.ts +98 -0
- package/dist/ts/gantt/actions/taskbar-edit.ts +1940 -0
- package/dist/ts/gantt/actions/toolbar.ts +489 -0
- package/dist/ts/gantt/actions/virtual-scroll.ts +60 -0
- package/dist/ts/gantt/base/common.ts +9 -0
- package/dist/ts/gantt/base/constant.ts +13 -0
- package/dist/ts/gantt/base/css-constants.ts +148 -0
- package/dist/ts/gantt/base/date-processor.ts +1257 -0
- package/dist/ts/gantt/base/enum.ts +372 -0
- package/dist/ts/gantt/base/gantt-chart.ts +1248 -0
- package/dist/ts/gantt/base/gantt.ts +4069 -0
- package/dist/ts/gantt/base/interface.ts +955 -0
- package/dist/ts/gantt/base/splitter.ts +174 -0
- package/dist/ts/gantt/base/task-processor.ts +2217 -0
- package/dist/ts/gantt/base/tree-grid.ts +694 -0
- package/dist/ts/gantt/base/utils.ts +208 -0
- package/dist/ts/gantt/export/export-helper.ts +552 -0
- package/dist/ts/gantt/export/pdf-base/dictionary.ts +152 -0
- package/dist/ts/gantt/export/pdf-base/pdf-borders.ts +277 -0
- package/dist/ts/gantt/export/pdf-base/pdf-grid-table.ts +901 -0
- package/dist/ts/gantt/export/pdf-base/pdf-style/gantt-theme.ts +131 -0
- package/dist/ts/gantt/export/pdf-base/pdf-style/style.ts +91 -0
- package/dist/ts/gantt/export/pdf-base/treegrid-layouter.ts +414 -0
- package/dist/ts/gantt/export/pdf-connector-line.ts +422 -0
- package/dist/ts/gantt/export/pdf-gantt.ts +282 -0
- package/dist/ts/gantt/export/pdf-taskbar.ts +395 -0
- package/dist/ts/gantt/export/pdf-timeline.ts +202 -0
- package/dist/ts/gantt/export/pdf-treegrid.ts +406 -0
- package/dist/ts/gantt/models/add-dialog-field-settings.ts +33 -0
- package/dist/ts/gantt/models/column.ts +464 -0
- package/dist/ts/gantt/models/day-working-time.ts +22 -0
- package/dist/ts/gantt/models/edit-dialog-field-settings.ts +33 -0
- package/dist/ts/gantt/models/edit-settings.ts +79 -0
- package/dist/ts/gantt/models/event-marker.ts +27 -0
- package/dist/ts/gantt/models/filter-settings.ts +53 -0
- package/dist/ts/gantt/models/holiday.ts +34 -0
- package/dist/ts/gantt/models/label-settings.ts +30 -0
- package/dist/ts/gantt/models/models.ts +36 -0
- package/dist/ts/gantt/models/resource-fields.ts +38 -0
- package/dist/ts/gantt/models/search-settings.ts +77 -0
- package/dist/ts/gantt/models/selection-settings.ts +56 -0
- package/dist/ts/gantt/models/sort-settings.ts +50 -0
- package/dist/ts/gantt/models/splitter-settings.ts +47 -0
- package/dist/ts/gantt/models/task-fields.ts +171 -0
- package/dist/ts/gantt/models/timeline-settings.ts +112 -0
- package/dist/ts/gantt/models/tooltip-settings.ts +46 -0
- package/dist/ts/gantt/renderer/chart-rows.ts +1838 -0
- package/dist/ts/gantt/renderer/connector-line.ts +1025 -0
- package/dist/ts/gantt/renderer/edit-tooltip.ts +228 -0
- package/dist/ts/gantt/renderer/event-marker.ts +96 -0
- package/dist/ts/gantt/renderer/nonworking-day.ts +205 -0
- package/dist/ts/gantt/renderer/render.ts +5 -0
- package/dist/ts/gantt/renderer/timeline.ts +1397 -0
- package/dist/ts/gantt/renderer/tooltip.ts +450 -0
- package/dist/ts/gantt/renderer/virtual-content-render.ts +50 -0
- package/license +9 -9
- package/package.json +80 -80
- package/src/gantt/actions/cell-edit.js +2 -1
- package/src/gantt/actions/dialog-edit.js +2 -1
- package/src/gantt/actions/edit.js +36 -9
- package/src/gantt/actions/rowdragdrop.js +37 -15
- package/src/gantt/actions/selection.js +3 -2
- package/src/gantt/actions/taskbar-edit.js +24 -24
- package/src/gantt/base/date-processor.js +0 -1
- package/src/gantt/base/gantt-chart.js +36 -5
- package/src/gantt/base/gantt-model.d.ts +779 -779
- package/src/gantt/base/gantt.d.ts +27 -27
- package/src/gantt/base/gantt.js +35 -76
- package/src/gantt/base/splitter.js +1 -0
- package/src/gantt/base/task-processor.js +13 -13
- package/src/gantt/base/tree-grid.js +3 -1
- package/src/gantt/export/pdf-base/treegrid-layouter.js +13 -13
- package/src/gantt/export/pdf-connector-line.js +11 -11
- package/src/gantt/export/pdf-gantt.js +24 -24
- package/src/gantt/export/pdf-taskbar.js +11 -11
- package/src/gantt/export/pdf-treegrid.js +13 -13
- package/src/gantt/models/add-dialog-field-settings-model.d.ts +21 -21
- package/src/gantt/models/add-dialog-field-settings.js +19 -19
- package/src/gantt/models/day-working-time-model.d.ts +11 -11
- package/src/gantt/models/day-working-time.js +19 -19
- package/src/gantt/models/edit-dialog-field-settings-model.d.ts +21 -21
- package/src/gantt/models/edit-dialog-field-settings.js +19 -19
- package/src/gantt/models/edit-settings-model.d.ts +50 -50
- package/src/gantt/models/edit-settings.js +19 -19
- package/src/gantt/models/event-marker-model.d.ts +16 -16
- package/src/gantt/models/event-marker.js +19 -19
- package/src/gantt/models/filter-settings-model.d.ts +34 -34
- package/src/gantt/models/filter-settings.js +19 -19
- package/src/gantt/models/holiday-model.d.ts +21 -21
- package/src/gantt/models/holiday.js +19 -19
- package/src/gantt/models/label-settings-model.d.ts +16 -16
- package/src/gantt/models/label-settings.js +19 -19
- package/src/gantt/models/resource-fields-model.d.ts +21 -21
- package/src/gantt/models/resource-fields.js +19 -19
- package/src/gantt/models/search-settings-model.d.ts +56 -56
- package/src/gantt/models/search-settings.js +19 -19
- package/src/gantt/models/selection-settings-model.d.ts +35 -35
- package/src/gantt/models/selection-settings.js +19 -19
- package/src/gantt/models/sort-settings-model.d.ts +24 -24
- package/src/gantt/models/sort-settings.js +19 -19
- package/src/gantt/models/splitter-settings-model.d.ts +30 -30
- package/src/gantt/models/splitter-settings.js +19 -19
- package/src/gantt/models/task-fields-model.d.ts +110 -110
- package/src/gantt/models/task-fields.js +19 -19
- package/src/gantt/models/timeline-settings-model.d.ts +71 -71
- package/src/gantt/models/timeline-settings.js +19 -19
- package/src/gantt/models/tooltip-settings-model.d.ts +26 -26
- package/src/gantt/models/tooltip-settings.js +19 -19
- package/src/gantt/renderer/chart-rows.js +49 -37
- package/src/gantt/renderer/connector-line.js +22 -18
- package/src/gantt/renderer/event-marker.js +1 -0
- package/src/gantt/renderer/nonworking-day.js +13 -6
- package/src/gantt/renderer/timeline.d.ts +1 -0
- package/src/gantt/renderer/timeline.js +51 -12
- package/src/gantt/renderer/tooltip.js +11 -3
- package/styles/bootstrap-dark.css +442 -427
- package/styles/bootstrap.css +442 -433
- package/styles/bootstrap4.css +454 -479
- package/styles/bootstrap5-dark.css +457 -433
- package/styles/bootstrap5.css +457 -433
- package/styles/fabric-dark.css +438 -421
- package/styles/fabric.css +445 -428
- package/styles/fluent-dark.css +1938 -0
- package/styles/fluent-dark.scss +1 -0
- package/styles/fluent.css +1938 -0
- package/styles/fluent.scss +1 -0
- package/styles/gantt/_all.scss +2 -2
- package/styles/gantt/_bootstrap-dark-definition.scss +210 -156
- package/styles/gantt/_bootstrap-definition.scss +211 -157
- package/styles/gantt/_bootstrap4-definition.scss +213 -158
- package/styles/gantt/_bootstrap5-definition.scss +215 -162
- package/styles/gantt/_fabric-dark-definition.scss +211 -157
- package/styles/gantt/_fabric-definition.scss +211 -157
- package/styles/gantt/_fluent-dark-definition.scss +1 -0
- package/styles/gantt/_fluent-definition.scss +215 -162
- package/styles/gantt/_fusionnew-definition.scss +214 -0
- package/styles/gantt/_highcontrast-definition.scss +211 -157
- package/styles/gantt/_highcontrast-light-definition.scss +211 -157
- package/styles/gantt/_layout.scss +1446 -1027
- package/styles/gantt/_material-dark-definition.scss +212 -157
- package/styles/gantt/_material-definition.scss +212 -157
- package/styles/gantt/_material3-definition.scss +215 -0
- package/styles/gantt/_tailwind-definition.scss +215 -161
- package/styles/gantt/_theme.scss +702 -668
- package/styles/gantt/bootstrap-dark.css +442 -427
- package/styles/gantt/bootstrap.css +442 -433
- package/styles/gantt/bootstrap4.css +454 -479
- package/styles/gantt/bootstrap5-dark.css +457 -433
- package/styles/gantt/bootstrap5.css +457 -433
- package/styles/gantt/fabric-dark.css +438 -421
- package/styles/gantt/fabric.css +445 -428
- package/styles/gantt/fluent-dark.css +1938 -0
- package/styles/gantt/fluent-dark.scss +22 -0
- package/styles/gantt/fluent.css +1938 -0
- package/styles/gantt/fluent.scss +22 -0
- package/styles/gantt/highcontrast-light.css +405 -405
- package/styles/gantt/highcontrast.css +444 -456
- package/styles/gantt/icons/_bootstrap-dark.scss +124 -113
- package/styles/gantt/icons/_bootstrap.scss +124 -113
- package/styles/gantt/icons/_bootstrap4.scss +124 -113
- package/styles/gantt/icons/_bootstrap5.scss +124 -112
- package/styles/gantt/icons/_fabric-dark.scss +124 -112
- package/styles/gantt/icons/_fabric.scss +124 -112
- package/styles/gantt/icons/_fluent-dark.scss +1 -0
- package/styles/gantt/icons/_fluent.scss +124 -112
- package/styles/gantt/icons/_fusionnew.scss +120 -0
- package/styles/gantt/icons/_highcontrast.scss +124 -112
- package/styles/gantt/icons/_material-dark.scss +124 -112
- package/styles/gantt/icons/_material.scss +124 -112
- package/styles/gantt/icons/_material3.scss +124 -0
- package/styles/gantt/icons/_tailwind-dark.scss +124 -113
- package/styles/gantt/icons/_tailwind.scss +124 -113
- package/styles/gantt/material-dark.css +446 -417
- package/styles/gantt/material.css +445 -419
- package/styles/gantt/tailwind-dark.css +452 -482
- package/styles/gantt/tailwind.css +449 -479
- package/styles/highcontrast-light.css +405 -405
- package/styles/highcontrast.css +444 -456
- package/styles/material-dark.css +446 -417
- package/styles/material.css +445 -419
- package/styles/tailwind-dark.css +452 -482
- package/styles/tailwind.css +449 -479
|
@@ -0,0 +1,829 @@
|
|
|
1
|
+
import { isNullOrUndefined, isUndefined, addClass} from '@syncfusion/ej2-base';
|
|
2
|
+
import { removeClass, getValue, createElement, extend } from '@syncfusion/ej2-base';
|
|
3
|
+
import { Gantt } from '../base/gantt';
|
|
4
|
+
import * as cls from '../base/css-constants';
|
|
5
|
+
import { parentsUntil, formatString, isScheduledTask, getIndex } from '../base/utils';
|
|
6
|
+
import { IGanttData, IPredecessor, IConnectorLineObject, ITaskData, ITaskbarEditedEventArgs, IValidateArgs } from '../base/interface';
|
|
7
|
+
import { Dialog } from '@syncfusion/ej2-popups';
|
|
8
|
+
import { DateProcessor } from '../base/date-processor';
|
|
9
|
+
/**
|
|
10
|
+
* File for handling connector line edit operation in Gantt.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export class ConnectorLineEdit {
|
|
14
|
+
private parent: Gantt;
|
|
15
|
+
private connectorLineElement: Element;
|
|
16
|
+
/**
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
public validationPredecessor: IPredecessor[] = null;
|
|
20
|
+
/** @private */
|
|
21
|
+
public confirmPredecessorDialog: Dialog = null;
|
|
22
|
+
/** @private */
|
|
23
|
+
public predecessorIndex: number = null;
|
|
24
|
+
/** @private */
|
|
25
|
+
public childRecord: IGanttData = null;
|
|
26
|
+
private dateValidateModule: DateProcessor;
|
|
27
|
+
constructor(ganttObj?: Gantt) {
|
|
28
|
+
this.parent = ganttObj;
|
|
29
|
+
this.dateValidateModule = this.parent.dateValidationModule;
|
|
30
|
+
this.parent.on('initPredessorDialog', this.initPredecessorValidationDialog, this);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* To update connector line edit element.
|
|
35
|
+
*
|
|
36
|
+
* @param {PointerEvent} e .
|
|
37
|
+
* @returns {void} .
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
public updateConnectorLineEditElement(e: PointerEvent): void {
|
|
41
|
+
const element: Element = this.getConnectorLineHoverElement(e.target);
|
|
42
|
+
if (!getValue('editModule.taskbarEditModule.taskBarEditAction', this.parent)) {
|
|
43
|
+
this.highlightConnectorLineElements(element);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* To get hovered connector line element.
|
|
49
|
+
*
|
|
50
|
+
* @param {EventTarget} target .
|
|
51
|
+
* @returns {void} .
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
private getConnectorLineHoverElement(target: EventTarget): Element {
|
|
55
|
+
const isOnLine: Element = parentsUntil(target as Element, cls.connectorLine);
|
|
56
|
+
const isOnRightArrow: Element = parentsUntil(target as Element, cls.connectorLineRightArrow);
|
|
57
|
+
const isOnLeftArrow: Element = parentsUntil(target as Element, cls.connectorLineLeftArrow);
|
|
58
|
+
if (isOnLine || isOnRightArrow || isOnLeftArrow) {
|
|
59
|
+
return parentsUntil(target as Element, cls.connectorLineContainer);
|
|
60
|
+
} else {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* To highlight connector line while hover.
|
|
67
|
+
*
|
|
68
|
+
* @param {Element} element .
|
|
69
|
+
* @returns {void} .
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
private highlightConnectorLineElements(element: Element): void {
|
|
73
|
+
if (element) {
|
|
74
|
+
if (element !== this.connectorLineElement) {
|
|
75
|
+
this.removeHighlight();
|
|
76
|
+
this.addHighlight(element);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
this.removeHighlight();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* To add connector line highlight class.
|
|
85
|
+
*
|
|
86
|
+
* @param {Element} element .
|
|
87
|
+
* @returns {void} .
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
private addHighlight(element: Element): void {
|
|
91
|
+
this.connectorLineElement = element;
|
|
92
|
+
addClass([element], [cls.connectorLineHoverZIndex]);
|
|
93
|
+
addClass(element.querySelectorAll('.' + cls.connectorLine), [cls.connectorLineHover]);
|
|
94
|
+
addClass(element.querySelectorAll('.' + cls.connectorLineRightArrow), [cls.connectorLineRightArrowHover]);
|
|
95
|
+
addClass(element.querySelectorAll('.' + cls.connectorLineLeftArrow), [cls.connectorLineLeftArrowHover]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* To remove connector line highlight class.
|
|
100
|
+
*
|
|
101
|
+
* @returns {void} .
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
private removeHighlight(): void {
|
|
105
|
+
if (!isNullOrUndefined(this.connectorLineElement)) {
|
|
106
|
+
removeClass([this.connectorLineElement], [cls.connectorLineHoverZIndex]);
|
|
107
|
+
removeClass(this.connectorLineElement.querySelectorAll('.' + cls.connectorLine), [cls.connectorLineHover]);
|
|
108
|
+
removeClass(this.connectorLineElement.querySelectorAll('.' + cls.connectorLineRightArrow), [cls.connectorLineRightArrowHover]);
|
|
109
|
+
removeClass(this.connectorLineElement.querySelectorAll('.' + cls.connectorLineLeftArrow), [cls.connectorLineLeftArrowHover]);
|
|
110
|
+
this.connectorLineElement = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* To remove connector line highlight class.
|
|
116
|
+
*
|
|
117
|
+
* @param {IGanttData[]} records .
|
|
118
|
+
* @returns {string} .
|
|
119
|
+
* @private
|
|
120
|
+
*/
|
|
121
|
+
public getEditedConnectorLineString(records: IGanttData[]): string {
|
|
122
|
+
let ganttRecord: IGanttData;
|
|
123
|
+
let predecessorsCollection: IPredecessor[];
|
|
124
|
+
let predecessor: IPredecessor;
|
|
125
|
+
let parentGanttRecord: IGanttData;
|
|
126
|
+
let childGanttRecord: IGanttData;
|
|
127
|
+
let connectorObj: IConnectorLineObject;
|
|
128
|
+
const idArray: string[] = [];
|
|
129
|
+
const lineArray: string[] = [];
|
|
130
|
+
let editedConnectorLineString: string = '';
|
|
131
|
+
for (let count: number = 0; count < records.length; count++) {
|
|
132
|
+
ganttRecord = records[count];
|
|
133
|
+
predecessorsCollection = ganttRecord.ganttProperties.predecessor;
|
|
134
|
+
if (predecessorsCollection) {
|
|
135
|
+
for (let predecessorCount: number = 0; predecessorCount < predecessorsCollection.length; predecessorCount++) {
|
|
136
|
+
predecessor = predecessorsCollection[predecessorCount];
|
|
137
|
+
const from: string = 'from'; const to: string = 'to';
|
|
138
|
+
this.parent.connectorLineModule.removeConnectorLineById('parent' + predecessor[from] + 'child' + predecessor[to]);
|
|
139
|
+
parentGanttRecord = this.parent.connectorLineModule.getRecordByID(predecessor[from]);
|
|
140
|
+
childGanttRecord = this.parent.connectorLineModule.getRecordByID(predecessor[to]);
|
|
141
|
+
if ((parentGanttRecord && parentGanttRecord.expanded === true) ||
|
|
142
|
+
(childGanttRecord && childGanttRecord.expanded === true)) {
|
|
143
|
+
connectorObj =
|
|
144
|
+
this.parent.predecessorModule.updateConnectorLineObject(parentGanttRecord, childGanttRecord, predecessor);
|
|
145
|
+
if (!isNullOrUndefined(connectorObj)) {
|
|
146
|
+
const lineIndex: number = idArray.indexOf(connectorObj.connectorLineId);
|
|
147
|
+
const lineString: string = this.parent.connectorLineModule.getConnectorLineTemplate(connectorObj);
|
|
148
|
+
if (lineIndex !== -1) {
|
|
149
|
+
lineArray[lineIndex] = lineString;
|
|
150
|
+
} else {
|
|
151
|
+
idArray.push(connectorObj.connectorLineId);
|
|
152
|
+
lineArray.push(lineString);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
editedConnectorLineString = lineArray.join('');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return editedConnectorLineString;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Tp refresh connector lines of edited records
|
|
164
|
+
*
|
|
165
|
+
* @param {IGanttData[]} editedRecord .
|
|
166
|
+
* @returns {void} .
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
169
|
+
public refreshEditedRecordConnectorLine(editedRecord: IGanttData[]): void {
|
|
170
|
+
this.parent.connectorLineModule.removePreviousConnectorLines(this.parent.previousRecords);
|
|
171
|
+
this.parent.connectorLineModule.expandedRecords = this.parent.virtualScrollModule && this.parent.enableVirtualization ?
|
|
172
|
+
this.parent.updatedRecords : this.parent.getExpandedRecords(this.parent.updatedRecords);
|
|
173
|
+
const editedConnectorLineString: string = this.getEditedConnectorLineString(editedRecord);
|
|
174
|
+
this.parent.connectorLineModule.dependencyViewContainer.innerHTML =
|
|
175
|
+
this.parent.connectorLineModule.dependencyViewContainer.innerHTML + editedConnectorLineString;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private idFromPredecessor(pre: string): string[] {
|
|
179
|
+
const preArray: string[] = pre.split(',');
|
|
180
|
+
const preIdArray: string[] = [];
|
|
181
|
+
for (let j: number = 0; j < preArray.length; j++) {
|
|
182
|
+
const strArray: string[] = [];
|
|
183
|
+
for (let i: number = 0; i < preArray[j].length; i++) {
|
|
184
|
+
if (!isNullOrUndefined(preArray[j].charAt(i)) && parseInt(preArray[j].charAt(i), 10).toString() !== 'NaN') {
|
|
185
|
+
strArray.push(preArray[j].charAt(i));
|
|
186
|
+
} else {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
preIdArray.push((strArray.join('')));
|
|
191
|
+
}
|
|
192
|
+
return preIdArray;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private predecessorValidation(predecessor: string[], record: ITaskData): boolean {
|
|
196
|
+
|
|
197
|
+
const recordId: string = record.rowUniqueID;
|
|
198
|
+
let currentId: string;
|
|
199
|
+
let currentRecord: ITaskData;
|
|
200
|
+
for (let count: number = 0; count < predecessor.length; count++) {
|
|
201
|
+
currentId = predecessor[count];
|
|
202
|
+
const visitedIdArray: string[] = [];
|
|
203
|
+
const predecessorCollection: string[] = predecessor.slice(0);
|
|
204
|
+
predecessorCollection.splice(count, 1);
|
|
205
|
+
|
|
206
|
+
while (currentId !== null) {
|
|
207
|
+
const currentIdArray: string[] = [];
|
|
208
|
+
if (visitedIdArray.indexOf(currentId) === -1) {
|
|
209
|
+
//Predecessor id not in records collection
|
|
210
|
+
if (isNullOrUndefined(this.parent.connectorLineModule.getRecordByID(currentId))) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
currentRecord = this.parent.connectorLineModule.getRecordByID(currentId).ganttProperties;
|
|
214
|
+
|
|
215
|
+
if (!isNullOrUndefined(currentRecord.predecessor) && currentRecord.predecessor.length > 0) {
|
|
216
|
+
currentRecord.predecessor.forEach((value: IPredecessor) => {
|
|
217
|
+
if (currentRecord.rowUniqueID.toString() !== value.from) {
|
|
218
|
+
currentIdArray.push(value.from.toString());
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/* eslint-disable-next-line */
|
|
223
|
+
if (recordId.toString() === currentRecord.rowUniqueID.toString() || currentIdArray.indexOf(recordId.toString()) !== -1) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
visitedIdArray.push(currentId);
|
|
227
|
+
if (!isNullOrUndefined(currentRecord.predecessor) && currentRecord.predecessor.length > 0) {
|
|
228
|
+
currentId = currentRecord.predecessor[0].from;
|
|
229
|
+
} else {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* To validate predecessor relations
|
|
242
|
+
*
|
|
243
|
+
* @param {IGanttData} ganttRecord .
|
|
244
|
+
* @param {string} predecessorString .
|
|
245
|
+
* @returns {boolean} .
|
|
246
|
+
* @private
|
|
247
|
+
*/
|
|
248
|
+
public validatePredecessorRelation(ganttRecord: IGanttData, predecessorString: string): boolean {
|
|
249
|
+
const flag: boolean = true;
|
|
250
|
+
const recordId: string = this.parent.viewType === 'ResourceView' ? ganttRecord.ganttProperties.taskId
|
|
251
|
+
: ganttRecord.ganttProperties.rowUniqueID;
|
|
252
|
+
let predecessorIdArray: string[];
|
|
253
|
+
let currentId: string;
|
|
254
|
+
if (!isNullOrUndefined(predecessorString) && predecessorString.length > 0) {
|
|
255
|
+
predecessorIdArray = this.idFromPredecessor(predecessorString);
|
|
256
|
+
for (let count: number = 0; count < predecessorIdArray.length; count++) {
|
|
257
|
+
//Check edited item has parent item in predecessor collection
|
|
258
|
+
const checkParent: boolean = this.checkParentRelation(ganttRecord, predecessorIdArray);
|
|
259
|
+
if (!checkParent) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
// Check if predecessor exist more then one
|
|
263
|
+
const tempIdArray: string[] = predecessorIdArray.slice(0);
|
|
264
|
+
const checkArray: string[] = [];
|
|
265
|
+
let countFlag: boolean = true;
|
|
266
|
+
tempIdArray.forEach((value: string) => {
|
|
267
|
+
if (checkArray.indexOf(value) === -1) {
|
|
268
|
+
checkArray.push(value);
|
|
269
|
+
} else {
|
|
270
|
+
countFlag = false;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
if (!countFlag) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
//Cyclick check
|
|
277
|
+
currentId = predecessorIdArray[count];
|
|
278
|
+
const visitedIdArray: string[] = [];
|
|
279
|
+
const predecessorCollection: string[] = predecessorIdArray.slice(0);
|
|
280
|
+
predecessorCollection.splice(count, 1);
|
|
281
|
+
|
|
282
|
+
while (currentId !== null) {
|
|
283
|
+
const currentIdArray: string[] = [];
|
|
284
|
+
let currentIdIndex: number;
|
|
285
|
+
let currentRecord: ITaskData;
|
|
286
|
+
if (visitedIdArray.indexOf(currentId) === -1) {
|
|
287
|
+
//Predecessor id not in records collection
|
|
288
|
+
if (isNullOrUndefined(this.parent.connectorLineModule.getRecordByID(currentId.toString()))) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
currentRecord = this.parent.connectorLineModule.getRecordByID(currentId.toString()).ganttProperties;
|
|
292
|
+
// let currentPredecessor='';
|
|
293
|
+
if (!isNullOrUndefined(currentRecord.predecessor) && currentRecord.predecessor.length > 0) {
|
|
294
|
+
currentRecord.predecessor.forEach((value: IPredecessor, index: number) => {
|
|
295
|
+
if (currentRecord.rowUniqueID.toString() !== value.from) {
|
|
296
|
+
currentIdArray.push(value.from.toString());
|
|
297
|
+
currentIdIndex = index;
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
// currentPredecessor=currentRecord.predecessor[0].from
|
|
301
|
+
}
|
|
302
|
+
if (recordId.toString() === currentRecord.rowUniqueID.toString() ||
|
|
303
|
+
currentIdArray.indexOf(recordId.toString()) !== -1) {
|
|
304
|
+
//cycylic occurs//break;
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
visitedIdArray.push(currentId);
|
|
308
|
+
if (!isNullOrUndefined(currentRecord.predecessor) && currentRecord.predecessor.length > 0) {
|
|
309
|
+
let result: boolean;
|
|
310
|
+
if (currentIdArray.length > 1) {
|
|
311
|
+
result = this.predecessorValidation(currentIdArray, ganttRecord.ganttProperties);
|
|
312
|
+
} else if (currentIdArray.length === 1) {
|
|
313
|
+
currentId = currentRecord.predecessor[currentIdIndex].from;
|
|
314
|
+
}
|
|
315
|
+
if (result === false) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
} else {
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return flag;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* To add dependency for Task
|
|
331
|
+
*
|
|
332
|
+
* @param {IGanttData} ganttRecord .
|
|
333
|
+
* @param {string} predecessorString .
|
|
334
|
+
* @returns {void} .
|
|
335
|
+
* @private
|
|
336
|
+
*/
|
|
337
|
+
public addPredecessor(ganttRecord: IGanttData, predecessorString: string): void {
|
|
338
|
+
const tempPredecessorString: string = isNullOrUndefined(ganttRecord.ganttProperties.predecessorsName) ||
|
|
339
|
+
ganttRecord.ganttProperties.predecessorsName === '' ?
|
|
340
|
+
predecessorString : (ganttRecord.ganttProperties.predecessorsName + ',' + predecessorString);
|
|
341
|
+
this.updatePredecessorHelper(ganttRecord, tempPredecessorString);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* To remove dependency from task
|
|
345
|
+
*
|
|
346
|
+
* @param {IGanttData} ganttRecord .
|
|
347
|
+
* @returns {void} .
|
|
348
|
+
* @private
|
|
349
|
+
*/
|
|
350
|
+
public removePredecessor(ganttRecord: IGanttData): void {
|
|
351
|
+
this.updatePredecessorHelper(ganttRecord, null);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* To modify current dependency values of Task
|
|
355
|
+
*
|
|
356
|
+
* @param {IGanttData} ganttRecord .
|
|
357
|
+
* @param {string} predecessorString .
|
|
358
|
+
* @param {ITaskbarEditedEventArgs} editedArgs .
|
|
359
|
+
* @returns {boolean} .
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
362
|
+
public updatePredecessor(ganttRecord: IGanttData, predecessorString: string, editedArgs?: ITaskbarEditedEventArgs): boolean {
|
|
363
|
+
return this.updatePredecessorHelper(ganttRecord, predecessorString, editedArgs);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
private updatePredecessorHelper(ganttRecord: IGanttData, predecessorString: string, editedArgs?: ITaskbarEditedEventArgs): boolean {
|
|
367
|
+
if (isUndefined(predecessorString) || this.validatePredecessorRelation(ganttRecord, predecessorString)) {
|
|
368
|
+
this.parent.isOnEdit = true;
|
|
369
|
+
let predecessorCollection: IPredecessor[] = [];
|
|
370
|
+
if (!isNullOrUndefined(predecessorString) && predecessorString !== '') {
|
|
371
|
+
predecessorCollection = this.parent.predecessorModule.calculatePredecessor(predecessorString, ganttRecord);
|
|
372
|
+
}
|
|
373
|
+
this.parent.setRecordValue(
|
|
374
|
+
'predecessor',
|
|
375
|
+
predecessorCollection,
|
|
376
|
+
ganttRecord.ganttProperties,
|
|
377
|
+
true);
|
|
378
|
+
const stringValue: string = this.parent.predecessorModule.getPredecessorStringValue(ganttRecord);
|
|
379
|
+
this.parent.setRecordValue(
|
|
380
|
+
'predecessorsName',
|
|
381
|
+
stringValue,
|
|
382
|
+
ganttRecord.ganttProperties,
|
|
383
|
+
true);
|
|
384
|
+
this.parent.setRecordValue('taskData.' + this.parent.taskFields.dependency, stringValue, ganttRecord);
|
|
385
|
+
this.parent.setRecordValue(this.parent.taskFields.dependency, stringValue, ganttRecord);
|
|
386
|
+
const args: ITaskbarEditedEventArgs = {} as ITaskbarEditedEventArgs;
|
|
387
|
+
args.action = editedArgs && editedArgs.action && editedArgs.action === 'CellEditing' ? editedArgs.action : 'DrawConnectorLine';
|
|
388
|
+
args.data = ganttRecord;
|
|
389
|
+
this.parent.editModule.initiateUpdateAction(args);
|
|
390
|
+
return true;
|
|
391
|
+
} else {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
private checkParentRelation(ganttRecord: IGanttData, predecessorIdArray: string[]): boolean {
|
|
397
|
+
const editingData: IGanttData = ganttRecord;
|
|
398
|
+
const checkParent: boolean = true;
|
|
399
|
+
if (editingData && editingData.parentItem) {
|
|
400
|
+
if (predecessorIdArray.indexOf(editingData.parentItem.taskId.toString()) !== -1) {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
for (let p: number = 0; p < predecessorIdArray.length; p++) {
|
|
405
|
+
const record: IGanttData[] = this.parent.currentViewData.filter((item: IGanttData) => {
|
|
406
|
+
return item && item.ganttProperties.rowUniqueID.toString() === predecessorIdArray[p].toString();
|
|
407
|
+
});
|
|
408
|
+
if (record[0] && record[0].hasChildRecords) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return checkParent;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
private initPredecessorValidationDialog(): void {
|
|
416
|
+
if (this.parent.taskFields.dependency && this.parent.isInPredecessorValidation) {
|
|
417
|
+
const dialogElement: HTMLElement = createElement('div', {
|
|
418
|
+
id: this.parent.element.id + '_dialogValidationRule'
|
|
419
|
+
});
|
|
420
|
+
this.parent.element.appendChild(dialogElement);
|
|
421
|
+
this.renderValidationDialog();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* To render validation dialog
|
|
427
|
+
*
|
|
428
|
+
* @returns {void} .
|
|
429
|
+
* @private
|
|
430
|
+
*/
|
|
431
|
+
public renderValidationDialog(): void {
|
|
432
|
+
const validationDialog: Dialog = new Dialog({
|
|
433
|
+
header: 'Validate Editing',
|
|
434
|
+
isModal: true,
|
|
435
|
+
visible: false,
|
|
436
|
+
width: '50%',
|
|
437
|
+
showCloseIcon: true,
|
|
438
|
+
close: this.validationDialogClose.bind(this),
|
|
439
|
+
content: '',
|
|
440
|
+
buttons: [
|
|
441
|
+
{
|
|
442
|
+
click: this.validationDialogOkButton.bind(this),
|
|
443
|
+
buttonModel: { content: this.parent.localeObj.getConstant('okText'), isPrimary: true }
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
click: this.validationDialogCancelButton.bind(this),
|
|
447
|
+
buttonModel: { content: this.parent.localeObj.getConstant('cancel') }
|
|
448
|
+
}],
|
|
449
|
+
target: this.parent.element,
|
|
450
|
+
animationSettings: { effect: 'None' }
|
|
451
|
+
});
|
|
452
|
+
document.getElementById(this.parent.element.id + '_dialogValidationRule').innerHTML = '';
|
|
453
|
+
validationDialog.isStringTemplate = true;
|
|
454
|
+
validationDialog.appendTo('#' + this.parent.element.id + '_dialogValidationRule');
|
|
455
|
+
this.parent.validationDialogElement = validationDialog;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private validationDialogOkButton(): void {
|
|
459
|
+
const currentArgs: IValidateArgs = this.parent.currentEditedArgs;
|
|
460
|
+
currentArgs.validateMode.preserveLinkWithEditing =
|
|
461
|
+
(document.getElementById(this.parent.element.id + '_ValidationAddlineOffset') as HTMLInputElement).checked;
|
|
462
|
+
currentArgs.validateMode.removeLink =
|
|
463
|
+
(document.getElementById(this.parent.element.id + '_ValidationRemoveline') as HTMLInputElement).checked;
|
|
464
|
+
currentArgs.validateMode.respectLink =
|
|
465
|
+
(document.getElementById(this.parent.element.id + '_ValidationCancel') as HTMLInputElement).checked;
|
|
466
|
+
this.applyPredecessorOption();
|
|
467
|
+
this.parent.validationDialogElement.hide();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
private validationDialogCancelButton(): void {
|
|
471
|
+
this.parent.currentEditedArgs.validateMode.respectLink = true;
|
|
472
|
+
this.applyPredecessorOption();
|
|
473
|
+
this.parent.validationDialogElement.hide();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private validationDialogClose(e: object): void {
|
|
477
|
+
if (getValue('isInteraction', e)) {
|
|
478
|
+
this.parent.currentEditedArgs.validateMode.respectLink = true;
|
|
479
|
+
this.applyPredecessorOption();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Validate and apply the predecessor option from validation dialog
|
|
484
|
+
*
|
|
485
|
+
* @returns {void} .
|
|
486
|
+
* @private
|
|
487
|
+
*/
|
|
488
|
+
public applyPredecessorOption(): void {
|
|
489
|
+
const args: IValidateArgs = this.parent.currentEditedArgs;
|
|
490
|
+
const ganttRecord: IGanttData = args.data;
|
|
491
|
+
if (args.validateMode.respectLink) {
|
|
492
|
+
this.parent.editModule.reUpdatePreviousRecords();
|
|
493
|
+
this.parent.chartRowsModule.refreshRecords([args.data]);
|
|
494
|
+
} else if (args.validateMode.removeLink) {
|
|
495
|
+
this.removePredecessors(ganttRecord, this.validationPredecessor);
|
|
496
|
+
this.parent.editModule.updateEditedTask(args.editEventArgs);
|
|
497
|
+
} else if (args.validateMode.preserveLinkWithEditing) {
|
|
498
|
+
this.calculateOffset(ganttRecord);
|
|
499
|
+
this.parent.editModule.updateEditedTask(args.editEventArgs);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
private calculateOffset(record: IGanttData): void {
|
|
504
|
+
const prevPredecessor: IPredecessor[] = extend([], record.ganttProperties.predecessor, [], true) as IPredecessor[];
|
|
505
|
+
const validPredecessor: IPredecessor[] = this.parent.predecessorModule.getValidPredecessor(record);
|
|
506
|
+
for (let i: number = 0; i < validPredecessor.length; i++) {
|
|
507
|
+
const predecessor: IPredecessor = validPredecessor[i];
|
|
508
|
+
const parentTask: IGanttData = this.parent.connectorLineModule.getRecordByID(predecessor.from);
|
|
509
|
+
let offset: number;
|
|
510
|
+
if (isScheduledTask(parentTask.ganttProperties) && isScheduledTask(record.ganttProperties)) {
|
|
511
|
+
let tempStartDate: Date;
|
|
512
|
+
let tempEndDate: Date;
|
|
513
|
+
let tempDuration: number;
|
|
514
|
+
let isNegativeOffset: boolean;
|
|
515
|
+
switch (predecessor.type) {
|
|
516
|
+
case 'FS':
|
|
517
|
+
tempStartDate = new Date(parentTask.ganttProperties.endDate.getTime());
|
|
518
|
+
tempEndDate = new Date(record.ganttProperties.startDate.getTime());
|
|
519
|
+
break;
|
|
520
|
+
case 'SS':
|
|
521
|
+
tempStartDate = new Date(parentTask.ganttProperties.startDate.getTime());
|
|
522
|
+
tempEndDate = new Date(record.ganttProperties.startDate.getTime());
|
|
523
|
+
break;
|
|
524
|
+
case 'SF':
|
|
525
|
+
tempStartDate = new Date(parentTask.ganttProperties.startDate.getTime());
|
|
526
|
+
tempEndDate = new Date(record.ganttProperties.endDate.getTime());
|
|
527
|
+
break;
|
|
528
|
+
case 'FF':
|
|
529
|
+
tempStartDate = new Date(parentTask.ganttProperties.endDate.getTime());
|
|
530
|
+
tempEndDate = new Date(record.ganttProperties.endDate.getTime());
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (tempStartDate.getTime() < tempEndDate.getTime()) {
|
|
535
|
+
tempStartDate = this.dateValidateModule.checkStartDate(tempStartDate);
|
|
536
|
+
tempEndDate = this.dateValidateModule.checkEndDate(tempEndDate, null);
|
|
537
|
+
isNegativeOffset = false;
|
|
538
|
+
} else {
|
|
539
|
+
const tempDate: Date = new Date(tempStartDate.getTime());
|
|
540
|
+
tempStartDate = this.dateValidateModule.checkStartDate(tempEndDate);
|
|
541
|
+
tempEndDate = this.dateValidateModule.checkEndDate(tempDate, null);
|
|
542
|
+
isNegativeOffset = true;
|
|
543
|
+
}
|
|
544
|
+
if (tempStartDate.getTime() < tempEndDate.getTime()) {
|
|
545
|
+
tempDuration = this.dateValidateModule.getDuration(tempStartDate, tempEndDate, predecessor.offsetUnit, true, false);
|
|
546
|
+
offset = isNegativeOffset ? (tempDuration * -1) : tempDuration;
|
|
547
|
+
} else {
|
|
548
|
+
offset = 0;
|
|
549
|
+
}
|
|
550
|
+
} else {
|
|
551
|
+
offset = 0;
|
|
552
|
+
}
|
|
553
|
+
const preIndex: number = getIndex (predecessor, 'from', prevPredecessor, 'to');
|
|
554
|
+
prevPredecessor[preIndex].offset = offset;
|
|
555
|
+
// Update predecessor in predecessor task
|
|
556
|
+
const parentPredecessors: IPredecessor = extend([], parentTask.ganttProperties.predecessor, [], true);
|
|
557
|
+
const parentPreIndex: number = getIndex(predecessor, 'from', parentPredecessors, 'to');
|
|
558
|
+
parentPredecessors[parentPreIndex].offset = offset;
|
|
559
|
+
this.parent.setRecordValue('predecessor', parentPredecessors, parentTask.ganttProperties, true);
|
|
560
|
+
}
|
|
561
|
+
this.parent.setRecordValue('predecessor', prevPredecessor, record.ganttProperties, true);
|
|
562
|
+
const predecessorString: string = this.parent.predecessorModule.getPredecessorStringValue(record);
|
|
563
|
+
this.parent.setRecordValue('taskData.' + this.parent.taskFields.dependency, predecessorString, record);
|
|
564
|
+
this.parent.setRecordValue(this.parent.taskFields.dependency, predecessorString, record);
|
|
565
|
+
this.parent.setRecordValue('predecessorsName', predecessorString, record.ganttProperties, true);
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Update predecessor value with user selection option in predecessor validation dialog
|
|
569
|
+
*
|
|
570
|
+
* @param {IGanttData} ganttRecord .
|
|
571
|
+
* @param {IPredecessor[]} predecessor .
|
|
572
|
+
* @returns {void} .
|
|
573
|
+
*/
|
|
574
|
+
private removePredecessors(ganttRecord: IGanttData, predecessor: IPredecessor[]): void {
|
|
575
|
+
const prevPredecessor: IPredecessor[] =
|
|
576
|
+
extend([], [], ganttRecord.ganttProperties.predecessor, true) as IPredecessor[];
|
|
577
|
+
const preLength: number = predecessor.length;
|
|
578
|
+
for (let i: number = 0; i < preLength; i++) {
|
|
579
|
+
const parentGanttRecord: IGanttData = this.parent.connectorLineModule.getRecordByID(predecessor[i].from);
|
|
580
|
+
const parentPredecessor: IPredecessor[] =
|
|
581
|
+
extend([], [], parentGanttRecord.ganttProperties.predecessor, true) as IPredecessor[];
|
|
582
|
+
const index: number = getIndex(predecessor[i], 'from', prevPredecessor, 'to');
|
|
583
|
+
prevPredecessor.splice(index, 1);
|
|
584
|
+
const parentIndex: number = getIndex(predecessor[i], 'from', parentPredecessor, 'to');
|
|
585
|
+
parentPredecessor.splice(parentIndex, 1);
|
|
586
|
+
this.parent.setRecordValue('predecessor', parentPredecessor, parentGanttRecord.ganttProperties, true);
|
|
587
|
+
}
|
|
588
|
+
if (prevPredecessor.length !== ganttRecord.ganttProperties.predecessor.length) {
|
|
589
|
+
this.parent.setRecordValue('predecessor', prevPredecessor, ganttRecord.ganttProperties, true);
|
|
590
|
+
const predecessorString: string = this.parent.predecessorModule.getPredecessorStringValue(ganttRecord);
|
|
591
|
+
this.parent.setRecordValue('predecessorsName', predecessorString, ganttRecord.ganttProperties, true);
|
|
592
|
+
this.parent.setRecordValue('taskData.' + this.parent.taskFields.dependency, predecessorString, ganttRecord);
|
|
593
|
+
this.parent.setRecordValue(this.parent.taskFields.dependency, predecessorString, ganttRecord);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* To open predecessor validation dialog
|
|
599
|
+
*
|
|
600
|
+
* @param {object} args .
|
|
601
|
+
* @returns {void} .
|
|
602
|
+
* @private
|
|
603
|
+
*/
|
|
604
|
+
public openValidationDialog(args: object): void {
|
|
605
|
+
const contentTemplate: HTMLElement = this.validationDialogTemplate(args);
|
|
606
|
+
this.parent.validationDialogElement.setProperties({ content: contentTemplate });
|
|
607
|
+
this.parent.validationDialogElement.show();
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Predecessor link validation dialog template
|
|
612
|
+
*
|
|
613
|
+
* @param {object} args .
|
|
614
|
+
* @returns {HTMLElement} .
|
|
615
|
+
* @private
|
|
616
|
+
*/
|
|
617
|
+
public validationDialogTemplate(args: object): HTMLElement {
|
|
618
|
+
const ganttId: string = this.parent.element.id;
|
|
619
|
+
const contentdiv: HTMLElement = createElement('div', {
|
|
620
|
+
className: 'e-ValidationContent'
|
|
621
|
+
});
|
|
622
|
+
const taskData: IGanttData = getValue('task', args);
|
|
623
|
+
const parenttaskData: IGanttData = getValue('parentTask', args);
|
|
624
|
+
const violationType: string = getValue('violationType', args);
|
|
625
|
+
const recordName: string = taskData.ganttProperties.taskName;
|
|
626
|
+
const recordNewStartDate: string = this.parent.getFormatedDate(taskData.ganttProperties.startDate, 'MM/dd/yyyy');
|
|
627
|
+
const parentName: string = parenttaskData.ganttProperties.taskName;
|
|
628
|
+
const recordArgs: string[] = [recordName, parentName];
|
|
629
|
+
let topContentText: string;
|
|
630
|
+
if (violationType === 'taskBeforePredecessor_FS') {
|
|
631
|
+
topContentText = this.parent.localeObj.getConstant('taskBeforePredecessor_FS');
|
|
632
|
+
} else if (violationType === 'taskAfterPredecessor_FS') {
|
|
633
|
+
topContentText = this.parent.localeObj.getConstant('taskAfterPredecessor_FS');
|
|
634
|
+
} else if (violationType === 'taskBeforePredecessor_SS') {
|
|
635
|
+
topContentText = this.parent.localeObj.getConstant('taskBeforePredecessor_SS');
|
|
636
|
+
} else if (violationType === 'taskAfterPredecessor_SS') {
|
|
637
|
+
topContentText = this.parent.localeObj.getConstant('taskAfterPredecessor_SS');
|
|
638
|
+
} else if (violationType === 'taskBeforePredecessor_FF') {
|
|
639
|
+
topContentText = this.parent.localeObj.getConstant('taskBeforePredecessor_FF');
|
|
640
|
+
} else if (violationType === 'taskAfterPredecessor_FF') {
|
|
641
|
+
topContentText = this.parent.localeObj.getConstant('taskAfterPredecessor_FF');
|
|
642
|
+
} else if (violationType === 'taskBeforePredecessor_SF') {
|
|
643
|
+
topContentText = this.parent.localeObj.getConstant('taskBeforePredecessor_SF');
|
|
644
|
+
} else if (violationType === 'taskAfterPredecessor_SF') {
|
|
645
|
+
topContentText = this.parent.localeObj.getConstant('taskAfterPredecessor_SF');
|
|
646
|
+
}
|
|
647
|
+
topContentText = formatString(topContentText, recordArgs);
|
|
648
|
+
const topContent: string = '<div id="' + ganttId + '_ValidationText">' + topContentText + '<div>';
|
|
649
|
+
const innerTable: string = '<table>' +
|
|
650
|
+
'<tr><td><input type="radio" id="' + ganttId + '_ValidationCancel" name="ValidationRule" checked/><label for="'
|
|
651
|
+
+ ganttId + '_ValidationCancel" id= "' + ganttId + '_cancelLink">Cancel, keep the existing link</label></td></tr>' +
|
|
652
|
+
'<tr><td><input type="radio" id="' + ganttId + '_ValidationRemoveline" name="ValidationRule"/><label for="'
|
|
653
|
+
+ ganttId + '_ValidationRemoveline" id="' + ganttId + '_removeLink">Remove the link and move <b>'
|
|
654
|
+
+ recordName + '</b> to start on <b>' + recordNewStartDate + '</b>.</label></td></tr>' +
|
|
655
|
+
'<tr><td><input type="radio" id="' + ganttId + '_ValidationAddlineOffset" name="ValidationRule"/><label for="'
|
|
656
|
+
+ ganttId + '_ValidationAddlineOffset" id="' + ganttId + '_preserveLink">Move the <b>'
|
|
657
|
+
+ recordName + '</b> to start on <b>' + recordNewStartDate + '</b> and keep the link.</label></td></tr></table>';
|
|
658
|
+
contentdiv.innerHTML = topContent + innerTable;
|
|
659
|
+
return contentdiv;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* To validate the types while editing the taskbar
|
|
664
|
+
*
|
|
665
|
+
* @param {IGanttData} ganttRecord .
|
|
666
|
+
* @returns {boolean} .
|
|
667
|
+
* @private
|
|
668
|
+
*/
|
|
669
|
+
public validateTypes(ganttRecord: IGanttData): object {
|
|
670
|
+
const predecessor: IPredecessor[] = this.parent.predecessorModule.getValidPredecessor(ganttRecord);
|
|
671
|
+
let parentGanttRecord: IGanttData;
|
|
672
|
+
this.validationPredecessor = [];
|
|
673
|
+
let violatedParent: IGanttData;
|
|
674
|
+
let violateType: string;
|
|
675
|
+
const startDate: Date = this.parent.predecessorModule.getPredecessorDate(ganttRecord, predecessor);
|
|
676
|
+
const ganttTaskData: ITaskData = ganttRecord.ganttProperties;
|
|
677
|
+
const endDate: Date = this.parent.allowUnscheduledTasks && isNullOrUndefined(startDate) ?
|
|
678
|
+
ganttTaskData.endDate :
|
|
679
|
+
this.dateValidateModule.getEndDate(startDate, ganttTaskData.duration, ganttTaskData.durationUnit, ganttTaskData, false);
|
|
680
|
+
for (let i: number = 0; i < predecessor.length; i++) {
|
|
681
|
+
parentGanttRecord = this.parent.connectorLineModule.getRecordByID(predecessor[i].from);
|
|
682
|
+
let violationType: string = null;
|
|
683
|
+
if (predecessor[i].type === 'FS') {
|
|
684
|
+
if (ganttTaskData.startDate < startDate) {
|
|
685
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
686
|
+
violationType = 'taskBeforePredecessor_FS';
|
|
687
|
+
} else if (ganttTaskData.startDate > startDate) {
|
|
688
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
689
|
+
violationType = 'taskAfterPredecessor_FS';
|
|
690
|
+
}
|
|
691
|
+
} else if (predecessor[i].type === 'SS') {
|
|
692
|
+
if (ganttTaskData.startDate < startDate) {
|
|
693
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
694
|
+
violationType = 'taskBeforePredecessor_SS';
|
|
695
|
+
} else if (ganttTaskData.startDate > startDate) {
|
|
696
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
697
|
+
violationType = 'taskAfterPredecessor_SS';
|
|
698
|
+
}
|
|
699
|
+
} else if (predecessor[i].type === 'FF') {
|
|
700
|
+
if (endDate <= parentGanttRecord.ganttProperties.endDate) {
|
|
701
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
702
|
+
violationType = 'taskBeforePredecessor_FF';
|
|
703
|
+
} else if (endDate > parentGanttRecord.ganttProperties.endDate) {
|
|
704
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
705
|
+
violationType = 'taskAfterPredecessor_FF';
|
|
706
|
+
}
|
|
707
|
+
} else if (predecessor[i].type === 'SF') {
|
|
708
|
+
if (endDate < parentGanttRecord.ganttProperties.startDate) {
|
|
709
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
710
|
+
violationType = 'taskBeforePredecessor_SF';
|
|
711
|
+
} else if (endDate >= parentGanttRecord.ganttProperties.startDate) {
|
|
712
|
+
this.validationPredecessor.push(predecessor[i]);
|
|
713
|
+
violationType = 'taskAfterPredecessor_SF';
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
if (!isNullOrUndefined(violationType) && isNullOrUndefined(violateType)) {
|
|
717
|
+
violatedParent = parentGanttRecord;
|
|
718
|
+
violateType = violationType;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
const validateArgs: object = {
|
|
722
|
+
parentTask: violatedParent,
|
|
723
|
+
task: ganttRecord,
|
|
724
|
+
violationType: violateType
|
|
725
|
+
};
|
|
726
|
+
return validateArgs;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Method to remove and update new predecessor collection in successor record
|
|
731
|
+
*
|
|
732
|
+
* @param {IGanttData} data .
|
|
733
|
+
* @returns {void} .
|
|
734
|
+
* @private
|
|
735
|
+
*/
|
|
736
|
+
public addRemovePredecessor(data: IGanttData): void {
|
|
737
|
+
const prevData: IGanttData = this.parent.previousRecords[data.uniqueID];
|
|
738
|
+
const newPredecessor: IPredecessor[] = data.ganttProperties.predecessor.slice();
|
|
739
|
+
// eslint-disable-next-line
|
|
740
|
+
if (prevData && prevData.ganttProperties && prevData.ganttProperties.hasOwnProperty('predecessor')) {
|
|
741
|
+
const prevPredecessor: IPredecessor[] = prevData.ganttProperties.predecessor;
|
|
742
|
+
if (!isNullOrUndefined(prevPredecessor)) {
|
|
743
|
+
for (let p: number = 0; p < prevPredecessor.length; p++) {
|
|
744
|
+
const parentGanttRecord: IGanttData = this.parent.connectorLineModule.getRecordByID(prevPredecessor[p].from);
|
|
745
|
+
if (parentGanttRecord === data) {
|
|
746
|
+
data.ganttProperties.predecessor.push(prevPredecessor[p]);
|
|
747
|
+
} else {
|
|
748
|
+
const parentPredecessor: IPredecessor[] =
|
|
749
|
+
extend([], [], parentGanttRecord.ganttProperties.predecessor, true) as IPredecessor[];
|
|
750
|
+
const parentIndex: number = getIndex(prevPredecessor[p], 'from', parentPredecessor, 'to');
|
|
751
|
+
if (parentIndex !== -1) {
|
|
752
|
+
parentPredecessor.splice(parentIndex, 1);
|
|
753
|
+
this.parent.setRecordValue('predecessor', parentPredecessor, parentGanttRecord.ganttProperties, true);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
if (!isNullOrUndefined(newPredecessor)) {
|
|
759
|
+
for (let n: number = 0; n < newPredecessor.length; n++) {
|
|
760
|
+
const parentGanttRecord: IGanttData = this.parent.connectorLineModule.getRecordByID(newPredecessor[n].from);
|
|
761
|
+
const parentPredecessor: IPredecessor[] =
|
|
762
|
+
extend([], [], parentGanttRecord.ganttProperties.predecessor, true) as IPredecessor[];
|
|
763
|
+
parentPredecessor.push(newPredecessor[n]);
|
|
764
|
+
this.parent.setRecordValue('predecessor', parentPredecessor, parentGanttRecord.ganttProperties, true);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Method to remove a predecessor from a record.
|
|
772
|
+
*
|
|
773
|
+
* @param {IGanttData} childRecord .
|
|
774
|
+
* @param {number} index .
|
|
775
|
+
* @returns {void} .
|
|
776
|
+
* @private
|
|
777
|
+
*/
|
|
778
|
+
public removePredecessorByIndex(childRecord: IGanttData, index: number): void {
|
|
779
|
+
const childPredecessor: IPredecessor[] = childRecord.ganttProperties.predecessor;
|
|
780
|
+
const predecessor: IPredecessor = childPredecessor.splice(index, 1) as IPredecessor;
|
|
781
|
+
const parentRecord: IGanttData = this.parent.connectorLineModule.getRecordByID(predecessor[0].from);
|
|
782
|
+
const parentPredecessor: IPredecessor[] = parentRecord.ganttProperties.predecessor;
|
|
783
|
+
const parentIndex: number = getIndex(predecessor[0], 'from', parentPredecessor, 'to');
|
|
784
|
+
parentPredecessor.splice(parentIndex, 1);
|
|
785
|
+
const predecessorString: string = this.parent.predecessorModule.getPredecessorStringValue(childRecord);
|
|
786
|
+
childPredecessor.push(predecessor[0]);
|
|
787
|
+
this.parent.connectorLineEditModule.updatePredecessor(childRecord, predecessorString);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* To render predecessor delete confirmation dialog
|
|
792
|
+
*
|
|
793
|
+
* @returns {void} .
|
|
794
|
+
* @private
|
|
795
|
+
*/
|
|
796
|
+
public renderPredecessorDeleteConfirmDialog(): void {
|
|
797
|
+
this.confirmPredecessorDialog = new Dialog({
|
|
798
|
+
width: '320px',
|
|
799
|
+
isModal: true,
|
|
800
|
+
content: this.parent.localeObj.getConstant('confirmPredecessorDelete'),
|
|
801
|
+
buttons: [
|
|
802
|
+
{
|
|
803
|
+
click: this.confirmOkDeleteButton.bind(this),
|
|
804
|
+
buttonModel: { content: this.parent.localeObj.getConstant('okText'), isPrimary: true }
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
click: this.confirmCloseDialog.bind(this),
|
|
808
|
+
buttonModel: { content: this.parent.localeObj.getConstant('cancel') }
|
|
809
|
+
}],
|
|
810
|
+
target: this.parent.element,
|
|
811
|
+
animationSettings: { effect: 'None' }
|
|
812
|
+
});
|
|
813
|
+
const confirmDialog: HTMLElement = createElement('div', {
|
|
814
|
+
id: this.parent.element.id + '_deletePredecessorConfirmDialog'
|
|
815
|
+
});
|
|
816
|
+
this.parent.element.appendChild(confirmDialog);
|
|
817
|
+
this.confirmPredecessorDialog.isStringTemplate = true;
|
|
818
|
+
this.confirmPredecessorDialog.appendTo(confirmDialog);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
private confirmCloseDialog(): void {
|
|
822
|
+
this.confirmPredecessorDialog.destroy();
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
private confirmOkDeleteButton(): void {
|
|
826
|
+
this.removePredecessorByIndex(this.childRecord, this.predecessorIndex);
|
|
827
|
+
this.confirmPredecessorDialog.destroy();
|
|
828
|
+
}
|
|
829
|
+
}
|