@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,1248 @@
|
|
|
1
|
+
import { Gantt } from '../base/gantt';
|
|
2
|
+
import {
|
|
3
|
+
createElement, formatUnit, EventHandler, Browser, KeyboardEvents, getElement,
|
|
4
|
+
KeyboardEventArgs
|
|
5
|
+
} from '@syncfusion/ej2-base';
|
|
6
|
+
import { isNullOrUndefined, closest, addClass, removeClass, getValue, setValue } from '@syncfusion/ej2-base';
|
|
7
|
+
import * as cls from '../base/css-constants';
|
|
8
|
+
import { ChartScroll } from '../actions/chart-scroll';
|
|
9
|
+
import { IGanttData, IWorkTimelineRanges } from '../base/interface';
|
|
10
|
+
import { click } from '@syncfusion/ej2-grids';
|
|
11
|
+
import { ITaskbarClickEventArgs, RecordDoubleClickEventArgs, IMouseMoveEventArgs, IIndicator } from '../base/interface';
|
|
12
|
+
import { TooltipEventArgs } from '@syncfusion/ej2-popups';
|
|
13
|
+
import { FocusStrategy } from '@syncfusion/ej2-grids/src/grid/services/focus-strategy';
|
|
14
|
+
import { VirtualContentRenderer } from '../renderer/virtual-content-render';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* module to render gantt chart - project view
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export class GanttChart {
|
|
21
|
+
private parent: Gantt;
|
|
22
|
+
public chartElement: HTMLElement;
|
|
23
|
+
public chartTimelineContainer: HTMLElement;
|
|
24
|
+
public chartBodyContainer: HTMLElement;
|
|
25
|
+
public chartBodyContent: HTMLElement;
|
|
26
|
+
public rangeViewContainer: HTMLElement;
|
|
27
|
+
public scrollElement: HTMLElement;
|
|
28
|
+
public scrollObject: ChartScroll;
|
|
29
|
+
public isExpandCollapseFromChart: boolean = false;
|
|
30
|
+
public isExpandAll: boolean = false;
|
|
31
|
+
private focusedElement: HTMLElement;
|
|
32
|
+
public focusedRowIndex: number;
|
|
33
|
+
private isGanttElement: boolean = false;
|
|
34
|
+
public keyboardModule: KeyboardEvents;
|
|
35
|
+
public targetElement: Element;
|
|
36
|
+
public virtualRender: VirtualContentRenderer;
|
|
37
|
+
constructor(parent: Gantt) {
|
|
38
|
+
this.parent = parent;
|
|
39
|
+
this.chartTimelineContainer = null;
|
|
40
|
+
this.rangeViewContainer =
|
|
41
|
+
createElement('div', { className: cls.rangeContainer });
|
|
42
|
+
this.rangeViewContainer.setAttribute("role", "RangeContainer");
|
|
43
|
+
this.virtualRender = new VirtualContentRenderer(this.parent);
|
|
44
|
+
this.addEventListener();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private addEventListener(): void {
|
|
48
|
+
this.parent.on('renderPanels', this.renderChartContainer, this);
|
|
49
|
+
this.parent.on('recordsUpdated', this.renderChartElements, this);
|
|
50
|
+
this.parent.on('dataReady', this.renderInitialContents, this);
|
|
51
|
+
this.parent.on('tree-grid-created', this.renderChartContents, this);
|
|
52
|
+
this.parent.on('destroy', this.destroy, this);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private renderChartContents(): void {
|
|
56
|
+
this.parent.notify('refreshDayMarkers', {});
|
|
57
|
+
this.wireEvents();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Method to render top level containers in Gantt chart
|
|
61
|
+
*
|
|
62
|
+
* @returns {void} .
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
public renderChartContainer(): void {
|
|
66
|
+
this.chartElement = createElement('div', { id: this.parent.element.id + 'GanttChart', className: cls.ganttChart });
|
|
67
|
+
this.parent.chartPane.appendChild(this.chartElement);
|
|
68
|
+
this.renderTimelineContainer();
|
|
69
|
+
this.renderBodyContainers();
|
|
70
|
+
// render top level div header and content
|
|
71
|
+
// Get timeline header from timeline class file and append to header div
|
|
72
|
+
// render content div
|
|
73
|
+
// Render scroll able div
|
|
74
|
+
// Render container for all element like, table, weekend and holidays
|
|
75
|
+
// Get rows element from rows renderer class
|
|
76
|
+
// Get label related info label renderer class
|
|
77
|
+
// Get baseline from baseline renderer class
|
|
78
|
+
// Get weekend elements from weekend-holidays renderer class
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* method to render timeline, holidays, weekends at load time
|
|
82
|
+
*
|
|
83
|
+
* @returns {void} .
|
|
84
|
+
*/
|
|
85
|
+
private renderInitialContents(): void {
|
|
86
|
+
this.parent.timelineModule.createTimelineSeries();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @returns {void} .
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
public renderOverAllocationContainer(): void {
|
|
93
|
+
for (let i: number = 0; i < this.parent.flatData.length; i++) {
|
|
94
|
+
const data: IGanttData = this.parent.flatData[i];
|
|
95
|
+
if (data.childRecords.length > 0) {
|
|
96
|
+
this.parent.dataOperation.updateOverlappingValues(data);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const rangeContainer: HTMLElement = this.parent.element.querySelector('.' + cls.rangeContainer);
|
|
100
|
+
if (rangeContainer) {
|
|
101
|
+
rangeContainer.innerHTML = '';
|
|
102
|
+
}
|
|
103
|
+
if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) {
|
|
104
|
+
this.renderRangeContainer(this.parent.currentViewData);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
private renderChartElements(): void {
|
|
108
|
+
if (this.parent.isFromOnPropertyChange) {
|
|
109
|
+
this.rangeViewContainer.innerHTML = '';
|
|
110
|
+
this.parent.updateProjectDates(
|
|
111
|
+
this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate, this.parent.isTimelineRoundOff);
|
|
112
|
+
this.parent.isFromOnPropertyChange = false;
|
|
113
|
+
} else {
|
|
114
|
+
this.parent.chartRowsModule.renderChartRows();
|
|
115
|
+
if (this.parent.predecessorModule && this.parent.taskFields.dependency) {
|
|
116
|
+
this.parent.connectorLineIds = [];
|
|
117
|
+
this.parent.updatedConnectorLineCollection = [];
|
|
118
|
+
this.parent.predecessorModule.createConnectorLinesCollection();
|
|
119
|
+
}
|
|
120
|
+
this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection);
|
|
121
|
+
if (this.parent.viewType === 'ResourceView' && this.parent.showOverAllocation) {
|
|
122
|
+
this.renderOverAllocationContainer();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
this.updateWidthAndHeight();
|
|
126
|
+
this.parent.notify('selectRowByIndex', {});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @param {IGanttData[]} records .
|
|
131
|
+
* @returns {void} .
|
|
132
|
+
* @private
|
|
133
|
+
*/
|
|
134
|
+
public renderRangeContainer(records: IGanttData[]): void {
|
|
135
|
+
const recordLength: number = records.length;
|
|
136
|
+
let count: number; let ganttRecord: IGanttData;
|
|
137
|
+
let rangeCollection: IWorkTimelineRanges[];
|
|
138
|
+
if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) {
|
|
139
|
+
for (count = 0; count < recordLength; count++) {
|
|
140
|
+
ganttRecord = records[count];
|
|
141
|
+
rangeCollection = ganttRecord.ganttProperties.workTimelineRanges;
|
|
142
|
+
if (rangeCollection) {
|
|
143
|
+
this.renderRange(rangeCollection, ganttRecord);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
private getTopValue(currentRecord: IGanttData): number {
|
|
149
|
+
const updatedRecords: IGanttData[] = this.parent.getExpandedRecords(this.parent.currentViewData);
|
|
150
|
+
const recordIndex: number = updatedRecords.indexOf(currentRecord);
|
|
151
|
+
if (!currentRecord.expanded) {
|
|
152
|
+
return (recordIndex * this.parent.rowHeight);
|
|
153
|
+
}
|
|
154
|
+
return ((recordIndex + 1) * this.parent.rowHeight);
|
|
155
|
+
}
|
|
156
|
+
/*get height for range bar*/
|
|
157
|
+
private getRangeHeight(data: IGanttData): number {
|
|
158
|
+
if (!data.expanded && data.hasChildRecords) {
|
|
159
|
+
return (this.parent.rowHeight - Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight)));
|
|
160
|
+
}
|
|
161
|
+
return (data.childRecords.length * this.parent.rowHeight) -
|
|
162
|
+
Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight));
|
|
163
|
+
}
|
|
164
|
+
private renderRange(rangeCollection: IWorkTimelineRanges[], currentRecord: IGanttData): void {
|
|
165
|
+
const topValue: number = this.getTopValue(currentRecord);
|
|
166
|
+
const sameIDElement: Element = this.rangeViewContainer.querySelector('.' + 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID);
|
|
167
|
+
if (sameIDElement) {
|
|
168
|
+
sameIDElement.remove();
|
|
169
|
+
}
|
|
170
|
+
const parentDiv: HTMLElement = createElement('div', {
|
|
171
|
+
className: 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID, styles: `top:${topValue}px; position: absolute;`
|
|
172
|
+
});
|
|
173
|
+
if (currentRecord.level === 0 && !currentRecord.expanded && isNullOrUndefined(currentRecord.parentItem)
|
|
174
|
+
&& !this.parent.enableMultiTaskbar) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
for (let i: number = 0; i < rangeCollection.length; i++) {
|
|
178
|
+
const height: number = this.getRangeHeight(currentRecord);
|
|
179
|
+
const leftDiv: HTMLElement = createElement('div', {
|
|
180
|
+
className: cls.rangeChildContainer + ' ' + 'e-leftarc', styles: `left:${rangeCollection[i].left}px;
|
|
181
|
+
top: ${Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2)}px;
|
|
182
|
+
height: ${height + 1}px; border-right: 0px`
|
|
183
|
+
});
|
|
184
|
+
const rightDiv: HTMLElement = createElement('div', {
|
|
185
|
+
className: cls.rangeChildContainer + ' ' + 'e-rightarc',
|
|
186
|
+
styles: `left:${rangeCollection[i].left + rangeCollection[i].width - 5}px;
|
|
187
|
+
top: ${Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2)}px; height: ${height + 1}px;
|
|
188
|
+
border-left: 0px`
|
|
189
|
+
});
|
|
190
|
+
parentDiv.appendChild(leftDiv);
|
|
191
|
+
parentDiv.appendChild(rightDiv);
|
|
192
|
+
this.rangeViewContainer.appendChild(parentDiv);
|
|
193
|
+
}
|
|
194
|
+
this.parent.ganttChartModule.chartBodyContent.appendChild(this.rangeViewContainer);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @returns {void} .
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
public renderTimelineContainer(): void {
|
|
201
|
+
this.chartTimelineContainer =
|
|
202
|
+
createElement('div', { className: cls.timelineHeaderContainer });
|
|
203
|
+
this.chartTimelineContainer.setAttribute("role", "TimelineHeader");
|
|
204
|
+
this.chartElement.appendChild(this.chartTimelineContainer);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* initiate chart container
|
|
209
|
+
*
|
|
210
|
+
* @returns {void} .
|
|
211
|
+
*/
|
|
212
|
+
private renderBodyContainers(): void {
|
|
213
|
+
this.chartBodyContainer = createElement('div', { className: cls.chartBodyContainer });
|
|
214
|
+
this.chartElement.appendChild(this.chartBodyContainer);
|
|
215
|
+
this.scrollElement = createElement('div', {
|
|
216
|
+
className: cls.chartScrollElement + ' ' + cls.scrollContent, styles: 'position:relative;'
|
|
217
|
+
});
|
|
218
|
+
this.chartBodyContainer.appendChild(this.scrollElement);
|
|
219
|
+
this.chartBodyContent = createElement('div', { className: cls.chartBodyContent, styles: 'position:relative; overflow:hidden ' });
|
|
220
|
+
if (this.parent.virtualScrollModule && this.parent.enableVirtualization) {
|
|
221
|
+
this.parent.ganttChartModule.virtualRender.renderWrapper();
|
|
222
|
+
} else {
|
|
223
|
+
this.scrollElement.appendChild(this.chartBodyContent);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// this.parent.chartRowsModule.createChartTable();
|
|
227
|
+
this.scrollObject = new ChartScroll(this.parent);
|
|
228
|
+
//this.scrollObject.setWidth(this.chartProperties.width);
|
|
229
|
+
let toolbarHeight: number = 0;
|
|
230
|
+
if (!isNullOrUndefined(this.parent.toolbarModule) && !isNullOrUndefined(this.parent.toolbarModule.element)) {
|
|
231
|
+
toolbarHeight = this.parent.toolbarModule.element.offsetHeight;
|
|
232
|
+
}
|
|
233
|
+
this.scrollObject.
|
|
234
|
+
setHeight(this.parent.ganttHeight - this.chartTimelineContainer.offsetHeight - toolbarHeight);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* @returns {void} .
|
|
238
|
+
* @private
|
|
239
|
+
*/
|
|
240
|
+
public updateWidthAndHeight(): void {
|
|
241
|
+
//empty row height
|
|
242
|
+
const emptydivHeight: number = 36;
|
|
243
|
+
const emptyHeight: number = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight;
|
|
244
|
+
let contentElement: HTMLElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0] as HTMLElement;
|
|
245
|
+
if (emptyHeight >= contentElement['offsetHeight']) {
|
|
246
|
+
this.chartBodyContent.style.height = formatUnit(emptyHeight);
|
|
247
|
+
} else {
|
|
248
|
+
let scrollHeight: number = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight'];
|
|
249
|
+
if (contentElement['offsetHeight'] >= scrollHeight) {
|
|
250
|
+
this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px';
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px';
|
|
254
|
+
}
|
|
255
|
+
} //let element: HTMLElement = this.chartTimelineContainer.querySelector('.' + cls.timelineHeaderTableContainer);
|
|
256
|
+
this.chartBodyContent.style.width = formatUnit(this.parent.timelineModule.totalTimelineWidth);
|
|
257
|
+
this.setVirtualHeight();
|
|
258
|
+
this.parent.notify('updateHeight', {});
|
|
259
|
+
this.parent.updateGridLineContainerHeight();
|
|
260
|
+
this.updateLastRowBottomWidth();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private setVirtualHeight(): void {
|
|
264
|
+
if (this.parent.virtualScrollModule && this.parent.enableVirtualization) {
|
|
265
|
+
const wrapper: HTMLElement = getValue('virtualTrack', this.parent.ganttChartModule.virtualRender);
|
|
266
|
+
wrapper.style.height = this.parent.updatedRecords.length * this.parent.rowHeight + 'px';
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Method to update bottom border for chart rows
|
|
271
|
+
*
|
|
272
|
+
* @returns {void} .
|
|
273
|
+
*/
|
|
274
|
+
public updateLastRowBottomWidth(): void {
|
|
275
|
+
if (this.parent.currentViewData.length > 0 && this.parent.height !== 'auto') {
|
|
276
|
+
const expandedRecords: IGanttData[] = this.parent.virtualScrollModule && this.parent.enableVirtualization ?
|
|
277
|
+
this.parent.currentViewData : this.parent.getExpandedRecords(this.parent.currentViewData);
|
|
278
|
+
const lastExpandedRow: IGanttData = expandedRecords[expandedRecords.length - 1];
|
|
279
|
+
const lastExpandedRowIndex: number = this.parent.currentViewData.indexOf(lastExpandedRow);
|
|
280
|
+
const lastRow: HTMLElement = this.parent.getRowByIndex(lastExpandedRowIndex);
|
|
281
|
+
const table: Element = this.parent.chartRowsModule.ganttChartTableBody;
|
|
282
|
+
if (table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow')) {
|
|
283
|
+
removeClass(table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow'), 'e-lastrow');
|
|
284
|
+
}
|
|
285
|
+
if (this.chartBodyContent.clientHeight < this.chartBodyContainer.clientHeight) {
|
|
286
|
+
if (lastRow) {
|
|
287
|
+
addClass(lastRow.querySelectorAll('td'), 'e-lastrow');
|
|
288
|
+
const emptydivHeight: number = 36;
|
|
289
|
+
const emptyHeight: number = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight;
|
|
290
|
+
let contentElement: HTMLElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0] as HTMLElement;
|
|
291
|
+
if (emptyHeight >= contentElement['offsetHeight']) {
|
|
292
|
+
this.chartBodyContent.style.height = formatUnit(emptyHeight);
|
|
293
|
+
} else {
|
|
294
|
+
let scrollHeight: number = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight'];
|
|
295
|
+
if (contentElement['offsetHeight'] >= scrollHeight) {
|
|
296
|
+
this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px';
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px';
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private removeEventListener(): void {
|
|
308
|
+
if (this.parent.isDestroyed) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
this.parent.off('renderPanels', this.renderChartContainer);
|
|
312
|
+
this.parent.off('recordsUpdated', this.renderChartElements);
|
|
313
|
+
this.parent.off('dataReady', this.renderInitialContents);
|
|
314
|
+
this.parent.off('tree-grid-created', this.renderChartContents);
|
|
315
|
+
this.parent.off('destroy', this.destroy);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Click event handler in chart side
|
|
319
|
+
*
|
|
320
|
+
* @param {PointerEvent} e .
|
|
321
|
+
* @returns {void} .
|
|
322
|
+
*/
|
|
323
|
+
private ganttChartMouseDown(e: PointerEvent): void {
|
|
324
|
+
if (e.which !== 3 && this.parent.editSettings.allowTaskbarEditing) {
|
|
325
|
+
this.parent.notify('chartMouseDown', e);
|
|
326
|
+
this.parent.element.tabIndex = 0;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private ganttChartMouseClick(e: PointerEvent): void {
|
|
331
|
+
if (this.parent.editSettings.allowTaskbarEditing) {
|
|
332
|
+
if (this.parent.autoFocusTasks) {
|
|
333
|
+
this.scrollToTarget(e); /** Scroll to task */
|
|
334
|
+
}
|
|
335
|
+
this.parent.notify('chartMouseClick', e);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private ganttChartMouseUp(e: PointerEvent): void {
|
|
340
|
+
if (this.parent.editSettings.allowTaskbarEditing) {
|
|
341
|
+
this.parent.notify('chartMouseUp', e);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
* @param {PointerEvent} e .
|
|
348
|
+
* @returns {void} .
|
|
349
|
+
*/
|
|
350
|
+
private scrollToTarget(e: PointerEvent): void {
|
|
351
|
+
const row: Element = closest(e.target as Element, 'tr');
|
|
352
|
+
if (row && this.parent.element.contains(row) &&
|
|
353
|
+
(this.parent.element.querySelectorAll('.e-chart-rows-container')[0].contains(e.target as Element) ||
|
|
354
|
+
this.parent.element.querySelectorAll('.e-gridcontent')[0].contains(e.target as Element)) &&
|
|
355
|
+
this.parent.currentViewData.length > 0) {
|
|
356
|
+
const rowIndex: number = getValue('rowIndex', closest(e.target as Element, 'tr'));
|
|
357
|
+
const dateObject: Date = this.parent.currentViewData[rowIndex].ganttProperties.startDate;
|
|
358
|
+
if (!isNullOrUndefined(dateObject)) {
|
|
359
|
+
const left: number = this.parent.dataOperation.getTaskLeft(dateObject, false);
|
|
360
|
+
if (this.parent.autoFocusTasks) {
|
|
361
|
+
this.updateScrollLeft(left);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* To focus selected task in chart side
|
|
368
|
+
*
|
|
369
|
+
* @param {number} scrollLeft .
|
|
370
|
+
* @returns {void} .
|
|
371
|
+
* @private
|
|
372
|
+
*/
|
|
373
|
+
public updateScrollLeft(scrollLeft: number): void {
|
|
374
|
+
scrollLeft = scrollLeft > 0 ? scrollLeft : 0;
|
|
375
|
+
scrollLeft = this.scrollElement.scrollWidth <= scrollLeft ? this.scrollElement.scrollWidth : scrollLeft;
|
|
376
|
+
if ((this.scrollElement.offsetWidth + this.parent.ganttChartModule.scrollElement.scrollLeft) < scrollLeft
|
|
377
|
+
|| (this.scrollElement.scrollLeft > scrollLeft)) {
|
|
378
|
+
this.scrollObject.setScrollLeft(scrollLeft - 50);
|
|
379
|
+
}
|
|
380
|
+
// this.parent.ganttChartModule.scrollObject.updateLeftPosition();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Method trigger while perform mouse up action.
|
|
385
|
+
*
|
|
386
|
+
* @param {PointerEvent} e .
|
|
387
|
+
* @returns {void}
|
|
388
|
+
* @private
|
|
389
|
+
*/
|
|
390
|
+
private mouseUp(e: PointerEvent): void {
|
|
391
|
+
if (this.parent.allowRowDragAndDrop) {
|
|
392
|
+
const ganttDragElemet: HTMLElement = this.parent.element.querySelector('.e-ganttdrag');
|
|
393
|
+
if (ganttDragElemet) {
|
|
394
|
+
ganttDragElemet.remove();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (!this.isGanttElement) {
|
|
398
|
+
this.parent.notify('chartMouseUp', e);
|
|
399
|
+
}
|
|
400
|
+
this.isGanttElement = false;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Method trigger while perform mouse up action.
|
|
404
|
+
*
|
|
405
|
+
* @param {PointerEvent} e .
|
|
406
|
+
* @returns {void} .
|
|
407
|
+
* @private
|
|
408
|
+
*/
|
|
409
|
+
private documentMouseUp(e: PointerEvent): void {
|
|
410
|
+
this.isGanttElement = true;
|
|
411
|
+
if (this.parent.allowRowDragAndDrop) {
|
|
412
|
+
const ganttDragElemet: HTMLElement = this.parent.element.querySelector('.e-ganttdrag');
|
|
413
|
+
if (ganttDragElemet) {
|
|
414
|
+
ganttDragElemet.remove();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (this.parent.isDestroyed || e.which === 3) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
let isTaskbarEdited: boolean = false;
|
|
421
|
+
if (this.parent.editSettings.allowTaskbarEditing &&
|
|
422
|
+
getValue('editModule.taskbarEditModule.isMouseDragged', this.parent) &&
|
|
423
|
+
getValue('editModule.taskbarEditModule.taskBarEditAction', this.parent)) {
|
|
424
|
+
isTaskbarEdited = true;
|
|
425
|
+
}
|
|
426
|
+
this.parent.notify('chartMouseUp', e);
|
|
427
|
+
if (this.parent.showActiveElement) {
|
|
428
|
+
if (this.focusedElement && !(e.target as HTMLElement).classList.contains('e-split-bar')) {
|
|
429
|
+
this.focusedElement.tabIndex = this.focusedElement.tabIndex === 0 ? -1 : this.focusedElement.tabIndex;
|
|
430
|
+
removeClass([this.focusedElement], 'e-active-container');
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (!isTaskbarEdited) {
|
|
434
|
+
/** Expand/collapse action */
|
|
435
|
+
const target: EventTarget = e.target;
|
|
436
|
+
const isOnTaskbarElement: boolean | Element = (e.target as HTMLElement).classList.contains(cls.taskBarMainContainer)
|
|
437
|
+
|| closest(e.target as Element, '.' + cls.taskBarMainContainer);
|
|
438
|
+
if (closest((<HTMLElement>target), '.e-gantt-parent-taskbar') && !this.parent.editSettings.allowEditing) {
|
|
439
|
+
this.chartExpandCollapseRequest(e);
|
|
440
|
+
} else if (!isOnTaskbarElement && this.parent.autoFocusTasks) {
|
|
441
|
+
this.scrollToTarget(e); /** Scroll to task */
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (this.parent.editModule && this.parent.editModule.taskbarEditModule) {
|
|
445
|
+
this.parent.editModule.taskbarEditModule.removeFalseLine(true);
|
|
446
|
+
}
|
|
447
|
+
if (!isNullOrUndefined(this.parent.onTaskbarClick) && !isTaskbarEdited) {
|
|
448
|
+
const target: EventTarget = e.target;
|
|
449
|
+
const taskbarElement: Element =
|
|
450
|
+
closest((<HTMLElement>target), '.e-gantt-parent-taskbar,.e-gantt-child-taskbar,.e-gantt-milestone');
|
|
451
|
+
if (taskbarElement) {
|
|
452
|
+
this.onTaskbarClick(e, target, taskbarElement);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* This event triggered when click on taskbar element
|
|
459
|
+
*
|
|
460
|
+
* @param {PointerEvent | KeyboardEventArgs} e .
|
|
461
|
+
* @param {EventTarget} target .
|
|
462
|
+
* @param {Element} taskbarElement .
|
|
463
|
+
* @returns {void}
|
|
464
|
+
*/
|
|
465
|
+
public onTaskbarClick(e: PointerEvent | KeyboardEventArgs, target: EventTarget, taskbarElement: Element): void {
|
|
466
|
+
const chartRow: Node = closest(target as Element, 'tr');
|
|
467
|
+
const rowIndex: number = getValue('rowIndex', chartRow);
|
|
468
|
+
const data: IGanttData = this.getRecordByTarget(e);
|
|
469
|
+
const args: ITaskbarClickEventArgs = {
|
|
470
|
+
data: data,
|
|
471
|
+
taskbarElement: taskbarElement,
|
|
472
|
+
rowIndex: rowIndex,
|
|
473
|
+
target: target as Element
|
|
474
|
+
};
|
|
475
|
+
this.parent.trigger('onTaskbarClick', args);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Method trigger while perform mouse leave action.
|
|
480
|
+
*
|
|
481
|
+
* @param {PointerEvent} e .
|
|
482
|
+
* @returns {void} .
|
|
483
|
+
* @private
|
|
484
|
+
*/
|
|
485
|
+
private ganttChartLeave(e: PointerEvent): void {
|
|
486
|
+
if (this.parent.editSettings.allowTaskbarEditing) {
|
|
487
|
+
this.parent.notify('chartMouseLeave', e);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Method trigger while perform mouse move action.
|
|
493
|
+
*
|
|
494
|
+
* @param {PointerEvent} e .
|
|
495
|
+
* @returns {void} .
|
|
496
|
+
* @private
|
|
497
|
+
*/
|
|
498
|
+
private ganttChartMove(e: PointerEvent): void {
|
|
499
|
+
if (this.parent.editSettings.allowTaskbarEditing) {
|
|
500
|
+
this.parent.notify('chartMouseMove', e);
|
|
501
|
+
if (!isNullOrUndefined(this.parent.taskFields.dependency) && this.parent.connectorLineEditModule) {
|
|
502
|
+
this.parent.connectorLineEditModule.updateConnectorLineEditElement(e);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Method trigger while perform right click action.
|
|
509
|
+
*
|
|
510
|
+
* @param {PointerEvent} e .
|
|
511
|
+
* @returns {void} .
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
private contextClick(e: PointerEvent): void {
|
|
515
|
+
if (this.parent.allowFiltering && this.parent.filterModule) {
|
|
516
|
+
this.parent.filterModule.closeFilterOnContextClick(e.srcElement as Element);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Method to trigger while perform mouse move on Gantt.
|
|
522
|
+
*
|
|
523
|
+
* @param {PointerEvent} e .
|
|
524
|
+
* @returns {void} .
|
|
525
|
+
* @private
|
|
526
|
+
*/
|
|
527
|
+
public mouseMoveHandler(e: PointerEvent): void {
|
|
528
|
+
if (!isNullOrUndefined(this.parent.onMouseMove) &&
|
|
529
|
+
(this.parent.flatData.length ||
|
|
530
|
+
(<HTMLElement>e.target).classList.contains('e-header-cell-label') ||
|
|
531
|
+
(<HTMLElement>e.target).classList.contains('e-headercell'))) {
|
|
532
|
+
const target: EventTarget = e.target;
|
|
533
|
+
const args: IMouseMoveEventArgs = { originalEvent: e };
|
|
534
|
+
const element: Element = closest((<HTMLElement>target), '.e-chart-row-cell,.e-connector-line-container,' +
|
|
535
|
+
'.e-event-markers,.e-header-cell-label,.e-rowcell,.e-headercell,.e-indicator-span');
|
|
536
|
+
if (element) {
|
|
537
|
+
let rowData: IGanttData;
|
|
538
|
+
const rowElement: Element = closest((<HTMLElement>target), '.e-rowcell,.e-chart-row-cell');
|
|
539
|
+
const columnElement: Element = closest((<HTMLElement>target), '.e-rowcell,.e-headercell');
|
|
540
|
+
if (rowElement) {
|
|
541
|
+
rowData = this.parent.ganttChartModule.getRecordByTarget(e);
|
|
542
|
+
args.data = rowData;
|
|
543
|
+
}
|
|
544
|
+
if (columnElement) {
|
|
545
|
+
const cellIndex: number = getValue('cellIndex', columnElement);
|
|
546
|
+
args.column = this.parent.treeGrid.columns[cellIndex];
|
|
547
|
+
}
|
|
548
|
+
if (closest((<HTMLElement>target), '.e-indicator-span')) {
|
|
549
|
+
let index: number = 0;
|
|
550
|
+
const indicators: IIndicator[] = rowData.ganttProperties.indicators;
|
|
551
|
+
if (indicators.length > 1) {
|
|
552
|
+
for (index = 0; index < indicators.length; index++) {
|
|
553
|
+
if (indicators[index].name === ((<HTMLElement>element).innerText).trim()) {
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
args.indicator = indicators[index];
|
|
559
|
+
}
|
|
560
|
+
if (closest((<HTMLElement>target), '.e-connector-line-container')) {
|
|
561
|
+
const obj: TooltipEventArgs = {} as TooltipEventArgs;
|
|
562
|
+
obj.target = element as HTMLElement;
|
|
563
|
+
args.predecessor = this.parent.tooltipModule.getPredecessorTooltipData(obj);
|
|
564
|
+
}
|
|
565
|
+
if (closest((<HTMLElement>target), '.e-event-markers')) {
|
|
566
|
+
const obj: TooltipEventArgs = {} as TooltipEventArgs;
|
|
567
|
+
obj.target = element as HTMLElement;
|
|
568
|
+
args.eventMarkers = this.parent.tooltipModule.getMarkerTooltipData(obj);
|
|
569
|
+
}
|
|
570
|
+
if ((<HTMLElement>target).classList.contains('e-header-cell-label')) {
|
|
571
|
+
args.date = new Date((<HTMLElement>target).dataset.content);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
this.parent.trigger('onMouseMove', args);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Double click handler for chart
|
|
580
|
+
*
|
|
581
|
+
* @param {PointerEvent} e .
|
|
582
|
+
* @returns {void} .
|
|
583
|
+
*/
|
|
584
|
+
private doubleClickHandler(e: PointerEvent): void {
|
|
585
|
+
this.parent.notify('chartDblClick', e);
|
|
586
|
+
const target: EventTarget = e.target;
|
|
587
|
+
const row: Element = closest(target as Element, 'tr');
|
|
588
|
+
const rowIndex: number = getValue('rowIndex', row);
|
|
589
|
+
const rowData: IGanttData = this.parent.ganttChartModule.getRecordByTarget(e);
|
|
590
|
+
const args: RecordDoubleClickEventArgs = {
|
|
591
|
+
row: row,
|
|
592
|
+
rowData: rowData,
|
|
593
|
+
rowIndex: rowIndex,
|
|
594
|
+
target: target as Element
|
|
595
|
+
};
|
|
596
|
+
this.recordDoubleClick(args);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* To trigger record double click event.
|
|
601
|
+
*
|
|
602
|
+
* @param {RecordDoubleClickEventArgs} args .
|
|
603
|
+
* @returns {void} .
|
|
604
|
+
* @private
|
|
605
|
+
*/
|
|
606
|
+
public recordDoubleClick(args: RecordDoubleClickEventArgs): void {
|
|
607
|
+
this.parent.trigger('recordDoubleClick', args);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* @param {PointerEvent | KeyboardEventArgs} e .
|
|
612
|
+
* @returns {IGanttData} .
|
|
613
|
+
* @private
|
|
614
|
+
*/
|
|
615
|
+
public getRecordByTarget(e: PointerEvent | KeyboardEventArgs): IGanttData {
|
|
616
|
+
let ganttData: IGanttData;
|
|
617
|
+
let row: Element = closest(e.target as Element, 'div.' + cls.taskBarMainContainer);
|
|
618
|
+
if (!isNullOrUndefined(row)) {
|
|
619
|
+
const id: string = row.getAttribute('rowUniqueId');
|
|
620
|
+
ganttData = this.parent.getRecordByID(id);
|
|
621
|
+
} else {
|
|
622
|
+
row = closest(e.target as Element, 'tr');
|
|
623
|
+
if (row) {
|
|
624
|
+
const rowIndex: number = getValue('rowIndex', closest(e.target as Element, 'tr'));
|
|
625
|
+
ganttData = this.parent.currentViewData[rowIndex];
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return ganttData;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* To get gantt chart row elements
|
|
633
|
+
*
|
|
634
|
+
* @returns {NodeListOf<Element>} .
|
|
635
|
+
* @private
|
|
636
|
+
*/
|
|
637
|
+
public getChartRows(): NodeListOf<Element> {
|
|
638
|
+
return document.getElementById(this.parent.element.id + 'GanttTaskTableBody').querySelectorAll('.e-chart-row');
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Expand Collapse operations from gantt chart side
|
|
643
|
+
*
|
|
644
|
+
* @param {PointerEvent} e .
|
|
645
|
+
* @returns {void} .
|
|
646
|
+
* @private
|
|
647
|
+
*/
|
|
648
|
+
private chartExpandCollapseRequest(e: PointerEvent): void {
|
|
649
|
+
if (this.parent.enableMultiTaskbar) {
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
const target: EventTarget = e.target;
|
|
653
|
+
const parentElement: Element = closest((<HTMLElement>target), '.e-gantt-parent-taskbar');
|
|
654
|
+
const record: IGanttData = this.getRecordByTarget(e);
|
|
655
|
+
const chartRow: Node = closest(target as Element, 'tr');
|
|
656
|
+
const rowIndex: number = getValue('rowIndex', chartRow);
|
|
657
|
+
const gridRow: Node = this.parent.treeGrid.getRows()[rowIndex];
|
|
658
|
+
const args: object = { data: record, gridRow: gridRow, chartRow: chartRow, cancel: false };
|
|
659
|
+
this.isExpandCollapseFromChart = true;
|
|
660
|
+
if (parentElement.classList.contains('e-row-expand')) {
|
|
661
|
+
this.collapseGanttRow(args);
|
|
662
|
+
} else if (parentElement.classList.contains('e-row-collapse')) {
|
|
663
|
+
this.expandGanttRow(args);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* @returns {void} .
|
|
668
|
+
* @private
|
|
669
|
+
*/
|
|
670
|
+
public reRenderConnectorLines(): void {
|
|
671
|
+
this.parent.connectorLineModule.dependencyViewContainer.innerHTML = '';
|
|
672
|
+
this.parent.connectorLineIds = [];
|
|
673
|
+
this.parent.updatedConnectorLineCollection = [];
|
|
674
|
+
this.parent.predecessorModule.createConnectorLinesCollection();
|
|
675
|
+
this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* To collapse gantt rows
|
|
680
|
+
*
|
|
681
|
+
* @param {object} args .
|
|
682
|
+
* @param {boolean} isCancel .
|
|
683
|
+
* @returns {void} .
|
|
684
|
+
* @private
|
|
685
|
+
*/
|
|
686
|
+
public collapseGanttRow(args: object, isCancel?: boolean): void {
|
|
687
|
+
if (isCancel) {
|
|
688
|
+
this.collapsedGanttRow(args);
|
|
689
|
+
} else {
|
|
690
|
+
this.parent.trigger('collapsing', args, (arg: object) => {
|
|
691
|
+
if (this.isExpandCollapseFromChart && !getValue('cancel', arg)) {
|
|
692
|
+
this.collapsedGanttRow(arg);
|
|
693
|
+
}
|
|
694
|
+
this.isExpandCollapseFromChart = false;
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* @returns {void} .
|
|
701
|
+
* @param {object} args .
|
|
702
|
+
* @private
|
|
703
|
+
*/
|
|
704
|
+
public collapsedGanttRow(args: object): void {
|
|
705
|
+
const record: IGanttData = getValue('data', args);
|
|
706
|
+
if (this.isExpandCollapseFromChart) {
|
|
707
|
+
this.expandCollapseChartRows('collapse', getValue('chartRow', args), record, null);
|
|
708
|
+
this.parent.treeGrid.collapseRow(getValue('gridRow', args), record);
|
|
709
|
+
this.isExpandCollapseFromChart = false;
|
|
710
|
+
} else {
|
|
711
|
+
this.expandCollapseChartRows('collapse', getValue('chartRow', args), record, null);
|
|
712
|
+
}
|
|
713
|
+
// To render the child record on parent row after collapsing
|
|
714
|
+
if (this.parent.viewType === 'ResourceView') {
|
|
715
|
+
this.renderMultiTaskbar(record);
|
|
716
|
+
}
|
|
717
|
+
if (!this.parent.enableVirtualization) {
|
|
718
|
+
this.parent.updateContentHeight();
|
|
719
|
+
}
|
|
720
|
+
this.updateWidthAndHeight();
|
|
721
|
+
this.reRenderConnectorLines();
|
|
722
|
+
getValue('chartRow', args).setAttribute('aria-expanded', 'false');
|
|
723
|
+
this.parent.trigger('collapsed', args);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* To expand gantt rows
|
|
728
|
+
*
|
|
729
|
+
* @returns {void} .
|
|
730
|
+
* @param {object} args .
|
|
731
|
+
* @param {boolean} isCancel .
|
|
732
|
+
* @private
|
|
733
|
+
*/
|
|
734
|
+
public expandGanttRow(args: object, isCancel?: boolean): void {
|
|
735
|
+
if (isCancel) {
|
|
736
|
+
this.expandedGanttRow(args);
|
|
737
|
+
} else {
|
|
738
|
+
this.parent.trigger('expanding', args, (arg: object) => {
|
|
739
|
+
if (this.isExpandCollapseFromChart && !getValue('cancel', arg)) {
|
|
740
|
+
this.expandedGanttRow(arg);
|
|
741
|
+
}
|
|
742
|
+
this.isExpandCollapseFromChart = false;
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* @returns {void} .
|
|
749
|
+
* @param {object} args .
|
|
750
|
+
* @private
|
|
751
|
+
*/
|
|
752
|
+
public expandedGanttRow(args: object): void {
|
|
753
|
+
const record: IGanttData = getValue('data', args);
|
|
754
|
+
if (this.isExpandCollapseFromChart) {
|
|
755
|
+
this.expandCollapseChartRows('expand', getValue('chartRow', args), record, null);
|
|
756
|
+
this.parent.treeGrid.expandRow(getValue('gridRow', args), record);
|
|
757
|
+
this.isExpandCollapseFromChart = false;
|
|
758
|
+
} else {
|
|
759
|
+
if (!this.parent.isExpandCollapseLevelMethod) {
|
|
760
|
+
this.expandCollapseChartRows('expand', getValue('chartRow', args), record, null);
|
|
761
|
+
}
|
|
762
|
+
this.parent.isExpandCollapseLevelMethod = false;
|
|
763
|
+
}
|
|
764
|
+
// To render the child record on parent row after expanding.
|
|
765
|
+
if (this.parent.viewType === 'ResourceView') {
|
|
766
|
+
this.renderMultiTaskbar(record);
|
|
767
|
+
}
|
|
768
|
+
if (!this.parent.enableVirtualization) {
|
|
769
|
+
this.parent.updateContentHeight();
|
|
770
|
+
}
|
|
771
|
+
this.updateWidthAndHeight();
|
|
772
|
+
this.reRenderConnectorLines();
|
|
773
|
+
getValue('chartRow', args).setAttribute('aria-expanded', 'true');
|
|
774
|
+
this.parent.trigger('expanded', args);
|
|
775
|
+
}
|
|
776
|
+
private renderMultiTaskbar(record: IGanttData): void {
|
|
777
|
+
if (this.parent.enableMultiTaskbar) {
|
|
778
|
+
this.parent.chartRowsModule.refreshRecords([record], true);
|
|
779
|
+
} else if (this.parent.showOverAllocation) {
|
|
780
|
+
this.parent.ganttChartModule.renderRangeContainer(this.parent.currentViewData);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* On expand collapse operation row properties will be updated here.
|
|
786
|
+
*
|
|
787
|
+
* @param {string} action .
|
|
788
|
+
* @param {Node} rowElement .
|
|
789
|
+
* @param {IGanttData} record .
|
|
790
|
+
* @param {boolean} isChild .
|
|
791
|
+
* @returns {void} .
|
|
792
|
+
* @private
|
|
793
|
+
*/
|
|
794
|
+
private expandCollapseChartRows(action: string, rowElement: Node, record: IGanttData, isChild: boolean): void {
|
|
795
|
+
let displayType: string;
|
|
796
|
+
if (action === 'expand') {
|
|
797
|
+
displayType = 'table-row';
|
|
798
|
+
if (!isChild) {
|
|
799
|
+
record.expanded = true;
|
|
800
|
+
}
|
|
801
|
+
const targetElement: NodeListOf<Element> = (rowElement as HTMLElement).querySelectorAll('.e-row-collapse');
|
|
802
|
+
for (let t: number = 0; t < targetElement.length; t++) {
|
|
803
|
+
addClass([targetElement[t]], 'e-row-expand');
|
|
804
|
+
removeClass([targetElement[t]], 'e-row-collapse');
|
|
805
|
+
}
|
|
806
|
+
} else if (action === 'collapse') {
|
|
807
|
+
displayType = 'none';
|
|
808
|
+
if (!isChild) {
|
|
809
|
+
record.expanded = false;
|
|
810
|
+
}
|
|
811
|
+
const targetElement: NodeListOf<Element> = (rowElement as HTMLElement).querySelectorAll('.e-row-expand');
|
|
812
|
+
for (let t: number = 0; t < targetElement.length; t++) {
|
|
813
|
+
addClass([targetElement[t]], 'e-row-collapse');
|
|
814
|
+
removeClass([targetElement[t]], 'e-row-expand');
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
const childRecords: IGanttData[] = record.childRecords;
|
|
818
|
+
const chartRows: NodeListOf<Element> = this.getChartRows();
|
|
819
|
+
const rows: HTMLElement[] = [];
|
|
820
|
+
for (let i: number = 0; i < chartRows.length; i++) {
|
|
821
|
+
if ((<HTMLElement>chartRows[i]).classList.contains('gridrowtaskId'
|
|
822
|
+
+ record.ganttProperties.rowUniqueID + 'level' + (record.level + 1))) {
|
|
823
|
+
rows.push(<HTMLElement>chartRows[i]);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
for (let i: number = 0; i < rows.length; i++) {
|
|
827
|
+
rows[i].style.display = displayType;
|
|
828
|
+
if ((childRecords[i].childRecords && childRecords[i].childRecords.length)
|
|
829
|
+
&& (action === 'collapse' || childRecords[i].expanded || this.isExpandAll)) {
|
|
830
|
+
this.expandCollapseChartRows(action, rows[i], childRecords[i], true);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Public method to expand or collapse all the rows of Gantt
|
|
837
|
+
*
|
|
838
|
+
* @returns {void}
|
|
839
|
+
* @param {string} action .
|
|
840
|
+
* @private
|
|
841
|
+
*/
|
|
842
|
+
public expandCollapseAll(action: string): void {
|
|
843
|
+
if (action === 'expand') {
|
|
844
|
+
this.isExpandAll = true;
|
|
845
|
+
this.parent.treeGrid.expandAll();
|
|
846
|
+
} else {
|
|
847
|
+
this.parent.treeGrid.collapseAll();
|
|
848
|
+
}
|
|
849
|
+
this.isExpandAll = false;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Public method to expand particular level of rows.
|
|
854
|
+
*
|
|
855
|
+
* @returns {void} .
|
|
856
|
+
* @param {number} level .
|
|
857
|
+
* @private
|
|
858
|
+
*/
|
|
859
|
+
public expandAtLevel(level: number): void {
|
|
860
|
+
this.parent.treeGrid.expandAtLevel(level);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Public method to collapse particular level of rows.
|
|
865
|
+
*
|
|
866
|
+
* @returns {void} .
|
|
867
|
+
* @param {number} level .
|
|
868
|
+
* @private
|
|
869
|
+
*/
|
|
870
|
+
public collapseAtLevel(level: number): void {
|
|
871
|
+
if (this.parent.enableVirtualization) {
|
|
872
|
+
this.parent.isExpandCollapseLevelMethod = true;
|
|
873
|
+
}
|
|
874
|
+
this.parent.treeGrid.collapseAtLevel(level);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Event Binding for gantt chart click
|
|
879
|
+
*
|
|
880
|
+
* @returns {void} .
|
|
881
|
+
*/
|
|
882
|
+
private wireEvents(): void {
|
|
883
|
+
const isIE11Pointer: Boolean = Browser.isPointer; // eslint-disable-line
|
|
884
|
+
const mouseDown: string = Browser.touchStartEvent;
|
|
885
|
+
const mouseUp: string = Browser.touchEndEvent;
|
|
886
|
+
const mouseMove: string = Browser.touchMoveEvent;
|
|
887
|
+
const cancel: string = isIE11Pointer ? 'pointerleave' : 'mouseleave';
|
|
888
|
+
EventHandler.add(this.parent.chartPane, mouseDown, this.ganttChartMouseDown, this);
|
|
889
|
+
EventHandler.add(this.parent.chartPane, cancel, this.ganttChartLeave, this);
|
|
890
|
+
EventHandler.add(this.parent.chartPane, mouseMove, this.ganttChartMove, this);
|
|
891
|
+
if (this.parent.isAdaptive) {
|
|
892
|
+
EventHandler.add(this.parent.chartPane, click, this.ganttChartMouseClick, this);
|
|
893
|
+
EventHandler.add(this.parent.chartPane, mouseUp, this.ganttChartMouseUp, this);
|
|
894
|
+
}
|
|
895
|
+
if (!this.parent.isAdaptive) {
|
|
896
|
+
EventHandler.add(this.parent.element, mouseUp, this.documentMouseUp, this);
|
|
897
|
+
EventHandler.add(document, mouseUp, this.mouseUp, this);
|
|
898
|
+
}
|
|
899
|
+
EventHandler.add(this.parent.element, 'mousemove', this.mouseMoveHandler, this);
|
|
900
|
+
EventHandler.add(document.body, 'contextmenu', this.contextClick, this);
|
|
901
|
+
EventHandler.add(document, 'mouseup', this.contextClick, this);
|
|
902
|
+
EventHandler.add(this.parent.chartRowsModule.ganttChartTableBody, 'dblclick', this.doubleClickHandler, this);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
private unWireEvents(): void {
|
|
906
|
+
const isIE11Pointer: Boolean = Browser.isPointer; // eslint-disable-line
|
|
907
|
+
const mouseDown: string = Browser.touchStartEvent;
|
|
908
|
+
const mouseUp: string = Browser.touchEndEvent;
|
|
909
|
+
const mouseMove: string = Browser.touchMoveEvent;
|
|
910
|
+
const cancel: string = isIE11Pointer ? 'pointerleave' : 'mouseleave';
|
|
911
|
+
EventHandler.remove(this.parent.chartRowsModule.ganttChartTableBody, mouseDown, this.ganttChartMouseDown);
|
|
912
|
+
EventHandler.remove(this.parent.chartPane, cancel, this.ganttChartLeave);
|
|
913
|
+
EventHandler.remove(this.parent.chartPane, mouseMove, this.ganttChartMove);
|
|
914
|
+
if (this.parent.isAdaptive) {
|
|
915
|
+
EventHandler.remove(this.parent.chartPane, click, this.ganttChartMouseClick);
|
|
916
|
+
EventHandler.remove(this.parent.chartPane, mouseUp, this.ganttChartMouseUp);
|
|
917
|
+
}
|
|
918
|
+
if (!this.parent.isAdaptive) {
|
|
919
|
+
EventHandler.remove(this.parent.element, mouseUp, this.documentMouseUp);
|
|
920
|
+
EventHandler.remove(document, mouseUp, this.mouseUp);
|
|
921
|
+
}
|
|
922
|
+
EventHandler.remove(this.parent.element, 'mousemove', this.mouseMoveHandler);
|
|
923
|
+
EventHandler.remove(document.body, 'contextmenu', this.contextClick);
|
|
924
|
+
EventHandler.remove(document, 'mouseup', this.contextClick);
|
|
925
|
+
EventHandler.remove(this.parent.chartRowsModule.ganttChartTableBody, 'dblclick', this.doubleClickHandler);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* To get record by taskbar element.
|
|
930
|
+
*
|
|
931
|
+
* @param {Element} target .
|
|
932
|
+
* @returns {IGanttData} .
|
|
933
|
+
* @private
|
|
934
|
+
*/
|
|
935
|
+
public getRecordByTaskBar(target: Element): IGanttData {
|
|
936
|
+
const item: IGanttData = this.parent.currentViewData[this.getIndexByTaskBar(target)];
|
|
937
|
+
return item;
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Trigger Tab & Shift + Tab keypress to highlight active element.
|
|
941
|
+
*
|
|
942
|
+
* @param {KeyboardEventArgs} e .
|
|
943
|
+
* @returns {void} .
|
|
944
|
+
* @private
|
|
945
|
+
*/
|
|
946
|
+
public onTabAction(e: KeyboardEventArgs): void {
|
|
947
|
+
this.parent.treeGrid.grid.enableHeaderFocus = this.parent.enableHeaderFocus;
|
|
948
|
+
const isInEditedState: boolean = this.parent.editModule && this.parent.editModule.cellEditModule &&
|
|
949
|
+
this.parent.editModule.cellEditModule.isCellEdit;
|
|
950
|
+
if (!this.parent.showActiveElement && !isInEditedState) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
const $target: Element = isInEditedState ? (e.target as Element).closest('.e-rowcell') : e.target as Element;
|
|
954
|
+
if ($target.closest('.e-rowcell') || $target.closest('.e-chart-row')) {
|
|
955
|
+
this.parent.focusModule.setActiveElement($target as HTMLElement);
|
|
956
|
+
}
|
|
957
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
958
|
+
this.focusedRowIndex = $target.closest('.e-rowcell') ? ($target.parentElement as any).rowIndex :
|
|
959
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
960
|
+
$target.closest('.e-chart-row') ? ($target.closest('.e-chart-row') as any).rowIndex : -1;
|
|
961
|
+
const isTab: boolean = (e.action === 'tab') ? true : false;
|
|
962
|
+
const nextElement: Element | string = this.getNextElement($target, isTab, isInEditedState);
|
|
963
|
+
if (nextElement === 'noNextRow') {
|
|
964
|
+
this.manageFocus($target as HTMLElement, 'remove', true);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
if (typeof nextElement !== 'string') {
|
|
968
|
+
if ($target.classList.contains('e-rowcell') || $target.closest('.e-chart-row-cell') ||
|
|
969
|
+
$target.classList.contains('e-headercell') || $target.closest('.e-segmented-taskbar')) {
|
|
970
|
+
e.preventDefault();
|
|
971
|
+
}
|
|
972
|
+
if(isTab && $target.classList.contains('e-rowdragdrop')){
|
|
973
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
if ($target.classList.contains('e-rowcell') && (nextElement && nextElement.classList.contains('e-rowcell')) ||
|
|
977
|
+
$target.classList.contains('e-headercell')){ // eslint-disable-line
|
|
978
|
+
if (isTab) {
|
|
979
|
+
if (this.parent.editSettings.allowNextRowEdit) {
|
|
980
|
+
const rowData: IGanttData = this.parent.currentViewData[this.focusedRowIndex];
|
|
981
|
+
const columnName: string = this.parent.ganttColumns[nextElement.getAttribute('aria-colindex')].field;
|
|
982
|
+
if (rowData.hasChildRecords) {
|
|
983
|
+
if (columnName === this.parent.taskFields.endDate || columnName ===
|
|
984
|
+
this.parent.taskFields.duration || columnName === this.parent.taskFields.dependency ||
|
|
985
|
+
columnName === this.parent.taskFields.progress || columnName === this.parent.taskFields.work ||
|
|
986
|
+
columnName === 'taskType') {
|
|
987
|
+
this.parent.treeGrid.grid.endEdit();
|
|
988
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
989
|
+
} else if (columnName === this.parent.taskFields.name || columnName === this.parent.taskFields.startDate) {
|
|
990
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
991
|
+
} else {
|
|
992
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
993
|
+
this.parent.treeGrid.editCell(this.focusedRowIndex,columnName); // eslint-disable-line
|
|
994
|
+
}
|
|
995
|
+
} else {
|
|
996
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
997
|
+
}
|
|
998
|
+
} else {
|
|
999
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
1000
|
+
}
|
|
1001
|
+
} else {
|
|
1002
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
if (!this.parent.editModule.cellEditModule.isCellEdit) {
|
|
1006
|
+
if (nextElement) {
|
|
1007
|
+
if ($target.classList.contains('e-rowcell')) {
|
|
1008
|
+
this.manageFocus($target as HTMLElement, 'remove', false);
|
|
1009
|
+
} else {
|
|
1010
|
+
this.manageFocus($target as HTMLElement, 'remove', true);
|
|
1011
|
+
}
|
|
1012
|
+
if (nextElement.classList.contains('e-rowcell') && $target.nextElementSibling) {
|
|
1013
|
+
if (!$target.classList.contains('e-rowcell')) {
|
|
1014
|
+
this.parent.treeGrid.grid.notify('key-pressed', e);
|
|
1015
|
+
const fmodule: FocusStrategy = getValue('focusModule', this.parent.treeGrid.grid);
|
|
1016
|
+
fmodule.currentInfo.element = nextElement as HTMLElement;
|
|
1017
|
+
fmodule.currentInfo.elementToFocus = nextElement as HTMLElement;
|
|
1018
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
1019
|
+
fmodule.content.matrix.current = [(nextElement.parentElement as any).rowIndex, (nextElement as any).cellIndex];
|
|
1020
|
+
}
|
|
1021
|
+
this.manageFocus(nextElement as HTMLElement, 'add', false);
|
|
1022
|
+
} else {
|
|
1023
|
+
this.manageFocus(nextElement as HTMLElement, 'add', true);
|
|
1024
|
+
}
|
|
1025
|
+
this.parent.focusModule.setActiveElement(nextElement as HTMLElement);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Get next/previous sibling element.
|
|
1032
|
+
*
|
|
1033
|
+
* @param {Element} $target .
|
|
1034
|
+
* @param {boolean} isTab .
|
|
1035
|
+
* @param {boolean} isInEditedState .
|
|
1036
|
+
* @returns {Element | string} .
|
|
1037
|
+
*/
|
|
1038
|
+
private getNextElement($target: Element, isTab: boolean, isInEditedState: boolean): Element | string {
|
|
1039
|
+
let nextElement: Element = isTab ? $target.nextElementSibling : $target.previousElementSibling;
|
|
1040
|
+
while (nextElement && nextElement.parentElement.classList.contains('e-row')) {
|
|
1041
|
+
if (!nextElement.matches('.e-hide') && !nextElement.matches('.e-rowdragdrop')) {
|
|
1042
|
+
return nextElement;
|
|
1043
|
+
}
|
|
1044
|
+
nextElement = isTab ? nextElement.nextElementSibling : nextElement.previousElementSibling;
|
|
1045
|
+
}
|
|
1046
|
+
if (!isNullOrUndefined(nextElement) && (nextElement.classList.contains('e-taskbar-main-container')
|
|
1047
|
+
|| nextElement.classList.contains('e-right-connectorpoint-outer-div'))) {
|
|
1048
|
+
const record: IGanttData = this.parent.currentViewData[this.focusedRowIndex];
|
|
1049
|
+
if (!isNullOrUndefined(record.ganttProperties.segments) && record.ganttProperties.segments.length > 0) {
|
|
1050
|
+
nextElement = nextElement.classList.contains('e-right-connectorpoint-outer-div')
|
|
1051
|
+
? nextElement.parentElement.nextElementSibling
|
|
1052
|
+
: nextElement.getElementsByClassName('e-gantt-child-taskbar-inner-div')[0];
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (this.validateNextElement(nextElement)) {
|
|
1056
|
+
return nextElement;
|
|
1057
|
+
} else {
|
|
1058
|
+
let rowIndex: number = -1;
|
|
1059
|
+
let rowElement: Element = null;
|
|
1060
|
+
let childElement: Element | string;
|
|
1061
|
+
if ($target.classList.contains('e-rowcell') && isInEditedState && this.parent.editSettings.allowNextRowEdit) {
|
|
1062
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
1063
|
+
rowIndex = ($target.parentElement as any).rowIndex;
|
|
1064
|
+
rowElement = this.getNextRowElement(rowIndex, isTab, true);
|
|
1065
|
+
childElement = this.getChildElement(rowElement, isTab);
|
|
1066
|
+
return childElement;
|
|
1067
|
+
} else if ($target.classList.contains('e-rowcell')) {
|
|
1068
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
1069
|
+
rowIndex = ($target.parentElement as any).rowIndex;
|
|
1070
|
+
if (isTab) {
|
|
1071
|
+
rowElement = this.parent.getRowByIndex(rowIndex);
|
|
1072
|
+
if (this.validateNextElement(rowElement, 'e-left-label-container')) {
|
|
1073
|
+
return rowElement.getElementsByClassName('e-left-label-container')[0];
|
|
1074
|
+
} else if (this.validateNextElement(rowElement, 'e-taskbar-main-container')) {
|
|
1075
|
+
return rowElement.getElementsByClassName('e-taskbar-main-container')[0];
|
|
1076
|
+
} else if (this.validateNextElement(rowElement, 'e-right-label-container')) {
|
|
1077
|
+
return rowElement.getElementsByClassName('e-right-label-container')[0];
|
|
1078
|
+
}
|
|
1079
|
+
} else {
|
|
1080
|
+
rowElement = this.getNextRowElement(rowIndex, isTab, false);
|
|
1081
|
+
if (this.validateNextElement(rowElement, 'e-right-label-container')) {
|
|
1082
|
+
return rowElement.getElementsByClassName('e-right-label-container')[0];
|
|
1083
|
+
} else if (this.validateNextElement(rowElement, 'e-taskbar-main-container')) {
|
|
1084
|
+
return rowElement.getElementsByClassName('e-taskbar-main-container')[0];
|
|
1085
|
+
} else if (this.validateNextElement(rowElement, 'e-left-label-container')) {
|
|
1086
|
+
return rowElement.getElementsByClassName('e-left-label-container')[0];
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
} else if ($target.parentElement.classList.contains('e-chart-row-cell') ||
|
|
1090
|
+
$target.parentElement.parentElement.classList.contains('e-chart-row-cell')) {
|
|
1091
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
1092
|
+
rowIndex = (closest($target, '.e-chart-row') as any).rowIndex;
|
|
1093
|
+
if (isTab) {
|
|
1094
|
+
rowElement = this.getNextRowElement(rowIndex, isTab, true);
|
|
1095
|
+
} else {
|
|
1096
|
+
rowElement = this.parent.treeGrid.grid.getRowByIndex(rowIndex);
|
|
1097
|
+
}
|
|
1098
|
+
const childElement : Element | string = this.getChildElement(rowElement, isTab);
|
|
1099
|
+
return childElement;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
return null;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Get next/previous row element.
|
|
1106
|
+
*
|
|
1107
|
+
* @param {number} rowIndex .
|
|
1108
|
+
* @param {boolean} isTab .
|
|
1109
|
+
* @param {boolean} isChartRow .
|
|
1110
|
+
* @returns {Element} .
|
|
1111
|
+
*/
|
|
1112
|
+
private getNextRowElement(rowIndex: number, isTab: boolean, isChartRow: boolean): Element {
|
|
1113
|
+
const expandedRecords: IGanttData[] = this.parent.getExpandedRecords(this.parent.currentViewData);
|
|
1114
|
+
const currentItem: IGanttData = this.parent.currentViewData[rowIndex];
|
|
1115
|
+
const expandedRecordIndex: number = expandedRecords.indexOf(currentItem);
|
|
1116
|
+
const nextRecord: IGanttData = isTab ? expandedRecords[expandedRecordIndex + 1] : expandedRecords[expandedRecordIndex - 1];
|
|
1117
|
+
const nextRowIndex: number = this.parent.currentViewData.indexOf(nextRecord);
|
|
1118
|
+
if (nextRecord) {
|
|
1119
|
+
return isChartRow ? this.parent.treeGrid.grid.getRowByIndex(nextRowIndex) : this.parent.getRowByIndex(nextRowIndex);
|
|
1120
|
+
} else {
|
|
1121
|
+
return null;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Validate next/previous sibling element haschilds.
|
|
1126
|
+
*
|
|
1127
|
+
* @param {Element} $target .
|
|
1128
|
+
* @param {string} className .
|
|
1129
|
+
* @returns {boolean} .
|
|
1130
|
+
*/
|
|
1131
|
+
private validateNextElement($target: Element, className?: string): boolean {
|
|
1132
|
+
if ($target && $target.classList.contains('e-rowcell')) {
|
|
1133
|
+
return true;
|
|
1134
|
+
}
|
|
1135
|
+
if ($target && className) {
|
|
1136
|
+
const elementByClass: Element = $target.getElementsByClassName(className)[0];
|
|
1137
|
+
return (elementByClass && elementByClass.hasChildNodes()) ? true : false;
|
|
1138
|
+
} else if ($target) {
|
|
1139
|
+
return (!isNullOrUndefined($target) && $target.hasChildNodes()) ? true : false;
|
|
1140
|
+
}
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Getting child element based on row element.
|
|
1145
|
+
*
|
|
1146
|
+
* @param {Element} rowElement .
|
|
1147
|
+
* @param {boolean} isTab .
|
|
1148
|
+
* @returns {Element | string} .
|
|
1149
|
+
*/
|
|
1150
|
+
private getChildElement(rowElement: Element, isTab?: boolean): Element | string {
|
|
1151
|
+
let childElement: Element;
|
|
1152
|
+
if (rowElement) {
|
|
1153
|
+
childElement = isTab ? rowElement.children[0] : rowElement.children[rowElement.children.length - 1];
|
|
1154
|
+
while (childElement) {
|
|
1155
|
+
if (!childElement.matches('.e-hide') && !childElement.matches('.e-rowdragdrop')) {
|
|
1156
|
+
return childElement;
|
|
1157
|
+
}
|
|
1158
|
+
childElement = isTab ? childElement.nextElementSibling : childElement.previousElementSibling;
|
|
1159
|
+
}
|
|
1160
|
+
} else {
|
|
1161
|
+
return 'noNextRow';
|
|
1162
|
+
}
|
|
1163
|
+
return childElement;
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Add/Remove active element.
|
|
1167
|
+
*
|
|
1168
|
+
* @private
|
|
1169
|
+
* @param {HTMLElement} element .
|
|
1170
|
+
* @param {string} focus .
|
|
1171
|
+
* @param {boolean} isChartElement .
|
|
1172
|
+
* @returns {void} .
|
|
1173
|
+
*/
|
|
1174
|
+
public manageFocus(element: HTMLElement, focus: string, isChartElement?: boolean): void {
|
|
1175
|
+
if (isChartElement) {
|
|
1176
|
+
let childElement: Element = null;
|
|
1177
|
+
if (element.classList.contains('e-left-label-container') ||
|
|
1178
|
+
element.classList.contains('e-right-label-container')) {
|
|
1179
|
+
childElement = element.getElementsByTagName('span')[0];
|
|
1180
|
+
} else if (element.classList.contains('e-taskbar-main-container')
|
|
1181
|
+
|| element.classList.contains('e-gantt-child-taskbar-inner-div')) {
|
|
1182
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
1183
|
+
const rowIndex: number = (closest(element, '.e-chart-row') as any).rowIndex;
|
|
1184
|
+
const data: IGanttData = this.parent.currentViewData[rowIndex];
|
|
1185
|
+
const className: string = data.hasChildRecords ? data.ganttProperties.isAutoSchedule ? 'e-gantt-parent-taskbar' :
|
|
1186
|
+
'e-manualparent-main-container' :
|
|
1187
|
+
data.ganttProperties.isMilestone ? 'e-gantt-milestone' : !isNullOrUndefined(data.ganttProperties.segments)
|
|
1188
|
+
&& data.ganttProperties.segments.length > 0 ? 'e-segmented-taskbar' : 'e-gantt-child-taskbar';
|
|
1189
|
+
childElement = element.getElementsByClassName(className)[0];
|
|
1190
|
+
if (isNullOrUndefined(childElement)) {
|
|
1191
|
+
childElement = element;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
if (focus === 'add' && !isNullOrUndefined(childElement)) {
|
|
1195
|
+
element.setAttribute('tabIndex', '0');
|
|
1196
|
+
addClass([childElement], 'e-active-container');
|
|
1197
|
+
element.focus();
|
|
1198
|
+
this.focusedElement = childElement as HTMLElement;
|
|
1199
|
+
} else if (!isNullOrUndefined(childElement)) {
|
|
1200
|
+
removeClass([childElement], 'e-active-container');
|
|
1201
|
+
element.setAttribute('tabIndex', '-1');
|
|
1202
|
+
element.blur();
|
|
1203
|
+
}
|
|
1204
|
+
} else {
|
|
1205
|
+
if (focus === 'add') {
|
|
1206
|
+
element.setAttribute('tabIndex', '0');
|
|
1207
|
+
addClass([element], ['e-focused', 'e-focus']);
|
|
1208
|
+
element.focus();
|
|
1209
|
+
} else {
|
|
1210
|
+
element.setAttribute('tabIndex', '-1');
|
|
1211
|
+
removeClass([element], ['e-focused', 'e-focus']);
|
|
1212
|
+
element.blur();
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* To get index by taskbar element.
|
|
1218
|
+
*
|
|
1219
|
+
* @param {Element} target .
|
|
1220
|
+
* @returns {number} .
|
|
1221
|
+
* @private
|
|
1222
|
+
*/
|
|
1223
|
+
public getIndexByTaskBar(target: Element): number {
|
|
1224
|
+
let row: Element;
|
|
1225
|
+
let recordIndex: number;
|
|
1226
|
+
if (!target.classList.contains(cls.taskBarMainContainer)) {
|
|
1227
|
+
row = closest(target, 'div.' + cls.taskBarMainContainer);
|
|
1228
|
+
} else {
|
|
1229
|
+
row = target;
|
|
1230
|
+
}
|
|
1231
|
+
if (isNullOrUndefined(row)) {
|
|
1232
|
+
row = closest(target, 'tr.' + cls.chartRow);
|
|
1233
|
+
recordIndex = [].slice.call(this.parent.chartRowsModule.ganttChartTableBody.childNodes).indexOf(row);
|
|
1234
|
+
} else {
|
|
1235
|
+
const id: string = row.getAttribute('rowUniqueId');
|
|
1236
|
+
const record: IGanttData = this.parent.getRecordByID(id);
|
|
1237
|
+
recordIndex = this.parent.currentViewData.indexOf(record);
|
|
1238
|
+
}
|
|
1239
|
+
return recordIndex;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
private destroy(): void {
|
|
1243
|
+
this.removeEventListener();
|
|
1244
|
+
this.unWireEvents();
|
|
1245
|
+
this.scrollObject.destroy();
|
|
1246
|
+
this.scrollObject = null;
|
|
1247
|
+
}
|
|
1248
|
+
}
|