@worktile/gantt 15.0.0-next.0 → 15.1.0-next.0

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.
Files changed (56) hide show
  1. package/class/event.d.ts +13 -0
  2. package/class/item.d.ts +7 -1
  3. package/components/bar/bar-drag.d.ts +10 -0
  4. package/components/bar/bar.component.d.ts +2 -1
  5. package/components/bar/bar.component.scss +22 -0
  6. package/components/calendar/calendar.scss +91 -0
  7. package/components/calendar/grid/calendar-grid.component.d.ts +24 -0
  8. package/components/calendar/header/calendar-header.component.d.ts +21 -0
  9. package/components/icon/icons.d.ts +1 -0
  10. package/components/links/links.component.d.ts +5 -5
  11. package/components/main/gantt-main.component.d.ts +3 -3
  12. package/components/table/body/gantt-table-body.component.d.ts +58 -0
  13. package/components/table/gantt-table.component.scss +169 -85
  14. package/components/table/gantt-table.scss +271 -0
  15. package/components/table/header/gantt-table-header.component.d.ts +31 -0
  16. package/esm2020/class/event.mjs +5 -1
  17. package/esm2020/class/item.mjs +9 -4
  18. package/esm2020/components/bar/bar-drag.mjs +106 -42
  19. package/esm2020/components/bar/bar.component.mjs +8 -2
  20. package/esm2020/components/calendar/grid/calendar-grid.component.mjs +71 -0
  21. package/esm2020/components/calendar/header/calendar-header.component.mjs +67 -0
  22. package/esm2020/components/icon/icons.mjs +4 -2
  23. package/esm2020/components/links/links.component.mjs +72 -54
  24. package/esm2020/components/main/gantt-main.component.mjs +5 -5
  25. package/esm2020/components/table/body/gantt-table-body.component.mjs +286 -0
  26. package/esm2020/components/table/header/gantt-table-header.component.mjs +140 -0
  27. package/esm2020/gantt-dom.service.mjs +8 -12
  28. package/esm2020/gantt-item-upper.mjs +15 -6
  29. package/esm2020/gantt-print.service.mjs +2 -2
  30. package/esm2020/gantt-upper.mjs +18 -15
  31. package/esm2020/gantt.component.mjs +114 -24
  32. package/esm2020/gantt.module.mjs +25 -10
  33. package/esm2020/root.component.mjs +10 -8
  34. package/esm2020/table/gantt-column.component.mjs +4 -2
  35. package/esm2020/table/gantt-table.component.mjs +12 -4
  36. package/esm2020/utils/helpers.mjs +11 -1
  37. package/fesm2015/worktile-gantt.mjs +903 -373
  38. package/fesm2015/worktile-gantt.mjs.map +1 -1
  39. package/fesm2020/worktile-gantt.mjs +894 -375
  40. package/fesm2020/worktile-gantt.mjs.map +1 -1
  41. package/gantt-dom.service.d.ts +1 -0
  42. package/gantt-item-upper.d.ts +3 -2
  43. package/gantt-upper.d.ts +4 -1
  44. package/gantt.component.d.ts +20 -7
  45. package/gantt.component.scss +35 -0
  46. package/gantt.module.d.ts +18 -15
  47. package/package.json +1 -1
  48. package/root.component.d.ts +1 -1
  49. package/styles/index.scss +4 -2
  50. package/styles/variables.scss +9 -7
  51. package/table/gantt-column.component.d.ts +2 -1
  52. package/table/gantt-table.component.d.ts +5 -2
  53. package/components/calendar/calendar.component.d.ts +0 -26
  54. package/components/table/gantt-table.component.d.ts +0 -41
  55. package/esm2020/components/calendar/calendar.component.mjs +0 -88
  56. package/esm2020/components/table/gantt-table.component.mjs +0 -161
@@ -1,16 +1,18 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, ContentChild, HostBinding, Component, Pipe, ViewChild, Injectable, PLATFORM_ID, ElementRef, Optional, SkipSelf, ViewChildren, forwardRef, ChangeDetectionStrategy, ContentChildren, NgModule } from '@angular/core';
2
+ import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, ContentChild, HostBinding, Component, Injectable, ViewChild, Pipe, ViewChildren, PLATFORM_ID, ElementRef, Optional, SkipSelf, forwardRef, ChangeDetectionStrategy, ContentChildren, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
- import { isPlatformServer, CommonModule } from '@angular/common';
5
- import { take, takeUntil, skip, debounceTime, map, pairwise, auditTime, startWith, switchMap, finalize } from 'rxjs/operators';
6
- import { BehaviorSubject, Subject, from, merge, fromEvent, Observable, EMPTY } from 'rxjs';
4
+ import { DOCUMENT, isPlatformServer, CommonModule } from '@angular/common';
5
+ import { take, takeUntil, skip, switchMap, debounceTime as debounceTime$1, map, pairwise, auditTime, startWith as startWith$1, finalize } from 'rxjs/operators';
6
+ import { BehaviorSubject, Subject, from, takeUntil as takeUntil$1, startWith, debounceTime, filter, merge, EMPTY, fromEvent, Observable } from 'rxjs';
7
7
  import { fromUnixTime, getWeek, getDaysInMonth, differenceInCalendarDays, setDate, addSeconds, addMinutes, addHours, addDays, addWeeks, addMonths, addQuarters, addYears, startOfDay, startOfWeek, startOfMonth, startOfQuarter, startOfYear, endOfDay, endOfWeek, endOfMonth, endOfQuarter, endOfYear, getUnixTime, format, isWeekend, isToday, differenceInDays, differenceInCalendarQuarters, eachMonthOfInterval, eachYearOfInterval, eachWeekOfInterval, eachDayOfInterval, differenceInCalendarYears } from 'date-fns';
8
8
  export { addDays, addHours, addMinutes, addMonths, addQuarters, addSeconds, addWeeks, addYears, differenceInCalendarDays, differenceInCalendarQuarters, differenceInDays, eachDayOfInterval, eachMonthOfInterval, eachWeekOfInterval, endOfDay, endOfMonth, endOfQuarter, endOfWeek, endOfYear, format, fromUnixTime, getDaysInMonth, getUnixTime, getWeek, isToday, isWeekend, setDate, startOfDay, startOfMonth, startOfQuarter, startOfWeek, startOfYear } from 'date-fns';
9
9
  import { SelectionModel } from '@angular/cdk/collections';
10
10
  import { coerceBooleanProperty, coerceCssPixelValue } from '@angular/cdk/coercion';
11
- import * as i1$1 from '@angular/cdk/drag-drop';
12
- import { DragDropModule } from '@angular/cdk/drag-drop';
13
- import { __decorate, __param, __awaiter } from 'tslib';
11
+ import * as i2$1 from '@angular/cdk/scrolling';
12
+ import { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';
13
+ import { __awaiter, __decorate, __param } from 'tslib';
14
+ import * as i2 from '@angular/cdk/drag-drop';
15
+ import { CdkDrag, DragDropModule } from '@angular/cdk/drag-drop';
14
16
 
15
17
  class GanttDatePoint {
16
18
  constructor(start, text, x, y, additions, style) {
@@ -37,6 +39,10 @@ class GanttBarClickEvent {
37
39
  }
38
40
  class GanttSelectedEvent {
39
41
  }
42
+ class GanttTableDragDroppedEvent {
43
+ }
44
+ class GanttTableDragEnterPredicateContext {
45
+ }
40
46
 
41
47
  class GanttDate {
42
48
  constructor(date) {
@@ -225,7 +231,7 @@ class GanttItemInternal {
225
231
  get refs() {
226
232
  return this.refs$.getValue();
227
233
  }
228
- constructor(item, options) {
234
+ constructor(item, level, options) {
229
235
  this.refs$ = new BehaviorSubject(null);
230
236
  this.origin = item;
231
237
  this.id = this.origin.id;
@@ -244,14 +250,16 @@ class GanttItemInternal {
244
250
  this.barStyle = this.origin.barStyle;
245
251
  this.linkable = this.origin.linkable === undefined ? true : this.origin.linkable;
246
252
  this.draggable = this.origin.draggable === undefined ? true : this.origin.draggable;
253
+ this.itemDraggable = this.origin.itemDraggable;
247
254
  this.expandable = this.origin.expandable || (this.origin.children || []).length > 0;
248
255
  this.expanded = this.origin.expanded === undefined ? false : this.origin.expanded;
249
256
  this.start = item.start ? new GanttDate(item.start) : null;
250
257
  this.end = item.end ? new GanttDate(item.end) : null;
258
+ this.level = level;
251
259
  // 默认填充 30 天
252
260
  this.fillDays = (options === null || options === void 0 ? void 0 : options.fillDays) || 30;
253
261
  this.children = (item.children || []).map((subItem) => {
254
- return new GanttItemInternal(subItem, { fillDays: this.fillDays });
262
+ return new GanttItemInternal(subItem, level + 1, { fillDays: this.fillDays });
255
263
  });
256
264
  this.type = this.origin.type || GanttItemType.bar;
257
265
  this.progress = this.origin.progress;
@@ -278,10 +286,13 @@ class GanttItemInternal {
278
286
  this.origin.start = this.start.getUnixTime();
279
287
  this.origin.end = this.end.getUnixTime();
280
288
  }
289
+ updateLevel(level) {
290
+ this.level = level;
291
+ }
281
292
  addChildren(items) {
282
293
  this.origin.children = items;
283
294
  this.children = (items || []).map((subItem) => {
284
- return new GanttItemInternal(subItem, { fillDays: this.fillDays });
295
+ return new GanttItemInternal(subItem, this.level + 1, { fillDays: this.fillDays });
285
296
  });
286
297
  }
287
298
  setExpand(expanded) {
@@ -803,6 +814,16 @@ function flatten(array) {
803
814
  return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
804
815
  }, []);
805
816
  }
817
+ // export function recursiveItems(items: GanttItemInternal[]) {
818
+ // const result = [];
819
+ // (items || []).forEach((item) => {
820
+ // result.push(item);
821
+ // if (item.expanded && item.children) {
822
+ // result.push(...recursiveItems(item.children));
823
+ // }
824
+ // });
825
+ // return result;
826
+ // }
806
827
  function recursiveItems(items) {
807
828
  const result = [];
808
829
  (items || []).forEach((item) => {
@@ -890,6 +911,7 @@ class GanttUpper {
890
911
  this.barClick = new EventEmitter();
891
912
  this.viewChange = new EventEmitter();
892
913
  this.expandChange = new EventEmitter();
914
+ this.computeAllRefs = true;
893
915
  this.linkDragEnded = new EventEmitter();
894
916
  this.items = [];
895
917
  this.groups = [];
@@ -924,7 +946,7 @@ class GanttUpper {
924
946
  var _a;
925
947
  const group = this.groupsMap[origin.group_id];
926
948
  if (group) {
927
- const item = new GanttItemInternal(origin, { fillDays: (_a = this.view.options) === null || _a === void 0 ? void 0 : _a.fillDays });
949
+ const item = new GanttItemInternal(origin, 0, { fillDays: (_a = this.view.options) === null || _a === void 0 ? void 0 : _a.fillDays });
928
950
  group.items.push(item);
929
951
  }
930
952
  });
@@ -932,7 +954,7 @@ class GanttUpper {
932
954
  else {
933
955
  this.originItems.forEach((origin) => {
934
956
  var _a;
935
- const item = new GanttItemInternal(origin, { fillDays: (_a = this.view.options) === null || _a === void 0 ? void 0 : _a.fillDays });
957
+ const item = new GanttItemInternal(origin, 0, { fillDays: (_a = this.view.options) === null || _a === void 0 ? void 0 : _a.fillDays });
936
958
  this.items.push(item);
937
959
  });
938
960
  }
@@ -992,12 +1014,17 @@ class GanttUpper {
992
1014
  };
993
1015
  }
994
1016
  computeRefs() {
995
- this.groups.forEach((group) => {
996
- const groupItems = recursiveItems(group.items);
997
- this.computeItemsRefs(...groupItems);
998
- });
999
- const items = recursiveItems(this.items);
1000
- this.computeItemsRefs(...items);
1017
+ if (this.computeAllRefs) {
1018
+ this.groups.forEach((group) => {
1019
+ const groupItems = recursiveItems(group.items);
1020
+ this.computeItemsRefs(...groupItems);
1021
+ });
1022
+ const items = recursiveItems(this.items);
1023
+ this.computeItemsRefs(...items);
1024
+ }
1025
+ }
1026
+ initSelectionModel() {
1027
+ return new SelectionModel(this.multiple, []);
1001
1028
  }
1002
1029
  expandGroups(expanded) {
1003
1030
  this.groups.forEach((group) => {
@@ -1006,9 +1033,6 @@ class GanttUpper {
1006
1033
  this.expandChange.next(null);
1007
1034
  this.cdr.detectChanges();
1008
1035
  }
1009
- initSelectionModel() {
1010
- return new SelectionModel(this.multiple, []);
1011
- }
1012
1036
  ngOnInit() {
1013
1037
  this.styles = Object.assign({}, defaultStyles, this.styles);
1014
1038
  this.viewOptions.dateFormat = Object.assign({}, defaultConfig.dateFormat, this.config.dateFormat, this.viewOptions.dateFormat);
@@ -1036,8 +1060,8 @@ class GanttUpper {
1036
1060
  });
1037
1061
  this.dragContainer.dragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
1038
1062
  this.dragEnded.emit(event);
1039
- this.computeRefs();
1040
- this.detectChanges();
1063
+ // this.computeRefs();
1064
+ // this.detectChanges();
1041
1065
  });
1042
1066
  });
1043
1067
  });
@@ -1084,12 +1108,12 @@ class GanttUpper {
1084
1108
  detectChanges() {
1085
1109
  this.cdr.detectChanges();
1086
1110
  }
1111
+ // public functions
1087
1112
  expandGroup(group) {
1088
1113
  group.setExpand(!group.expanded);
1089
1114
  this.expandChange.emit(group);
1090
1115
  this.cdr.detectChanges();
1091
1116
  }
1092
- // public functions
1093
1117
  expandAll() {
1094
1118
  this.expandGroups(true);
1095
1119
  }
@@ -1223,7 +1247,7 @@ class NgxGanttTableColumnComponent {
1223
1247
  }
1224
1248
  }
1225
1249
  NgxGanttTableColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableColumnComponent, deps: [{ token: GANTT_UPPER_TOKEN }], target: i0.ɵɵFactoryTarget.Component });
1226
- NgxGanttTableColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableColumnComponent, selector: "ngx-gantt-column", inputs: { width: "width", name: "name" }, queries: [{ propertyName: "templateRef", first: true, predicate: ["cell"], descendants: true, static: true }, { propertyName: "headerTemplateRef", first: true, predicate: ["header"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1250
+ NgxGanttTableColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableColumnComponent, selector: "ngx-gantt-column", inputs: { width: "width", name: "name", showExpandIcon: "showExpandIcon" }, queries: [{ propertyName: "templateRef", first: true, predicate: ["cell"], descendants: true, static: true }, { propertyName: "headerTemplateRef", first: true, predicate: ["header"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1227
1251
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableColumnComponent, decorators: [{
1228
1252
  type: Component,
1229
1253
  args: [{
@@ -1239,6 +1263,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1239
1263
  type: Input
1240
1264
  }], name: [{
1241
1265
  type: Input
1266
+ }], showExpandIcon: [{
1267
+ type: Input
1242
1268
  }], templateRef: [{
1243
1269
  type: ContentChild,
1244
1270
  args: ['cell', { static: true }]
@@ -1249,18 +1275,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1249
1275
 
1250
1276
  class NgxGanttTableComponent {
1251
1277
  constructor() {
1278
+ this.draggable = false;
1279
+ this.dragDropped = new EventEmitter();
1252
1280
  this.columnChanges = new EventEmitter();
1253
1281
  }
1254
1282
  }
1255
1283
  NgxGanttTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1256
- NgxGanttTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableComponent, selector: "ngx-gantt-table", outputs: { columnChanges: "columnChanges" }, queries: [{ propertyName: "rowBeforeTemplate", first: true, predicate: ["rowBeforeSlot"], descendants: true, static: true }, { propertyName: "rowAfterTemplate", first: true, predicate: ["rowAfterSlot"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1284
+ NgxGanttTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableComponent, selector: "ngx-gantt-table", inputs: { draggable: "draggable", dropEnterPredicate: "dropEnterPredicate" }, outputs: { dragDropped: "dragDropped", columnChanges: "columnChanges" }, queries: [{ propertyName: "rowBeforeTemplate", first: true, predicate: ["rowBeforeSlot"], descendants: true, static: true }, { propertyName: "rowAfterTemplate", first: true, predicate: ["rowAfterSlot"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1257
1285
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, decorators: [{
1258
1286
  type: Component,
1259
1287
  args: [{
1260
1288
  selector: 'ngx-gantt-table',
1261
1289
  template: ''
1262
1290
  }]
1263
- }], propDecorators: { columnChanges: [{
1291
+ }], propDecorators: { draggable: [{
1292
+ type: Input
1293
+ }], dropEnterPredicate: [{
1294
+ type: Input
1295
+ }], dragDropped: [{
1296
+ type: Output
1297
+ }], columnChanges: [{
1264
1298
  type: Output
1265
1299
  }], rowBeforeTemplate: [{
1266
1300
  type: ContentChild,
@@ -1272,6 +1306,100 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1272
1306
 
1273
1307
  const GANTT_ABSTRACT_TOKEN = new InjectionToken('gantt-abstract-token');
1274
1308
 
1309
+ class GanttPrintService {
1310
+ constructor() { }
1311
+ setInlineStyles(targetElem) {
1312
+ const svgElements = Array.from(targetElem.getElementsByTagName('svg'));
1313
+ for (const svgElement of svgElements) {
1314
+ this.recursElementChildren(svgElement);
1315
+ }
1316
+ }
1317
+ recursElementChildren(node) {
1318
+ const transformProperties = [
1319
+ 'fill',
1320
+ 'color',
1321
+ 'font-size',
1322
+ 'stroke',
1323
+ 'font',
1324
+ 'text-anchor',
1325
+ 'stroke-dasharray',
1326
+ 'shape-rendering',
1327
+ 'stroke-width'
1328
+ ];
1329
+ if (!node.style) {
1330
+ return;
1331
+ }
1332
+ const styles = getComputedStyle(node);
1333
+ for (const transformProperty of transformProperties) {
1334
+ node.style[transformProperty] = styles[transformProperty];
1335
+ }
1336
+ for (const child of Array.from(node.childNodes)) {
1337
+ this.recursElementChildren(child);
1338
+ }
1339
+ }
1340
+ register(root) {
1341
+ this.root = root.nativeElement;
1342
+ this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
1343
+ }
1344
+ print(name = 'download', ignoreElementClass) {
1345
+ return __awaiter(this, void 0, void 0, function* () {
1346
+ const root = this.root;
1347
+ const mainContainer = this.mainContainer;
1348
+ // set print width
1349
+ const printWidth = root.offsetWidth;
1350
+ // set print height
1351
+ const printHeight = root.offsetHeight - mainContainer.offsetHeight + mainContainer.scrollHeight;
1352
+ const html2canvas = (yield import(/* webpackChunkName: 'html2canvas' */ 'html2canvas')).default;
1353
+ html2canvas(root, {
1354
+ logging: false,
1355
+ allowTaint: true,
1356
+ useCORS: true,
1357
+ width: printWidth,
1358
+ height: printHeight,
1359
+ ignoreElements: (element) => {
1360
+ if (ignoreElementClass && element.classList.contains(ignoreElementClass)) {
1361
+ return true;
1362
+ }
1363
+ if (element.classList.contains('gantt-calendar-today-overlay')) {
1364
+ return true;
1365
+ }
1366
+ },
1367
+ onclone: (cloneDocument) => {
1368
+ const ganttClass = root.className;
1369
+ const cloneGanttDom = cloneDocument.querySelector(`.${ganttClass.replace(/\s+/g, '.')}`);
1370
+ const cloneGanttContainerDom = cloneDocument.querySelector('.gantt-container');
1371
+ const cloneCalendarOverlay = cloneDocument.querySelector('.gantt-calendar-grid-main');
1372
+ const cloneLinksOverlay = cloneDocument.querySelector('.gantt-links-overlay-main');
1373
+ // change targetDom width
1374
+ cloneGanttDom.style.width = `${printWidth}px`;
1375
+ cloneGanttDom.style.height = `${printHeight}px`;
1376
+ cloneGanttDom.style.overflow = `unset`;
1377
+ cloneGanttContainerDom.style.backgroundColor = '#fff';
1378
+ cloneCalendarOverlay.setAttribute('height', `${printHeight}`);
1379
+ cloneCalendarOverlay.setAttribute('style', `background: transparent`);
1380
+ if (cloneLinksOverlay) {
1381
+ cloneLinksOverlay.setAttribute('height', `${printHeight}`);
1382
+ cloneLinksOverlay.setAttribute('style', `height: ${printHeight}px`);
1383
+ }
1384
+ // setInlineStyles for svg
1385
+ this.setInlineStyles(cloneGanttDom);
1386
+ }
1387
+ }).then((canvas) => {
1388
+ const link = document.createElement('a');
1389
+ const dataUrl = canvas.toDataURL('image/png');
1390
+ link.download = `${name}.png`;
1391
+ link.href = dataUrl;
1392
+ link.click();
1393
+ });
1394
+ });
1395
+ }
1396
+ }
1397
+ GanttPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1398
+ GanttPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService });
1399
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, decorators: [{
1400
+ type: Injectable
1401
+ }], ctorParameters: function () { return []; } });
1402
+
1275
1403
  const supports = (typeof window !== 'undefined' && !!window.CSS && CSS.supports) || (() => false);
1276
1404
  /**
1277
1405
  * Note: we don't need to add vendor prefixes within `.scss` files since they're added automatically.
@@ -1287,6 +1415,140 @@ function setStyleWithVendorPrefix({ element, style, value }) {
1287
1415
  }
1288
1416
  }
1289
1417
 
1418
+ const defaultColumnWidth = 100;
1419
+ const minColumnWidth = 80;
1420
+ class GanttTableHeaderComponent {
1421
+ constructor(elementRef, gantt, cdr) {
1422
+ this.elementRef = elementRef;
1423
+ this.gantt = gantt;
1424
+ this.cdr = cdr;
1425
+ this.tableWidth = 0;
1426
+ this.unsubscribe$ = new Subject();
1427
+ this.className = `gantt-table-header `;
1428
+ }
1429
+ ngOnInit() {
1430
+ this.columnsChange();
1431
+ this.columns.changes.pipe(takeUntil$1(this.unsubscribe$)).subscribe(() => {
1432
+ this.columnsChange();
1433
+ this.cdr.detectChanges();
1434
+ });
1435
+ }
1436
+ columnsChange() {
1437
+ let tableWidth = 0;
1438
+ this.columns.forEach((column) => {
1439
+ if (!column.columnWidth) {
1440
+ column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1441
+ }
1442
+ tableWidth += Number(column.columnWidth.replace('px', ''));
1443
+ });
1444
+ this.tableWidth = tableWidth;
1445
+ }
1446
+ dragFixed(config) {
1447
+ if (config.movedWidth < config.minWidth) {
1448
+ setStyleWithVendorPrefix({
1449
+ element: config.target,
1450
+ style: 'transform',
1451
+ value: `translate3d(${config.minWidth - config.originWidth}px, 0, 0)`
1452
+ });
1453
+ }
1454
+ }
1455
+ onResizeStarted(event) {
1456
+ const target = event.source.element.nativeElement;
1457
+ this.dragStartLeft = target.getBoundingClientRect().left;
1458
+ }
1459
+ onResizeMoved(event, column) {
1460
+ const target = event.source.element.nativeElement;
1461
+ const left = target.getBoundingClientRect().left;
1462
+ let originWidth;
1463
+ let movedWidth;
1464
+ let minWidth;
1465
+ if (column) {
1466
+ originWidth = parseInt(column.columnWidth, 10);
1467
+ movedWidth = originWidth + (left - this.dragStartLeft);
1468
+ minWidth = minColumnWidth;
1469
+ }
1470
+ else {
1471
+ originWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1472
+ movedWidth = originWidth + (left - this.dragStartLeft);
1473
+ minWidth = minColumnWidth * this.columns.length;
1474
+ }
1475
+ this.dragFixed({
1476
+ target,
1477
+ originWidth,
1478
+ movedWidth,
1479
+ minWidth
1480
+ });
1481
+ this.showAuxiliaryLine(event);
1482
+ }
1483
+ onResizeEnded(event, column) {
1484
+ const beforeWidth = parseInt(column.columnWidth, 10);
1485
+ const target = event.source.element.nativeElement;
1486
+ const left = target.getBoundingClientRect().left;
1487
+ const width = parseInt(column.columnWidth, 10) + (left - this.dragStartLeft);
1488
+ const columnWidth = Math.max(width || 0, minColumnWidth);
1489
+ column.columnWidth = coerceCssPixelValue(columnWidth);
1490
+ if (this.gantt.table) {
1491
+ this.gantt.table.columnChanges.emit({ columns: this.columns });
1492
+ }
1493
+ this.tableWidth = this.tableWidth - beforeWidth + columnWidth;
1494
+ this.hideAuxiliaryLine();
1495
+ event.source.reset();
1496
+ }
1497
+ onOverallResizeEnded(event) {
1498
+ const target = event.source.element.nativeElement;
1499
+ const left = target.getBoundingClientRect().left;
1500
+ const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1501
+ const dragWidth = left - this.dragStartLeft;
1502
+ let tempWidth = 0;
1503
+ this.columns.forEach((column) => {
1504
+ const lastColumnWidth = parseInt(column.columnWidth, 10);
1505
+ const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10);
1506
+ const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth);
1507
+ column.columnWidth = coerceCssPixelValue(columnWidth);
1508
+ tempWidth += columnWidth;
1509
+ });
1510
+ this.tableWidth = tempWidth;
1511
+ if (this.gantt.table) {
1512
+ this.gantt.table.columnChanges.emit({ columns: this.columns });
1513
+ }
1514
+ this.hideAuxiliaryLine();
1515
+ event.source.reset();
1516
+ }
1517
+ showAuxiliaryLine(event) {
1518
+ const tableRect = this.elementRef.nativeElement.getBoundingClientRect();
1519
+ const targetRect = event.source.element.nativeElement.getBoundingClientRect();
1520
+ const distance = { x: targetRect.left - tableRect.left, y: targetRect.top - tableRect.top };
1521
+ this.resizeLineElementRef.nativeElement.style.left = `${distance.x}px`;
1522
+ this.resizeLineElementRef.nativeElement.style.display = 'block';
1523
+ }
1524
+ hideAuxiliaryLine() {
1525
+ this.resizeLineElementRef.nativeElement.style.display = 'none';
1526
+ }
1527
+ ngOnDestroy() {
1528
+ this.unsubscribe$.next();
1529
+ this.unsubscribe$.complete();
1530
+ }
1531
+ }
1532
+ GanttTableHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableHeaderComponent, deps: [{ token: i0.ElementRef }, { token: GANTT_ABSTRACT_TOKEN }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1533
+ GanttTableHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttTableHeaderComponent, selector: "gantt-table-header", inputs: { columns: "columns" }, host: { properties: { "class": "this.className" } }, viewQueries: [{ propertyName: "resizeLineElementRef", first: true, predicate: ["resizeLine"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"d-flex\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"> </ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"column-resize-handle\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"onResizeMoved($event, column)\"\n (cdkDragStarted)=\"onResizeStarted($event)\"\n (cdkDragEnded)=\"onResizeEnded($event, column)\"\n ></div>\n </div>\n</div>\n\n<div\n class=\"table-resize-handle\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"onResizeMoved($event)\"\n (cdkDragStarted)=\"onResizeStarted($event)\"\n (cdkDragEnded)=\"onOverallResizeEnded($event)\"\n></div>\n\n<div #resizeLine class=\"table-resize-auxiliary-line\"></div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }] });
1534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableHeaderComponent, decorators: [{
1535
+ type: Component,
1536
+ args: [{ selector: 'gantt-table-header', template: "<div class=\"d-flex\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"> </ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"column-resize-handle\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"onResizeMoved($event, column)\"\n (cdkDragStarted)=\"onResizeStarted($event)\"\n (cdkDragEnded)=\"onResizeEnded($event, column)\"\n ></div>\n </div>\n</div>\n\n<div\n class=\"table-resize-handle\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"onResizeMoved($event)\"\n (cdkDragStarted)=\"onResizeStarted($event)\"\n (cdkDragEnded)=\"onOverallResizeEnded($event)\"\n></div>\n\n<div #resizeLine class=\"table-resize-auxiliary-line\"></div>\n" }]
1537
+ }], ctorParameters: function () {
1538
+ return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
1539
+ type: Inject,
1540
+ args: [GANTT_ABSTRACT_TOKEN]
1541
+ }] }, { type: i0.ChangeDetectorRef }];
1542
+ }, propDecorators: { columns: [{
1543
+ type: Input
1544
+ }], resizeLineElementRef: [{
1545
+ type: ViewChild,
1546
+ args: ['resizeLine', { static: true }]
1547
+ }], className: [{
1548
+ type: HostBinding,
1549
+ args: ['class']
1550
+ }] } });
1551
+
1290
1552
  const angleRight = `<svg xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="amnavigation/angle-right" stroke-width="1" fill-rule="evenodd"><path d="M7.978 11.498l-.005.005L2.3 5.831 3.13 5l4.848 4.848L12.826 5l.83.831-5.673 5.672-.005-.005z" transform="rotate(-90 7.978 8.252)"></path></g></svg>`;
1291
1553
  const angleDown = `<svg xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="aknavigation/angle-down" stroke-width="1" fill-rule="evenodd"><path d="M7.978 11.997l-.005.006L2.3 6.33l.83-.831 4.848 4.848L12.826 5.5l.83.83-5.673 5.673-.005-.006z" ></path></g></svg>`;
1292
1554
  const plusSquare = `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="kxaction/plus-square" stroke-width="1" fill-rule="evenodd"><path d="M2 0h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm0 1.2a.8.8 0 0 0-.8.8v12a.8.8 0 0 0 .8.8h12a.8.8 0 0 0 .8-.8V2a.8.8 0 0 0-.8-.8H2zm5.45 6.2V4.75h1.2V7.4h2.65v1.2H8.65v2.65h-1.2V8.6H4.8V7.4h2.65z"></path></g></svg>`;
@@ -1365,13 +1627,15 @@ xmlns:xlink="http://www.w3.org/1999/xlink"
1365
1627
  </g>
1366
1628
  </g>
1367
1629
  </svg>`;
1630
+ const dragIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="aijaction/drag--" stroke-width="1" fill-rule="evenodd"><g id="aij拖动" transform="translate(5 1)" fill-rule="nonzero"><path d="M1 2a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm4 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2zM1 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm4 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm-4 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm4 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm-4 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm4 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" id="aij形状结合"></path></g></g></svg>`;
1368
1631
  const icons = {
1369
1632
  'angle-right': angleRight,
1370
1633
  'angle-down': angleDown,
1371
1634
  'plus-square': plusSquare,
1372
1635
  'minus-square': minusSquare,
1373
1636
  loading: loadingIcon,
1374
- empty: emptyIcon
1637
+ empty: emptyIcon,
1638
+ drag: dragIcon
1375
1639
  };
1376
1640
 
1377
1641
  class GanttIconComponent {
@@ -1447,42 +1711,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1447
1711
  }]
1448
1712
  }] });
1449
1713
 
1450
- const defaultColumnWidth = 100;
1451
- const minColumnWidth = 80;
1452
- class GanttTableComponent {
1453
- set columns(columns) {
1454
- columns.forEach((column) => {
1455
- if (!column.columnWidth) {
1456
- column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1457
- }
1458
- });
1459
- this.columnList = columns;
1714
+ class GanttTableBodyComponent {
1715
+ set renderData(data) {
1716
+ const firstData = data[0];
1717
+ if (firstData && firstData.hasOwnProperty('items')) {
1718
+ this.hasGroup = true;
1719
+ }
1720
+ this.ganttTableEmptyClass = (data === null || data === void 0 ? void 0 : data.length) ? false : true;
1721
+ this._renderData = data;
1460
1722
  }
1461
- constructor(gantt, ganttUpper, elementRef) {
1723
+ get renderData() {
1724
+ return this._renderData;
1725
+ }
1726
+ constructor(gantt, ganttUpper, cdr, document) {
1462
1727
  this.gantt = gantt;
1463
1728
  this.ganttUpper = ganttUpper;
1464
- this.elementRef = elementRef;
1729
+ this.cdr = cdr;
1730
+ this.document = document;
1731
+ this.draggable = false;
1732
+ this.dragDropped = new EventEmitter();
1465
1733
  this.itemClick = new EventEmitter();
1466
1734
  this.ganttTableClass = true;
1467
1735
  this.ganttTableEmptyClass = false;
1736
+ this.ganttTableDragging = false;
1737
+ this.hasExpandIcon = false;
1738
+ // 缓存 Element 和 DragRef 的关系,方便在 Item 拖动时查找
1739
+ this.itemDragRefMap = new Map();
1740
+ this.itemDragMoved = new Subject();
1741
+ this.destroy$ = new Subject();
1468
1742
  }
1469
- ngOnChanges(changes) {
1470
- var _a, _b;
1471
- if (!((_a = changes.groups.currentValue) === null || _a === void 0 ? void 0 : _a.length) && !((_b = changes.items.currentValue) === null || _b === void 0 ? void 0 : _b.length)) {
1472
- this.ganttTableEmptyClass = true;
1473
- }
1474
- else {
1475
- this.ganttTableEmptyClass = false;
1476
- }
1743
+ ngOnInit() {
1744
+ this.columns.changes.pipe(startWith(this.columns), takeUntil$1(this.destroy$)).subscribe(() => {
1745
+ this.hasExpandIcon = false;
1746
+ this.columns.forEach((column) => {
1747
+ if (!column.columnWidth) {
1748
+ column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1749
+ }
1750
+ if (column.showExpandIcon) {
1751
+ this.hasExpandIcon = true;
1752
+ }
1753
+ });
1754
+ this.cdr.detectChanges();
1755
+ });
1477
1756
  }
1478
- dragFixed(config) {
1479
- if (config.movedWidth < config.minWidth) {
1480
- setStyleWithVendorPrefix({
1481
- element: config.target,
1482
- style: 'transform',
1483
- value: `translate3d(${config.minWidth - config.originWidth}px, 0, 0)`
1757
+ ngAfterViewInit() {
1758
+ this.cdkDrags.changes
1759
+ .pipe(startWith(this.cdkDrags), takeUntil$1(this.destroy$))
1760
+ .subscribe((drags) => {
1761
+ this.itemDragRefMap.clear();
1762
+ drags.forEach((drag) => {
1763
+ if (drag.data) {
1764
+ // cdkDrag 变化时,缓存 Element 与 DragRef 的关系,方便 Drag Move 时查找
1765
+ this.itemDragRefMap.set(drag.element.nativeElement, drag);
1766
+ }
1484
1767
  });
1485
- }
1768
+ });
1769
+ this.itemDragMoved
1770
+ .pipe(debounceTime(30),
1771
+ // debounce 可能会导致拖动结束后仍然执行 moved ,所以通过判断 dragging 状态来过滤无效 moved
1772
+ filter((event) => event.source._dragRef.isDragging()), takeUntil$1(this.destroy$))
1773
+ .subscribe((event) => {
1774
+ this.onItemDragMoved(event);
1775
+ });
1486
1776
  }
1487
1777
  expandGroup(group) {
1488
1778
  this.gantt.expandGroup(group);
@@ -1491,80 +1781,163 @@ class GanttTableComponent {
1491
1781
  event.stopPropagation();
1492
1782
  this.gantt.expandChildren(item);
1493
1783
  }
1494
- dragStarted(event) {
1495
- const target = event.source.element.nativeElement;
1496
- this.dragStartLeft = target.getBoundingClientRect().left;
1784
+ onItemDragStarted(event) {
1785
+ this.ganttTableDragging = true;
1786
+ // 拖动开始时隐藏所有的子项
1787
+ const children = this.getChildrenElementsByDragRef(event.source);
1788
+ children.forEach((element) => {
1789
+ element.classList.add('drag-item-hide');
1790
+ });
1497
1791
  }
1498
- dragMoved(event, column) {
1499
- const target = event.source.element.nativeElement;
1500
- const left = target.getBoundingClientRect().left;
1501
- let originWidth;
1502
- let movedWidth;
1503
- let minWidth;
1504
- if (column) {
1505
- originWidth = parseInt(column.columnWidth, 10);
1506
- movedWidth = originWidth + (left - this.dragStartLeft);
1507
- minWidth = minColumnWidth;
1792
+ emitItemDragMoved(event) {
1793
+ this.itemDragMoved.next(event);
1794
+ }
1795
+ onItemDragMoved(event) {
1796
+ var _a;
1797
+ // 通过鼠标位置查找对应的目标 Item 元素
1798
+ let currentPointElement = this.document.elementFromPoint(event.pointerPosition.x, event.pointerPosition.y);
1799
+ if (!currentPointElement) {
1800
+ this.cleanupDragArtifacts();
1801
+ return;
1802
+ }
1803
+ let targetElement = currentPointElement.classList.contains('gantt-table-item')
1804
+ ? currentPointElement
1805
+ : currentPointElement.closest('.gantt-table-item');
1806
+ if (!targetElement) {
1807
+ this.cleanupDragArtifacts();
1808
+ return;
1809
+ }
1810
+ // 缓存放置目标Id 并计算鼠标相对应的位置
1811
+ this.itemDropTarget = {
1812
+ id: (_a = this.itemDragRefMap.get(targetElement)) === null || _a === void 0 ? void 0 : _a.data.id,
1813
+ position: this.getTargetPosition(targetElement, event)
1814
+ };
1815
+ // 执行外部传入的 dropEnterPredicate 判断是否允许拖入目标项
1816
+ if (this.dropEnterPredicate) {
1817
+ const targetDragRef = this.itemDragRefMap.get(targetElement);
1818
+ if (this.dropEnterPredicate({
1819
+ source: event.source.data.origin,
1820
+ target: targetDragRef.data.origin,
1821
+ dropPosition: this.itemDropTarget.position
1822
+ })) {
1823
+ this.showDropPositionPlaceholder(targetElement);
1824
+ }
1825
+ else {
1826
+ this.itemDropTarget = null;
1827
+ }
1508
1828
  }
1509
1829
  else {
1510
- originWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1511
- movedWidth = originWidth + (left - this.dragStartLeft);
1512
- minWidth = minColumnWidth * this.columnList.length;
1830
+ this.showDropPositionPlaceholder(targetElement);
1513
1831
  }
1514
- this.dragFixed({
1515
- target,
1516
- originWidth,
1517
- movedWidth,
1518
- minWidth
1832
+ }
1833
+ onItemDragEnded(event) {
1834
+ this.ganttTableDragging = false;
1835
+ }
1836
+ onListDropped(event) {
1837
+ var _a, _b;
1838
+ if (!this.itemDropTarget) {
1839
+ return;
1840
+ }
1841
+ const targetDragRef = this.cdkDrags.find((item) => { var _a; return ((_a = item.data) === null || _a === void 0 ? void 0 : _a.id) === this.itemDropTarget.id; });
1842
+ const sourceItem = event.item.data;
1843
+ const targetItem = targetDragRef === null || targetDragRef === void 0 ? void 0 : targetDragRef.data;
1844
+ this.removeItem(sourceItem);
1845
+ switch (this.itemDropTarget.position) {
1846
+ case 'before':
1847
+ case 'after':
1848
+ this.insertItem(targetItem, sourceItem, this.itemDropTarget.position);
1849
+ sourceItem.updateLevel(targetItem.level);
1850
+ break;
1851
+ case 'inside':
1852
+ this.insertChildrenItem(targetItem, sourceItem);
1853
+ sourceItem.updateLevel(targetItem.level + 1);
1854
+ break;
1855
+ }
1856
+ this.dragDropped.emit({
1857
+ source: sourceItem.origin,
1858
+ sourceParent: (_a = this.getParentByItem(sourceItem)) === null || _a === void 0 ? void 0 : _a.origin,
1859
+ target: targetItem.origin,
1860
+ targetParent: (_b = this.getParentByItem(targetItem)) === null || _b === void 0 ? void 0 : _b.origin,
1861
+ dropPosition: this.itemDropTarget.position
1519
1862
  });
1520
- this.showAuxiliaryLine(event);
1863
+ this.cleanupDragArtifacts(true);
1521
1864
  }
1522
- columnDragEnded(event, column) {
1523
- const target = event.source.element.nativeElement;
1524
- const left = target.getBoundingClientRect().left;
1525
- const width = parseInt(column.columnWidth, 10) + (left - this.dragStartLeft);
1526
- const columnWidth = Math.max(width || 0, minColumnWidth);
1527
- column.columnWidth = coerceCssPixelValue(columnWidth);
1528
- if (this.gantt.table) {
1529
- this.gantt.table.columnChanges.emit({ columns: this.columnList });
1865
+ trackBy(index, item) {
1866
+ return item.id || index;
1867
+ }
1868
+ ngOnDestroy() {
1869
+ this.destroy$.next();
1870
+ this.destroy$.complete();
1871
+ }
1872
+ removeItem(item) {
1873
+ this.renderData.splice(this.renderData.indexOf(item), 1);
1874
+ this.flatData.splice(this.flatData.indexOf(item), 1);
1875
+ }
1876
+ insertItem(target, inserted, position) {
1877
+ const appendIndex = position === 'after' ? 1 : 0;
1878
+ this.renderData.splice(this.renderData.indexOf(target) + appendIndex, 0, inserted);
1879
+ this.flatData.splice(this.flatData.indexOf(target) + appendIndex, 0, inserted);
1880
+ }
1881
+ insertChildrenItem(target, inserted) {
1882
+ if (target.expanded) {
1883
+ this.renderData.splice(this.renderData.indexOf(target) + target.children.length + 1, 0, inserted);
1884
+ this.flatData.splice(this.flatData.indexOf(target) + target.children.length + 1, 0, inserted);
1530
1885
  }
1531
- this.hideAuxiliaryLine();
1532
- event.source.reset();
1886
+ target.children.push(inserted);
1533
1887
  }
1534
- tableDragEnded(event) {
1535
- const target = event.source.element.nativeElement;
1536
- const left = target.getBoundingClientRect().left;
1537
- const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1538
- const dragWidth = left - this.dragStartLeft;
1539
- this.columnList.forEach((column) => {
1540
- const lastColumnWidth = parseInt(column.columnWidth, 10);
1541
- const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10);
1542
- const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth);
1543
- column.columnWidth = coerceCssPixelValue(columnWidth);
1888
+ getParentByItem(item) {
1889
+ return (this.flatData || []).find((n) => {
1890
+ var _a;
1891
+ return (_a = n.children) === null || _a === void 0 ? void 0 : _a.includes(item);
1544
1892
  });
1545
- if (this.gantt.table) {
1546
- this.gantt.table.columnChanges.emit({ columns: this.columnList });
1893
+ }
1894
+ getChildrenElementsByDragRef(dragRef) {
1895
+ // 通过循环持续查找 next element,如果 element 的 level 小于当前 item 的 level,则为它的 children
1896
+ const children = [];
1897
+ let nextElement = dragRef.getPlaceholderElement().nextElementSibling;
1898
+ let nextDragRef = this.itemDragRefMap.get(nextElement);
1899
+ while (nextDragRef && nextDragRef.data.level > dragRef.data.level) {
1900
+ children.push(nextElement);
1901
+ nextElement = nextElement.nextElementSibling;
1902
+ nextDragRef = this.itemDragRefMap.get(nextElement);
1547
1903
  }
1548
- this.hideAuxiliaryLine();
1549
- event.source.reset();
1904
+ return children;
1550
1905
  }
1551
- showAuxiliaryLine(event) {
1552
- const tableRect = this.elementRef.nativeElement.getBoundingClientRect();
1553
- this.draglineElementRef.nativeElement.style.left = `${event.event.clientX - tableRect.left}px`;
1554
- this.draglineElementRef.nativeElement.style.display = 'block';
1906
+ getTargetPosition(target, event) {
1907
+ const targetRect = target.getBoundingClientRect();
1908
+ const beforeOrAfterGap = targetRect.height * 0.3;
1909
+ // Item 高度分为上中下三段,其中上下的 Gap 为 height 的 30%,通过判断鼠标位置在哪一段 gap 来计算对应的位置
1910
+ if (event.pointerPosition.y - targetRect.top < beforeOrAfterGap) {
1911
+ return 'before';
1912
+ }
1913
+ else if (event.pointerPosition.y >= targetRect.bottom - beforeOrAfterGap) {
1914
+ return 'after';
1915
+ }
1916
+ else {
1917
+ return 'inside';
1918
+ }
1555
1919
  }
1556
- hideAuxiliaryLine() {
1557
- this.draglineElementRef.nativeElement.style.display = 'none';
1920
+ showDropPositionPlaceholder(targetElement) {
1921
+ this.cleanupDragArtifacts();
1922
+ if (this.itemDropTarget && targetElement) {
1923
+ targetElement.classList.add(`drop-position-${this.itemDropTarget.position}`);
1924
+ }
1558
1925
  }
1559
- trackBy(index, item) {
1560
- return item.id || index;
1926
+ cleanupDragArtifacts(dropped = false) {
1927
+ if (dropped) {
1928
+ this.itemDropTarget = null;
1929
+ }
1930
+ this.document.querySelectorAll('.drop-position-before').forEach((element) => element.classList.remove('drop-position-before'));
1931
+ this.document.querySelectorAll('.drop-position-after').forEach((element) => element.classList.remove('drop-position-after'));
1932
+ this.document.querySelectorAll('.drop-position-inside').forEach((element) => element.classList.remove('drop-position-inside'));
1933
+ this.document.querySelectorAll('.drag-item-hide').forEach((element) => element.classList.remove('drop-item-hide'));
1561
1934
  }
1562
1935
  }
1563
- GanttTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableComponent, deps: [{ token: GANTT_ABSTRACT_TOKEN }, { token: GANTT_UPPER_TOKEN }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1564
- GanttTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttTableComponent, selector: "gantt-table", inputs: { groups: "groups", items: "items", columns: "columns", groupTemplate: "groupTemplate", emptyTemplate: "emptyTemplate", rowBeforeTemplate: "rowBeforeTemplate", rowAfterTemplate: "rowAfterTemplate" }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.gantt-table": "this.ganttTableClass", "class.gantt-table-empty": "this.ganttTableEmptyClass" } }, viewQueries: [{ propertyName: "draglineElementRef", first: true, predicate: ["dragLine"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"gantt-table-header gantt-table-row\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"></ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event, column)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"columnDragEnded($event, column)\"\n ></div>\n </div>\n</div>\n<div class=\"gantt-table-body\">\n <ng-container *ngIf=\"!groups.length && !items.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"groups && groups.length > 0; else itemsTemplate\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"group.class\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"group.expanded\" (click)=\"expandGroup(group)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"group.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: group.origin, group: group.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ group.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <ng-container *ngIf=\"group.expanded\">\n <ng-template\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ group: group, items: group.items, level: 0 }\"\n ></ng-template>\n </ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"tableDragEnded($event)\"\n></div>\n\n<div #dragLine class=\"gantt-table-drag-auxiliary-line\"></div>\n\n<ng-template #itemsTemplate>\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items, level: 0 }\"></ng-template>\n</ng-template>\n\n<ng-template #ganttItems let-group=\"group\" let-items=\"items\" let-level=\"level\">\n <ng-container *ngFor=\"let item of items; trackBy: trackBy\">\n <div\n (click)=\"itemClick.emit({ event: $event, selectedValue: this.item.origin })\"\n class=\"gantt-table-item gantt-table-row\"\n [class.gantt-table-item-first-level-group]=\"level === 0 && (item.type | isGanttRangeItem)\"\n [class.gantt-table-item-with-group]=\"group\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let first = first\" [style.width]=\"column.columnWidth\">\n <div *ngIf=\"first\" class=\"gantt-expand-icon\" [style.marginLeft.px]=\"level * 20\">\n <ng-container *ngIf=\"level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n ></gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children, level: level + 1, group: group }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: GanttIconComponent, selector: "gantt-icon", inputs: ["iconName"] }, { kind: "pipe", type: IsGanttRangeItemPipe, name: "isGanttRangeItem" }] });
1565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableComponent, decorators: [{
1936
+ GanttTableBodyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, deps: [{ token: GANTT_ABSTRACT_TOKEN }, { token: GANTT_UPPER_TOKEN }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
1937
+ GanttTableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttTableBodyComponent, selector: "gantt-table-body", inputs: { renderData: "renderData", flatData: "flatData", columns: "columns", groupTemplate: "groupTemplate", emptyTemplate: "emptyTemplate", rowBeforeTemplate: "rowBeforeTemplate", rowAfterTemplate: "rowAfterTemplate", draggable: "draggable", dropEnterPredicate: "dropEnterPredicate" }, outputs: { dragDropped: "dragDropped", itemClick: "itemClick" }, host: { properties: { "class.gantt-table-draggable": "this.draggable", "class.gantt-table-body": "this.ganttTableClass", "class.gantt-table-empty": "this.ganttTableEmptyClass", "class.gantt-table-dragging": "this.ganttTableDragging" } }, viewQueries: [{ propertyName: "cdkDrags", predicate: (CdkDrag), descendants: true }], ngImport: i0, template: "<div\n class=\"gantt-table-body-container\"\n cdkDropList\n [cdkDropListAutoScrollStep]=\"6\"\n [cdkDropListData]=\"renderData\"\n [cdkDropListSortingDisabled]=\"true\"\n (cdkDropListDropped)=\"onListDropped($event)\"\n>\n <ng-container *ngIf=\"!renderData?.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"renderData && renderData.length > 0\">\n <ng-container *ngFor=\"let item of renderData; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"item.class\" *ngIf=\"item.items\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"item.expanded\" (click)=\"expandGroup(item)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, group: item.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ item.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <div\n *ngIf=\"!item.items\"\n (click)=\"itemClick.emit({ event: $event, selectedValue: item.origin })\"\n cdkDrag\n [cdkDragData]=\"item\"\n [cdkDragDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n (cdkDragStarted)=\"onItemDragStarted($event)\"\n (cdkDragEnded)=\"onItemDragEnded($event)\"\n (cdkDragMoved)=\"emitItemDragMoved($event)\"\n class=\"gantt-table-item\"\n [class.gantt-table-item-with-group]=\"hasGroup\"\n [class.gantt-table-item-first-level-group]=\"item.level === 0 && (item.type | isGanttRangeItem)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let first = first\" [style.width]=\"column.columnWidth\">\n <!-- drag icon -->\n <gantt-icon\n *ngIf=\"first && draggable\"\n class=\"gantt-drag-handle\"\n iconName=\"drag\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n ></gantt-icon>\n <!-- expand icon -->\n <div\n *ngIf=\"column?.showExpandIcon || (!hasExpandIcon && first)\"\n class=\"gantt-expand-icon\"\n [style.marginLeft.px]=\"item.level * 20\"\n >\n <ng-container *ngIf=\"item.level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n >\n </gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <!-- column content -->\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </ng-container>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: GanttIconComponent, selector: "gantt-icon", inputs: ["iconName"] }, { kind: "pipe", type: IsGanttRangeItemPipe, name: "isGanttRangeItem" }] });
1938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, decorators: [{
1566
1939
  type: Component,
1567
- args: [{ selector: 'gantt-table', template: "<div class=\"gantt-table-header gantt-table-row\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"></ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event, column)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"columnDragEnded($event, column)\"\n ></div>\n </div>\n</div>\n<div class=\"gantt-table-body\">\n <ng-container *ngIf=\"!groups.length && !items.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"groups && groups.length > 0; else itemsTemplate\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"group.class\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"group.expanded\" (click)=\"expandGroup(group)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"group.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: group.origin, group: group.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ group.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <ng-container *ngIf=\"group.expanded\">\n <ng-template\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ group: group, items: group.items, level: 0 }\"\n ></ng-template>\n </ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"tableDragEnded($event)\"\n></div>\n\n<div #dragLine class=\"gantt-table-drag-auxiliary-line\"></div>\n\n<ng-template #itemsTemplate>\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items, level: 0 }\"></ng-template>\n</ng-template>\n\n<ng-template #ganttItems let-group=\"group\" let-items=\"items\" let-level=\"level\">\n <ng-container *ngFor=\"let item of items; trackBy: trackBy\">\n <div\n (click)=\"itemClick.emit({ event: $event, selectedValue: this.item.origin })\"\n class=\"gantt-table-item gantt-table-row\"\n [class.gantt-table-item-first-level-group]=\"level === 0 && (item.type | isGanttRangeItem)\"\n [class.gantt-table-item-with-group]=\"group\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let first = first\" [style.width]=\"column.columnWidth\">\n <div *ngIf=\"first\" class=\"gantt-expand-icon\" [style.marginLeft.px]=\"level * 20\">\n <ng-container *ngIf=\"level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n ></gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children, level: level + 1, group: group }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n" }]
1940
+ args: [{ selector: 'gantt-table-body', template: "<div\n class=\"gantt-table-body-container\"\n cdkDropList\n [cdkDropListAutoScrollStep]=\"6\"\n [cdkDropListData]=\"renderData\"\n [cdkDropListSortingDisabled]=\"true\"\n (cdkDropListDropped)=\"onListDropped($event)\"\n>\n <ng-container *ngIf=\"!renderData?.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"renderData && renderData.length > 0\">\n <ng-container *ngFor=\"let item of renderData; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"item.class\" *ngIf=\"item.items\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"item.expanded\" (click)=\"expandGroup(item)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, group: item.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ item.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <div\n *ngIf=\"!item.items\"\n (click)=\"itemClick.emit({ event: $event, selectedValue: item.origin })\"\n cdkDrag\n [cdkDragData]=\"item\"\n [cdkDragDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n (cdkDragStarted)=\"onItemDragStarted($event)\"\n (cdkDragEnded)=\"onItemDragEnded($event)\"\n (cdkDragMoved)=\"emitItemDragMoved($event)\"\n class=\"gantt-table-item\"\n [class.gantt-table-item-with-group]=\"hasGroup\"\n [class.gantt-table-item-first-level-group]=\"item.level === 0 && (item.type | isGanttRangeItem)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n\n <div class=\"gantt-table-column\" *ngFor=\"let column of columns; let first = first\" [style.width]=\"column.columnWidth\">\n <!-- drag icon -->\n <gantt-icon\n *ngIf=\"first && draggable\"\n class=\"gantt-drag-handle\"\n iconName=\"drag\"\n cdkDragHandle\n [cdkDragHandleDisabled]=\"(draggable && item.itemDraggable === false) || !draggable\"\n ></gantt-icon>\n <!-- expand icon -->\n <div\n *ngIf=\"column?.showExpandIcon || (!hasExpandIcon && first)\"\n class=\"gantt-expand-icon\"\n [style.marginLeft.px]=\"item.level * 20\"\n >\n <ng-container *ngIf=\"item.level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n >\n </gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <!-- column content -->\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </ng-container>\n </ng-container>\n</div>\n" }]
1568
1941
  }], ctorParameters: function () {
1569
1942
  return [{ type: undefined, decorators: [{
1570
1943
  type: Inject,
@@ -1572,10 +1945,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1572
1945
  }] }, { type: GanttUpper, decorators: [{
1573
1946
  type: Inject,
1574
1947
  args: [GANTT_UPPER_TOKEN]
1575
- }] }, { type: i0.ElementRef }];
1576
- }, propDecorators: { groups: [{
1948
+ }] }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
1949
+ type: Inject,
1950
+ args: [DOCUMENT]
1951
+ }] }];
1952
+ }, propDecorators: { renderData: [{
1577
1953
  type: Input
1578
- }], items: [{
1954
+ }], flatData: [{
1579
1955
  type: Input
1580
1956
  }], columns: [{
1581
1957
  type: Input
@@ -1587,17 +1963,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1587
1963
  type: Input
1588
1964
  }], rowAfterTemplate: [{
1589
1965
  type: Input
1966
+ }], draggable: [{
1967
+ type: HostBinding,
1968
+ args: ['class.gantt-table-draggable']
1969
+ }, {
1970
+ type: Input
1971
+ }], dropEnterPredicate: [{
1972
+ type: Input
1973
+ }], dragDropped: [{
1974
+ type: Output
1590
1975
  }], itemClick: [{
1591
1976
  type: Output
1592
- }], draglineElementRef: [{
1593
- type: ViewChild,
1594
- args: ['dragLine', { static: true }]
1595
1977
  }], ganttTableClass: [{
1596
1978
  type: HostBinding,
1597
- args: ['class.gantt-table']
1979
+ args: ['class.gantt-table-body']
1598
1980
  }], ganttTableEmptyClass: [{
1599
1981
  type: HostBinding,
1600
1982
  args: ['class.gantt-table-empty']
1983
+ }], ganttTableDragging: [{
1984
+ type: HostBinding,
1985
+ args: ['class.gantt-table-dragging']
1986
+ }], cdkDrags: [{
1987
+ type: ViewChildren,
1988
+ args: [(CdkDrag)]
1601
1989
  }] } });
1602
1990
 
1603
1991
  class GanttLinkLine {
@@ -1857,13 +2245,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1857
2245
  } });
1858
2246
 
1859
2247
  class GanttLinksComponent {
1860
- constructor(ganttUpper, cdr, elementRef, ganttDragContainer) {
2248
+ constructor(ganttUpper, cdr, elementRef, ganttDragContainer, ngZone) {
1861
2249
  this.ganttUpper = ganttUpper;
1862
2250
  this.cdr = cdr;
1863
2251
  this.elementRef = elementRef;
1864
2252
  this.ganttDragContainer = ganttDragContainer;
1865
- this.groups = [];
1866
- this.items = [];
2253
+ this.ngZone = ngZone;
2254
+ // @Input() groups: GanttGroupInternal[] = [];
2255
+ // @Input() items: GanttItemInternal[] = [];
2256
+ this.flatData = [];
1867
2257
  this.lineClick = new EventEmitter();
1868
2258
  this.links = [];
1869
2259
  this.ganttLinkTypes = GanttLinkType;
@@ -1876,13 +2266,14 @@ class GanttLinksComponent {
1876
2266
  ngOnInit() {
1877
2267
  this.linkLine = createLineGenerator(this.ganttUpper.linkOptions.lineType, this.ganttUpper);
1878
2268
  this.showArrow = this.ganttUpper.linkOptions.showArrow;
1879
- this.buildLinks();
2269
+ // this.buildLinks();
1880
2270
  this.firstChange = false;
2271
+ this.buildLinks();
1881
2272
  this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
1882
2273
  this.elementRef.nativeElement.style.visibility = 'hidden';
1883
2274
  });
1884
- merge(this.ganttUpper.viewChange, this.ganttUpper.expandChange, this.ganttUpper.view.start$, this.ganttUpper.dragEnded, this.ganttUpper.linkDragEnded)
1885
- .pipe(skip(1), debounceTime(0), takeUntil(this.unsubscribe$))
2275
+ merge(this.ganttUpper.viewChange, this.ganttUpper.expandChange, this.ganttUpper.view.start$, this.ganttUpper.dragEnded, this.ganttUpper.linkDragEnded, this.ngZone.onStable.pipe(take(1)).pipe(switchMap(() => { var _a; return ((_a = this.ganttUpper.table) === null || _a === void 0 ? void 0 : _a.dragDropped) || EMPTY; })))
2276
+ .pipe(skip(1), debounceTime$1(0), takeUntil(this.unsubscribe$))
1886
2277
  .subscribe(() => {
1887
2278
  this.elementRef.nativeElement.style.visibility = 'visible';
1888
2279
  this.buildLinks();
@@ -1898,40 +2289,62 @@ class GanttLinksComponent {
1898
2289
  const lineHeight = this.ganttUpper.styles.lineHeight;
1899
2290
  const barHeight = this.ganttUpper.styles.barHeight;
1900
2291
  this.linkItems = [];
1901
- if (this.groups.length > 0) {
1902
- let itemNum = 0;
1903
- let groupNum = 0;
1904
- this.groups.forEach((group) => {
1905
- groupNum++;
1906
- if (group.expanded) {
1907
- const items = recursiveItems(group.items);
1908
- items.forEach((item, itemIndex) => {
1909
- const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
1910
- this.linkItems.push(Object.assign(Object.assign({}, item), { before: {
1911
- x: item.refs.x,
1912
- y
1913
- }, after: {
1914
- x: item.refs.x + item.refs.width,
1915
- y
1916
- } }));
1917
- });
1918
- itemNum += items.length;
2292
+ // if (this.groups.length > 0) {
2293
+ // let itemNum = 0;
2294
+ // let groupNum = 0;
2295
+ // this.groups.forEach((group) => {
2296
+ // groupNum++;
2297
+ // if (group.expanded) {
2298
+ // const items = recursiveItems(group.items);
2299
+ // items.forEach((item, itemIndex) => {
2300
+ // const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
2301
+ // this.linkItems.push({
2302
+ // ...item,
2303
+ // before: {
2304
+ // x: item.refs.x,
2305
+ // y
2306
+ // },
2307
+ // after: {
2308
+ // x: item.refs.x + item.refs.width,
2309
+ // y
2310
+ // }
2311
+ // });
2312
+ // });
2313
+ // itemNum += items.length;
2314
+ // }
2315
+ // });
2316
+ // } else {
2317
+ // const items = recursiveItems(this.items);
2318
+ // items.forEach((item, itemIndex) => {
2319
+ // const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
2320
+ // this.linkItems.push({
2321
+ // ...item,
2322
+ // before: {
2323
+ // x: item.refs.x,
2324
+ // y
2325
+ // },
2326
+ // after: {
2327
+ // x: item.refs.x + item.refs.width,
2328
+ // y
2329
+ // }
2330
+ // });
2331
+ // });
2332
+ // }
2333
+ this.flatData.forEach((item, itemIndex) => {
2334
+ if (!item.hasOwnProperty('items')) {
2335
+ const ganttItem = item;
2336
+ if (ganttItem.refs) {
2337
+ const y = itemIndex * lineHeight + ganttItem.refs.y + barHeight / 2;
2338
+ this.linkItems.push(Object.assign(Object.assign({}, ganttItem), { before: {
2339
+ x: ganttItem.refs.x,
2340
+ y
2341
+ }, after: {
2342
+ x: ganttItem.refs.x + ganttItem.refs.width,
2343
+ y
2344
+ } }));
1919
2345
  }
1920
- });
1921
- }
1922
- else {
1923
- const items = recursiveItems(this.items);
1924
- items.forEach((item, itemIndex) => {
1925
- const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
1926
- this.linkItems.push(Object.assign(Object.assign({}, item), { before: {
1927
- x: item.refs.x,
1928
- y
1929
- }, after: {
1930
- x: item.refs.x + item.refs.width,
1931
- y
1932
- } }));
1933
- });
1934
- }
2346
+ }
2347
+ });
1935
2348
  }
1936
2349
  buildLinks() {
1937
2350
  this.computeItemPosition();
@@ -1996,8 +2409,8 @@ class GanttLinksComponent {
1996
2409
  this.unsubscribe$.complete();
1997
2410
  }
1998
2411
  }
1999
- GanttLinksComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: GanttDragContainer }], target: i0.ɵɵFactoryTarget.Component });
2000
- GanttLinksComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: { groups: "groups", items: "items" }, outputs: { lineClick: "lineClick" }, host: { properties: { "class.gantt-links-overlay": "this.ganttLinksOverlay" } }, usesOnChanges: true, ngImport: i0, template: "<svg [attr.width]=\"ganttUpper.view.width\" class=\"gantt-links-overlay-main\">\n <ng-container *ngFor=\"let link of links; let i = index; trackBy: trackBy\">\n <path\n [attr.d]=\"link.path\"\n fill=\"transparent\"\n stroke-width=\"2\"\n [attr.stroke]=\"link.color\"\n pointer-events=\"none\"\n [attr.style]=\"link.type === ganttLinkTypes.sf ? 'marker-start: url(#triangle' + i + ')' : 'marker-end: url(#triangle' + i + ')'\"\n ></path>\n\n <g>\n <path\n class=\"link-line\"\n (click)=\"onLineClick($event, link)\"\n [attr.d]=\"link.path\"\n (mouseenter)=\"mouseEnterPath(link, i)\"\n (mouseleave)=\"mouseLeavePath(link)\"\n stroke=\"transparent\"\n stroke-width=\"9\"\n fill=\"none\"\n cursor=\"pointer\"\n ></path>\n </g>\n <defs *ngIf=\"showArrow\">\n <marker\n *ngIf=\"link.type === ganttLinkTypes.sf; else markerEnd\"\n [id]=\"'triangle' + i\"\n markerUnits=\"strokeWidth\"\n markerWidth=\"5\"\n markerHeight=\"4\"\n refX=\"5\"\n refY=\"2\"\n orient=\"180\"\n >\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n\n <ng-template #markerEnd>\n <marker [id]=\"'triangle' + i\" markerUnits=\"strokeWidth\" markerWidth=\"5\" markerHeight=\"4\" refX=\"5\" refY=\"2\" orient=\"auto\">\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n </ng-template>\n </defs>\n </ng-container>\n <line class=\"link-dragging-line\"></line>\n</svg>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2412
+ GanttLinksComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: GanttDragContainer }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2413
+ GanttLinksComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: { flatData: "flatData" }, outputs: { lineClick: "lineClick" }, host: { properties: { "class.gantt-links-overlay": "this.ganttLinksOverlay" } }, usesOnChanges: true, ngImport: i0, template: "<svg [attr.width]=\"ganttUpper.view.width\" class=\"gantt-links-overlay-main\">\n <ng-container *ngFor=\"let link of links; let i = index; trackBy: trackBy\">\n <path\n [attr.d]=\"link.path\"\n fill=\"transparent\"\n stroke-width=\"2\"\n [attr.stroke]=\"link.color\"\n pointer-events=\"none\"\n [attr.style]=\"link.type === ganttLinkTypes.sf ? 'marker-start: url(#triangle' + i + ')' : 'marker-end: url(#triangle' + i + ')'\"\n ></path>\n\n <g>\n <path\n class=\"link-line\"\n (click)=\"onLineClick($event, link)\"\n [attr.d]=\"link.path\"\n (mouseenter)=\"mouseEnterPath(link, i)\"\n (mouseleave)=\"mouseLeavePath(link)\"\n stroke=\"transparent\"\n stroke-width=\"9\"\n fill=\"none\"\n cursor=\"pointer\"\n ></path>\n </g>\n <defs *ngIf=\"showArrow\">\n <marker\n *ngIf=\"link.type === ganttLinkTypes.sf; else markerEnd\"\n [id]=\"'triangle' + i\"\n markerUnits=\"strokeWidth\"\n markerWidth=\"5\"\n markerHeight=\"4\"\n refX=\"5\"\n refY=\"2\"\n orient=\"180\"\n >\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n\n <ng-template #markerEnd>\n <marker [id]=\"'triangle' + i\" markerUnits=\"strokeWidth\" markerWidth=\"5\" markerHeight=\"4\" refX=\"5\" refY=\"2\" orient=\"auto\">\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n </ng-template>\n </defs>\n </ng-container>\n <line class=\"link-dragging-line\"></line>\n</svg>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2001
2414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, decorators: [{
2002
2415
  type: Component,
2003
2416
  args: [{ selector: 'gantt-links-overlay', template: "<svg [attr.width]=\"ganttUpper.view.width\" class=\"gantt-links-overlay-main\">\n <ng-container *ngFor=\"let link of links; let i = index; trackBy: trackBy\">\n <path\n [attr.d]=\"link.path\"\n fill=\"transparent\"\n stroke-width=\"2\"\n [attr.stroke]=\"link.color\"\n pointer-events=\"none\"\n [attr.style]=\"link.type === ganttLinkTypes.sf ? 'marker-start: url(#triangle' + i + ')' : 'marker-end: url(#triangle' + i + ')'\"\n ></path>\n\n <g>\n <path\n class=\"link-line\"\n (click)=\"onLineClick($event, link)\"\n [attr.d]=\"link.path\"\n (mouseenter)=\"mouseEnterPath(link, i)\"\n (mouseleave)=\"mouseLeavePath(link)\"\n stroke=\"transparent\"\n stroke-width=\"9\"\n fill=\"none\"\n cursor=\"pointer\"\n ></path>\n </g>\n <defs *ngIf=\"showArrow\">\n <marker\n *ngIf=\"link.type === ganttLinkTypes.sf; else markerEnd\"\n [id]=\"'triangle' + i\"\n markerUnits=\"strokeWidth\"\n markerWidth=\"5\"\n markerHeight=\"4\"\n refX=\"5\"\n refY=\"2\"\n orient=\"180\"\n >\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n\n <ng-template #markerEnd>\n <marker [id]=\"'triangle' + i\" markerUnits=\"strokeWidth\" markerWidth=\"5\" markerHeight=\"4\" refX=\"5\" refY=\"2\" orient=\"auto\">\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n </ng-template>\n </defs>\n </ng-container>\n <line class=\"link-dragging-line\"></line>\n</svg>\n" }]
@@ -2005,10 +2418,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2005
2418
  return [{ type: GanttUpper, decorators: [{
2006
2419
  type: Inject,
2007
2420
  args: [GANTT_UPPER_TOKEN]
2008
- }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }];
2009
- }, propDecorators: { groups: [{
2010
- type: Input
2011
- }], items: [{
2421
+ }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }, { type: i0.NgZone }];
2422
+ }, propDecorators: { flatData: [{
2012
2423
  type: Input
2013
2424
  }], lineClick: [{
2014
2425
  type: Output
@@ -2066,18 +2477,10 @@ class GanttDomService {
2066
2477
  .subscribe((event) => {
2067
2478
  this.syncScroll(event);
2068
2479
  }));
2069
- // fromEvent(this.mainContainer, 'scroll')
2070
- // .pipe(startWith(), takeUntil(this.unsubscribe$))
2071
- // .subscribe((event) => {
2072
- // // if (this.mainContainer.scrollLeft > 0) {
2073
- // // this.side.classList.add('gantt-side-has-shadow');
2074
- // // } else {
2075
- // // this.side.classList.remove('gantt-side-has-shadow');
2076
- // // }
2077
- // });
2078
2480
  }
2079
2481
  syncScroll(event) {
2080
2482
  const target = event.currentTarget;
2483
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2081
2484
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2082
2485
  this.sideContainer.scrollTop = target.scrollTop;
2083
2486
  this.mainContainer.scrollTop = target.scrollTop;
@@ -2103,8 +2506,11 @@ class GanttDomService {
2103
2506
  this.container = this.root.getElementsByClassName('gantt-container')[0];
2104
2507
  this.sideContainer = this.root.getElementsByClassName('gantt-side-container')[0];
2105
2508
  this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2106
- this.mainItems = this.root.getElementsByClassName('gantt-main-items')[0];
2107
- this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-overlay')[0];
2509
+ const mainItems = this.mainContainer.getElementsByClassName('gantt-main-items')[0];
2510
+ const mainGroups = this.mainContainer.getElementsByClassName('gantt-main-groups')[0];
2511
+ this.mainItems = mainItems || mainGroups;
2512
+ this.calendarHeader = this.root.getElementsByClassName('gantt-calendar-header')[0];
2513
+ this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-grid')[0];
2108
2514
  this.monitorScrollChange();
2109
2515
  this.disableBrowserWheelEvent();
2110
2516
  }
@@ -2141,6 +2547,7 @@ class GanttDomService {
2141
2547
  if (isNumber(left)) {
2142
2548
  const scrollLeft = left - this.mainContainer.clientWidth / 2;
2143
2549
  this.mainContainer.scrollLeft = scrollLeft > scrollThreshold ? scrollLeft : 0;
2550
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2144
2551
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2145
2552
  }
2146
2553
  }
@@ -2171,102 +2578,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2171
2578
  }, template: "<div class=\"gantt-drag-mask\">\n <div class=\"date-range\">\n <span class=\"start\"></span>\n <span class=\"end\"></span>\n </div>\n</div>\n" }]
2172
2579
  }] });
2173
2580
 
2174
- class GanttPrintService {
2175
- constructor() { }
2176
- setInlineStyles(targetElem) {
2177
- const svgElements = Array.from(targetElem.getElementsByTagName('svg'));
2178
- for (const svgElement of svgElements) {
2179
- this.recursElementChildren(svgElement);
2180
- }
2181
- }
2182
- recursElementChildren(node) {
2183
- const transformProperties = [
2184
- 'fill',
2185
- 'color',
2186
- 'font-size',
2187
- 'stroke',
2188
- 'font',
2189
- 'text-anchor',
2190
- 'stroke-dasharray',
2191
- 'shape-rendering',
2192
- 'stroke-width'
2193
- ];
2194
- if (!node.style) {
2195
- return;
2196
- }
2197
- const styles = getComputedStyle(node);
2198
- for (const transformProperty of transformProperties) {
2199
- node.style[transformProperty] = styles[transformProperty];
2200
- }
2201
- for (const child of Array.from(node.childNodes)) {
2202
- this.recursElementChildren(child);
2203
- }
2581
+ class GanttCalendarHeaderComponent {
2582
+ get view() {
2583
+ return this.ganttUpper.view;
2204
2584
  }
2205
- register(root) {
2206
- this.root = root.nativeElement;
2207
- this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2585
+ constructor(ganttUpper, ngZone, elementRef) {
2586
+ this.ganttUpper = ganttUpper;
2587
+ this.ngZone = ngZone;
2588
+ this.elementRef = elementRef;
2589
+ this.unsubscribe$ = new Subject();
2590
+ this.headerHeight = headerHeight;
2591
+ this.viewTypes = GanttViewType;
2592
+ this.className = `gantt-calendar gantt-calendar-header`;
2208
2593
  }
2209
- print(name = 'download', ignoreElementClass) {
2210
- return __awaiter(this, void 0, void 0, function* () {
2211
- const root = this.root;
2212
- const mainContainer = this.mainContainer;
2213
- // set print width
2214
- const printWidth = root.offsetWidth;
2215
- // set print height
2216
- const printHeight = root.offsetHeight - mainContainer.offsetHeight + mainContainer.scrollHeight;
2217
- const html2canvas = (yield import(/* webpackChunkName: 'html2canvas' */ 'html2canvas')).default;
2218
- html2canvas(root, {
2219
- logging: false,
2220
- allowTaint: true,
2221
- useCORS: true,
2222
- width: printWidth,
2223
- height: printHeight,
2224
- ignoreElements: (element) => {
2225
- if (ignoreElementClass && element.classList.contains(ignoreElementClass)) {
2226
- return true;
2227
- }
2228
- if (element.classList.contains('gantt-calendar-today-overlay')) {
2229
- return true;
2230
- }
2231
- },
2232
- onclone: (cloneDocument) => {
2233
- const ganttClass = root.className;
2234
- const cloneGanttDom = cloneDocument.querySelector(`.${ganttClass.replace(/\s+/g, '.')}`);
2235
- const cloneGanttContainerDom = cloneDocument.querySelector('.gantt-container');
2236
- const cloneCalendarOverlay = cloneDocument.querySelector('.gantt-calendar-overlay-main');
2237
- const cloneLinksOverlay = cloneDocument.querySelector('.gantt-links-overlay-main');
2238
- // change targetDom width
2239
- cloneGanttDom.style.width = `${printWidth}px`;
2240
- cloneGanttDom.style.height = `${printHeight}px`;
2241
- cloneGanttDom.style.overflow = `unset`;
2242
- cloneGanttContainerDom.style.backgroundColor = '#fff';
2243
- cloneCalendarOverlay.setAttribute('height', `${printHeight}`);
2244
- cloneCalendarOverlay.setAttribute('style', `background: transparent`);
2245
- if (cloneLinksOverlay) {
2246
- cloneLinksOverlay.setAttribute('height', `${printHeight}`);
2247
- cloneLinksOverlay.setAttribute('style', `height: ${printHeight}px`);
2248
- }
2249
- // setInlineStyles for svg
2250
- this.setInlineStyles(cloneGanttDom);
2251
- }
2252
- }).then((canvas) => {
2253
- const link = document.createElement('a');
2254
- const dataUrl = canvas.toDataURL('image/png');
2255
- link.download = `${name}.png`;
2256
- link.href = dataUrl;
2257
- link.click();
2594
+ ngOnInit() {
2595
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2596
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2597
+ .pipe(takeUntil(this.unsubscribe$))
2598
+ .subscribe(() => {
2599
+ if (this.ganttUpper.viewType === GanttViewType.day)
2600
+ this.setTodayPoint();
2258
2601
  });
2259
2602
  });
2260
2603
  }
2604
+ setTodayPoint() {
2605
+ const x = this.view.getTodayXPoint();
2606
+ const today = new GanttDate().getDate();
2607
+ const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2608
+ const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2609
+ if (isNumber(x)) {
2610
+ if (rect) {
2611
+ rect.style.left = `${x - todayWidth / 2}px`;
2612
+ rect.style.top = `${headerHeight - todayHeight}px`;
2613
+ rect.innerHTML = today.toString();
2614
+ }
2615
+ }
2616
+ else {
2617
+ todayEle.style.display = 'none';
2618
+ }
2619
+ }
2620
+ trackBy(point, index) {
2621
+ return point.text || index;
2622
+ }
2261
2623
  }
2262
- GanttPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2263
- GanttPrintServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService });
2264
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, decorators: [{
2265
- type: Injectable
2266
- }], ctorParameters: function () { return []; } });
2624
+ GanttCalendarHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarHeaderComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2625
+ GanttCalendarHeaderComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttCalendarHeaderComponent, selector: "gantt-calendar-header", host: { properties: { "class": "this.className" } }, ngImport: i0, template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-rect\" [hidden]=\"ganttUpper.viewType !== viewTypes.day\"> </span>\n</div>\n<svg [attr.width]=\"view.width\" [attr.height]=\"headerHeight\">\n <g>\n <text\n class=\"primary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n *ngFor=\"let point of view.primaryDatePoints; trackBy: trackBy\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n <ng-container *ngFor=\"let point of view.secondaryDatePoints; trackBy: trackBy\">\n <text\n class=\"secondary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n </ng-container>\n\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"headerHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n\n <g>\n <line [attr.x1]=\"0\" [attr.x2]=\"view.width\" [attr.y1]=\"headerHeight\" [attr.y2]=\"headerHeight\" class=\"header-line\"></line>\n </g>\n </g>\n</svg>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
2626
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarHeaderComponent, decorators: [{
2627
+ type: Component,
2628
+ args: [{ selector: 'gantt-calendar-header', template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-rect\" [hidden]=\"ganttUpper.viewType !== viewTypes.day\"> </span>\n</div>\n<svg [attr.width]=\"view.width\" [attr.height]=\"headerHeight\">\n <g>\n <text\n class=\"primary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n *ngFor=\"let point of view.primaryDatePoints; trackBy: trackBy\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n <ng-container *ngFor=\"let point of view.secondaryDatePoints; trackBy: trackBy\">\n <text\n class=\"secondary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n </ng-container>\n\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"headerHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n\n <g>\n <line [attr.x1]=\"0\" [attr.x2]=\"view.width\" [attr.y1]=\"headerHeight\" [attr.y2]=\"headerHeight\" class=\"header-line\"></line>\n </g>\n </g>\n</svg>\n" }]
2629
+ }], ctorParameters: function () {
2630
+ return [{ type: GanttUpper, decorators: [{
2631
+ type: Inject,
2632
+ args: [GANTT_UPPER_TOKEN]
2633
+ }] }, { type: i0.NgZone }, { type: i0.ElementRef }];
2634
+ }, propDecorators: { className: [{
2635
+ type: HostBinding,
2636
+ args: ['class']
2637
+ }] } });
2267
2638
 
2268
2639
  const mainHeight = 5000;
2269
- class GanttCalendarComponent {
2640
+ class GanttCalendarGridComponent {
2270
2641
  get view() {
2271
2642
  return this.ganttUpper.view;
2272
2643
  }
@@ -2274,30 +2645,21 @@ class GanttCalendarComponent {
2274
2645
  this.ganttUpper = ganttUpper;
2275
2646
  this.ngZone = ngZone;
2276
2647
  this.elementRef = elementRef;
2648
+ this.unsubscribe$ = new Subject();
2277
2649
  this.headerHeight = headerHeight;
2278
2650
  this.mainHeight = mainHeight;
2279
- this.todayHeight = todayHeight;
2280
- this.todayWidth = todayWidth;
2281
2651
  this.todayBorderRadius = todayBorderRadius;
2282
2652
  this.viewTypes = GanttViewType;
2283
- this.className = true;
2284
- this.unsubscribe$ = new Subject();
2653
+ this.className = `gantt-calendar gantt-calendar-grid`;
2285
2654
  }
2286
2655
  setTodayPoint() {
2287
2656
  const x = this.view.getTodayXPoint();
2288
- const today = new GanttDate().getDate();
2289
2657
  const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2290
- const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2291
2658
  const line = this.elementRef.nativeElement.getElementsByClassName('today-line')[0];
2292
2659
  if (isNumber(x)) {
2293
- if (rect) {
2294
- rect.style.left = `${x - todayWidth / 2}px`;
2295
- rect.style.top = `${headerHeight - todayHeight}px`;
2296
- rect.innerHTML = today.toString();
2297
- }
2298
2660
  if (line) {
2299
2661
  line.style.left = `${x}px`;
2300
- line.style.top = `${headerHeight}px`;
2662
+ line.style.top = `0px`;
2301
2663
  line.style.bottom = `${-mainHeight}px`;
2302
2664
  }
2303
2665
  }
@@ -2306,22 +2668,15 @@ class GanttCalendarComponent {
2306
2668
  }
2307
2669
  }
2308
2670
  ngOnInit() {
2309
- // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2310
- // the `onStable` will never emit any value.
2311
- const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
2312
- // Normally this isn't in the zone, but it can cause performance regressions for apps
2313
- // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
2314
- this.ngZone.runOutsideAngular(() => {
2315
- onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
2316
- merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2317
- .pipe(takeUntil(this.unsubscribe$))
2318
- .subscribe(() => {
2319
- this.setTodayPoint();
2320
- });
2671
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2672
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2673
+ .pipe(takeUntil(this.unsubscribe$))
2674
+ .subscribe(() => {
2675
+ this.setTodayPoint();
2321
2676
  });
2322
2677
  });
2323
2678
  }
2324
- trackBy(index, point) {
2679
+ trackBy(point, index) {
2325
2680
  return point.text || index;
2326
2681
  }
2327
2682
  ngOnDestroy() {
@@ -2329,11 +2684,11 @@ class GanttCalendarComponent {
2329
2684
  this.unsubscribe$.complete();
2330
2685
  }
2331
2686
  }
2332
- GanttCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2333
- GanttCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttCalendarComponent, selector: "gantt-calendar-overlay", host: { properties: { "class.gantt-calendar-overlay": "this.className" } }, ngImport: i0, template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-rect\" [hidden]=\"ganttUpper.viewType !== viewTypes.day\"> </span>\n <span class=\"today-line\" *ngIf=\"ganttUpper.showTodayLine\"> </span>\n</div>\n\n<svg class=\"gantt-calendar-overlay-main\" [attr.width]=\"view.width\" [attr.height]=\"headerHeight\">\n <g>\n <text\n class=\"primary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n *ngFor=\"let point of view.primaryDatePoints; trackBy: trackBy\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n <ng-container *ngFor=\"let point of view.secondaryDatePoints; trackBy: trackBy\">\n <text\n class=\"secondary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n </ng-container>\n\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n\n <g>\n <line [attr.x1]=\"0\" [attr.x2]=\"view.width\" [attr.y1]=\"headerHeight\" [attr.y2]=\"headerHeight\" class=\"header-line\"></line>\n </g>\n </g>\n <g>\n <g *ngIf=\"view.showTimeline\">\n <line\n *ngFor=\"let point of view.secondaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.cellWidth\"\n [attr.x2]=\"(i + 1) * view.cellWidth\"\n [attr.y1]=\"headerHeight\"\n [attr.y2]=\"mainHeight\"\n class=\"secondary-line\"\n ></line>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n </g>\n</svg>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
2334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarComponent, decorators: [{
2687
+ GanttCalendarGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarGridComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2688
+ GanttCalendarGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttCalendarGridComponent, selector: "gantt-calendar-grid", host: { properties: { "class": "this.className" } }, ngImport: i0, template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-line\" *ngIf=\"ganttUpper.showTodayLine\"> </span>\n</div>\n\n<svg class=\"gantt-calendar-grid-main\" [attr.width]=\"view.width\" [attr.height]=\"headerHeight - 1\">\n <g>\n <g *ngIf=\"view.showTimeline\">\n <line\n *ngFor=\"let point of view.secondaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.cellWidth\"\n [attr.x2]=\"(i + 1) * view.cellWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"secondary-line\"\n ></line>\n </g>\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n </g>\n</svg>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarGridComponent, decorators: [{
2335
2690
  type: Component,
2336
- args: [{ selector: 'gantt-calendar-overlay', template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-rect\" [hidden]=\"ganttUpper.viewType !== viewTypes.day\"> </span>\n <span class=\"today-line\" *ngIf=\"ganttUpper.showTodayLine\"> </span>\n</div>\n\n<svg class=\"gantt-calendar-overlay-main\" [attr.width]=\"view.width\" [attr.height]=\"headerHeight\">\n <g>\n <text\n class=\"primary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n *ngFor=\"let point of view.primaryDatePoints; trackBy: trackBy\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n <ng-container *ngFor=\"let point of view.secondaryDatePoints; trackBy: trackBy\">\n <text\n class=\"secondary-text\"\n [ngStyle]=\"point.style\"\n [class.today]=\"point.additions?.isToday\"\n [class.weekend]=\"point.additions?.isWeekend\"\n [attr.x]=\"point.x\"\n [attr.y]=\"point.y\"\n >\n {{ point.text }}\n </text>\n </ng-container>\n\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n\n <g>\n <line [attr.x1]=\"0\" [attr.x2]=\"view.width\" [attr.y1]=\"headerHeight\" [attr.y2]=\"headerHeight\" class=\"header-line\"></line>\n </g>\n </g>\n <g>\n <g *ngIf=\"view.showTimeline\">\n <line\n *ngFor=\"let point of view.secondaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.cellWidth\"\n [attr.x2]=\"(i + 1) * view.cellWidth\"\n [attr.y1]=\"headerHeight\"\n [attr.y2]=\"mainHeight\"\n class=\"secondary-line\"\n ></line>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n </g>\n</svg>\n" }]
2691
+ args: [{ selector: 'gantt-calendar-grid', template: "<div class=\"gantt-calendar-today-overlay\" [style.width.px]=\"view.width\">\n <span class=\"today-line\" *ngIf=\"ganttUpper.showTodayLine\"> </span>\n</div>\n\n<svg class=\"gantt-calendar-grid-main\" [attr.width]=\"view.width\" [attr.height]=\"headerHeight - 1\">\n <g>\n <g *ngIf=\"view.showTimeline\">\n <line\n *ngFor=\"let point of view.secondaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.cellWidth\"\n [attr.x2]=\"(i + 1) * view.cellWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"secondary-line\"\n ></line>\n </g>\n <g>\n <line\n *ngFor=\"let point of view.primaryDatePoints; let i = index; trackBy: trackBy\"\n [attr.x1]=\"(i + 1) * view.primaryWidth\"\n [attr.x2]=\"(i + 1) * view.primaryWidth\"\n [attr.y1]=\"0\"\n [attr.y2]=\"mainHeight\"\n class=\"primary-line\"\n ></line>\n </g>\n </g>\n</svg>\n" }]
2337
2692
  }], ctorParameters: function () {
2338
2693
  return [{ type: GanttUpper, decorators: [{
2339
2694
  type: Inject,
@@ -2341,7 +2696,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2341
2696
  }] }, { type: i0.NgZone }, { type: i0.ElementRef }];
2342
2697
  }, propDecorators: { className: [{
2343
2698
  type: HostBinding,
2344
- args: ['class.gantt-calendar-overlay']
2699
+ args: ['class']
2345
2700
  }] } });
2346
2701
 
2347
2702
  class NgxGanttToolbarComponent {
@@ -2402,7 +2757,7 @@ class NgxGanttRootComponent {
2402
2757
  this.setupViewScroll();
2403
2758
  // 优化初始化时Scroll滚动体验问题,通过透明度解决,默认透明度为0,滚动结束后恢复
2404
2759
  this.elementRef.nativeElement.style.opacity = '1';
2405
- this.ganttUpper.viewChange.pipe(startWith(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2760
+ this.ganttUpper.viewChange.pipe(startWith$1(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2406
2761
  this.scrollToToday();
2407
2762
  });
2408
2763
  });
@@ -2471,12 +2826,12 @@ class NgxGanttRootComponent {
2471
2826
  }
2472
2827
  }
2473
2828
  NgxGanttRootComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttRootComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: GanttDomService }, { token: GanttDragContainer }, { token: GANTT_UPPER_TOKEN }, { token: GanttPrintService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2474
- NgxGanttRootComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: { sideWidth: "sideWidth" }, host: { classAttribute: "gantt" }, providers: [GanttDomService, GanttDragContainer], queries: [{ propertyName: "sideTemplate", first: true, predicate: ["sideTemplate"], descendants: true, static: true }, { propertyName: "mainTemplate", first: true, predicate: ["mainTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "backdrop", first: true, predicate: GanttDragBackdropComponent, descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div class=\"gantt-side\" [style.width.px]=\"sideWidth\">\n <div class=\"gantt-side-container\">\n <ng-template [ngTemplateOutlet]=\"sideTemplate\"></ng-template>\n </div>\n</div>\n<div class=\"gantt-container\">\n <gantt-calendar-overlay></gantt-calendar-overlay>\n <gantt-drag-backdrop></gantt-drag-backdrop>\n <div class=\"gantt-main\">\n <ng-template [ngTemplateOutlet]=\"mainTemplate\"></ng-template>\n </div>\n</div>\n<gantt-toolbar *ngIf=\"ganttUpper.showToolbar || ganttUpper.toolbarTemplate\" [template]=\"ganttUpper.toolbarTemplate\"> </gantt-toolbar>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GanttCalendarComponent, selector: "gantt-calendar-overlay" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttToolbarComponent, selector: "ngx-gantt-toolbar,gantt-toolbar", inputs: ["template"] }] });
2829
+ NgxGanttRootComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: { sideWidth: "sideWidth" }, host: { classAttribute: "gantt" }, providers: [GanttDomService, GanttDragContainer], queries: [{ propertyName: "sideTemplate", first: true, predicate: ["sideTemplate"], descendants: true, static: true }, { propertyName: "mainTemplate", first: true, predicate: ["mainTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "backdrop", first: true, predicate: GanttDragBackdropComponent, descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div class=\"gantt-side\" *ngIf=\"sideTemplate\" [style.width.px]=\"sideWidth\">\n <div class=\"gantt-side-container\" cdkScrollable>\n <ng-template [ngTemplateOutlet]=\"sideTemplate\"></ng-template>\n </div>\n</div>\n<div class=\"gantt-container\" *ngIf=\"mainTemplate\">\n <gantt-calendar-header></gantt-calendar-header>\n <gantt-calendar-grid></gantt-calendar-grid>\n <gantt-drag-backdrop></gantt-drag-backdrop>\n <div class=\"gantt-main\">\n <ng-template [ngTemplateOutlet]=\"mainTemplate\"></ng-template>\n </div>\n</div>\n<ng-content></ng-content>\n<gantt-toolbar *ngIf=\"ganttUpper.showToolbar || ganttUpper.toolbarTemplate\" [template]=\"ganttUpper.toolbarTemplate\"> </gantt-toolbar>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: GanttCalendarHeaderComponent, selector: "gantt-calendar-header" }, { kind: "component", type: GanttCalendarGridComponent, selector: "gantt-calendar-grid" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttToolbarComponent, selector: "ngx-gantt-toolbar,gantt-toolbar", inputs: ["template"] }] });
2475
2830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttRootComponent, decorators: [{
2476
2831
  type: Component,
2477
2832
  args: [{ selector: 'ngx-gantt-root', providers: [GanttDomService, GanttDragContainer], host: {
2478
2833
  class: 'gantt'
2479
- }, template: "<div class=\"gantt-side\" [style.width.px]=\"sideWidth\">\n <div class=\"gantt-side-container\">\n <ng-template [ngTemplateOutlet]=\"sideTemplate\"></ng-template>\n </div>\n</div>\n<div class=\"gantt-container\">\n <gantt-calendar-overlay></gantt-calendar-overlay>\n <gantt-drag-backdrop></gantt-drag-backdrop>\n <div class=\"gantt-main\">\n <ng-template [ngTemplateOutlet]=\"mainTemplate\"></ng-template>\n </div>\n</div>\n<gantt-toolbar *ngIf=\"ganttUpper.showToolbar || ganttUpper.toolbarTemplate\" [template]=\"ganttUpper.toolbarTemplate\"> </gantt-toolbar>\n" }]
2834
+ }, template: "<div class=\"gantt-side\" *ngIf=\"sideTemplate\" [style.width.px]=\"sideWidth\">\n <div class=\"gantt-side-container\" cdkScrollable>\n <ng-template [ngTemplateOutlet]=\"sideTemplate\"></ng-template>\n </div>\n</div>\n<div class=\"gantt-container\" *ngIf=\"mainTemplate\">\n <gantt-calendar-header></gantt-calendar-header>\n <gantt-calendar-grid></gantt-calendar-grid>\n <gantt-drag-backdrop></gantt-drag-backdrop>\n <div class=\"gantt-main\">\n <ng-template [ngTemplateOutlet]=\"mainTemplate\"></ng-template>\n </div>\n</div>\n<ng-content></ng-content>\n<gantt-toolbar *ngIf=\"ganttUpper.showToolbar || ganttUpper.toolbarTemplate\" [template]=\"ganttUpper.toolbarTemplate\"> </gantt-toolbar>\n" }]
2480
2835
  }], ctorParameters: function () {
2481
2836
  return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: GanttDomService }, { type: GanttDragContainer }, { type: GanttUpper, decorators: [{
2482
2837
  type: Inject,
@@ -2498,6 +2853,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2498
2853
  }] } });
2499
2854
 
2500
2855
  const dragMinWidth = 10;
2856
+ const autoScrollStep = 10;
2501
2857
  const activeClass = 'gantt-bar-active';
2502
2858
  const dropActiveClass = 'gantt-bar-drop-active';
2503
2859
  const singleDropActiveClass = 'gantt-bar-single-drop-active';
@@ -2520,6 +2876,16 @@ class GanttBarDrag {
2520
2876
  this.root = root;
2521
2877
  this.dragRefs = [];
2522
2878
  this.destroy$ = new Subject();
2879
+ // scrolling state when drag
2880
+ this.dragScrolling = false;
2881
+ }
2882
+ createDragRef(element) {
2883
+ const dragRef = this.dragDrop.createDrag(element);
2884
+ // dragRef.withPreviewContainer(this.dom.mainContainer as HTMLElement);
2885
+ return dragRef;
2886
+ }
2887
+ createDragScrollEvent(dragRef) {
2888
+ return fromEvent(this.dom.mainContainer, 'scroll', passiveListenerOptions).pipe(takeUntil(dragRef.ended));
2523
2889
  }
2524
2890
  createMouseEvents() {
2525
2891
  var _a, _b, _c;
@@ -2556,33 +2922,38 @@ class GanttBarDrag {
2556
2922
  });
2557
2923
  }
2558
2924
  createBarDrag() {
2559
- const dragRef = this.dragDrop.createDrag(this.barElement);
2925
+ const dragRef = this.createDragRef(this.barElement);
2560
2926
  dragRef.lockAxis = 'x';
2561
2927
  dragRef.withBoundaryElement(this.dom.mainItems);
2562
2928
  dragRef.started.subscribe(() => {
2563
2929
  this.setDraggingStyles();
2930
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2931
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2932
+ if (this.dropListRef.isDragging()) {
2933
+ this.dragScrolling = true;
2934
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2935
+ this.barDragMove(dragRef, scrollDistance + this.barDragMoveDistance);
2936
+ }
2937
+ });
2564
2938
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2565
2939
  });
2566
2940
  dragRef.moved.subscribe((event) => {
2567
- const currentX = this.item.refs.x + event.distance.x;
2568
- const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
2569
- const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
2570
- const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
2571
- const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2572
- let start = currentDate;
2573
- let end = currentDate.addDays(diffDays);
2574
- if (currentX > currentStartX + dayWidth / 2) {
2575
- start = start.addDays(1);
2576
- end = end.addDays(1);
2941
+ this.barDragMove(dragRef, event.distance.x);
2942
+ if (!this.dragScrolling) {
2943
+ this.barDragMoveDistance = event.distance.x;
2577
2944
  }
2578
- this.openDragBackdrop(this.barElement, this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
2579
- this.item.updateDate(start, end);
2580
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2581
2945
  });
2582
2946
  dragRef.ended.subscribe((event) => {
2947
+ this.item.updateRefs({
2948
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
2949
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
2950
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
2951
+ });
2583
2952
  this.clearDraggingStyles();
2584
2953
  this.closeDragBackdrop();
2585
2954
  event.source.reset();
2955
+ this.dragScrolling = false;
2956
+ this.barDragMoveDistance = 0;
2586
2957
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2587
2958
  });
2588
2959
  this.barDragRef = dragRef;
@@ -2593,36 +2964,26 @@ class GanttBarDrag {
2593
2964
  const handles = this.barElement.querySelectorAll('.drag-handles .handle');
2594
2965
  handles.forEach((handle, index) => {
2595
2966
  const isBefore = index === 0;
2596
- const dragRef = this.dragDrop.createDrag(handle);
2967
+ const dragRef = this.createDragRef(handle);
2597
2968
  dragRef.lockAxis = 'x';
2598
2969
  dragRef.withBoundaryElement(this.dom.mainItems);
2599
2970
  dragRef.started.subscribe(() => {
2600
2971
  this.setDraggingStyles();
2972
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2973
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2974
+ if (this.dropListRef.isDragging()) {
2975
+ this.dragScrolling = true;
2976
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2977
+ this.barHandleDragMove(scrollDistance + this.barHandleDragMoveDistance, isBefore);
2978
+ }
2979
+ });
2601
2980
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2602
2981
  });
2603
2982
  dragRef.moved.subscribe((event) => {
2604
- if (isBefore) {
2605
- const x = this.item.refs.x + event.distance.x;
2606
- const width = this.item.refs.width + event.distance.x * -1;
2607
- const start = this.ganttUpper.view.getDateByXPoint(x);
2608
- if (width > dragMinWidth) {
2609
- this.barElement.style.width = width + 'px';
2610
- this.barElement.style.left = x + 'px';
2611
- this.openDragBackdrop(this.barElement, start, this.item.end);
2612
- this.item.updateDate(start, this.item.end);
2613
- }
2983
+ this.barHandleDragMove(event.distance.x, isBefore);
2984
+ if (!this.dragScrolling) {
2985
+ this.barHandleDragMoveDistance = event.distance.x;
2614
2986
  }
2615
- else {
2616
- const width = this.item.refs.width + event.distance.x;
2617
- const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
2618
- if (width > dragMinWidth) {
2619
- this.barElement.style.width = width + 'px';
2620
- this.openDragBackdrop(this.barElement, this.item.start, end);
2621
- this.item.updateDate(this.item.start, end);
2622
- }
2623
- }
2624
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2625
- event.source.reset();
2626
2987
  });
2627
2988
  dragRef.ended.subscribe((event) => {
2628
2989
  if (isBefore) {
@@ -2637,8 +2998,16 @@ class GanttBarDrag {
2637
2998
  this.item.updateDate(this.item.start, this.item.start.endOfDay());
2638
2999
  }
2639
3000
  }
3001
+ this.item.updateRefs({
3002
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
3003
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
3004
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
3005
+ });
2640
3006
  this.clearDraggingStyles();
2641
3007
  this.closeDragBackdrop();
3008
+ event.source.reset();
3009
+ this.dragScrolling = false;
3010
+ this.barHandleDragMoveDistance = 0;
2642
3011
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2643
3012
  });
2644
3013
  dragRefs.push(dragRef);
@@ -2696,8 +3065,10 @@ class GanttBarDrag {
2696
3065
  return dragRefs;
2697
3066
  }
2698
3067
  openDragBackdrop(dragElement, start, end) {
2699
- const dragBackdropElement = this.root.backdrop.nativeElement;
2700
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3068
+ // const dragBackdropElement = this.root.backdrop.nativeElement;
3069
+ // const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask') as HTMLElement;
3070
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3071
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2701
3072
  const rootRect = this.dom.root.getBoundingClientRect();
2702
3073
  const dragRect = dragElement.getBoundingClientRect();
2703
3074
  const left = dragRect.left - rootRect.left - this.dom.side.clientWidth;
@@ -2712,8 +3083,8 @@ class GanttBarDrag {
2712
3083
  dragMaskElement.querySelector('.end').innerHTML = end.format('MM-dd');
2713
3084
  }
2714
3085
  closeDragBackdrop() {
2715
- const dragBackdropElement = this.root.backdrop.nativeElement;
2716
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3086
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3087
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2717
3088
  dragMaskElement.style.display = 'none';
2718
3089
  dragBackdropElement.style.display = 'none';
2719
3090
  }
@@ -2725,6 +3096,45 @@ class GanttBarDrag {
2725
3096
  this.barElement.style.pointerEvents = '';
2726
3097
  this.barElement.classList.remove('gantt-bar-draggable-drag');
2727
3098
  }
3099
+ barDragMove(dragRef, distance) {
3100
+ const currentX = this.item.refs.x + distance;
3101
+ const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
3102
+ const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
3103
+ const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
3104
+ const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
3105
+ let start = currentDate;
3106
+ let end = currentDate.addDays(diffDays);
3107
+ if (currentX > currentStartX + dayWidth / 2) {
3108
+ start = start.addDays(1);
3109
+ end = end.addDays(1);
3110
+ }
3111
+ this.openDragBackdrop(dragRef['_preview'], this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
3112
+ this.item.updateDate(start, end);
3113
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3114
+ }
3115
+ barHandleDragMove(distance, isBefore) {
3116
+ if (isBefore) {
3117
+ const x = this.item.refs.x + distance;
3118
+ const width = this.item.refs.width + distance * -1;
3119
+ const start = this.ganttUpper.view.getDateByXPoint(x);
3120
+ if (width > dragMinWidth) {
3121
+ this.barElement.style.width = width + 'px';
3122
+ this.barElement.style.left = x + 'px';
3123
+ this.openDragBackdrop(this.barElement, start, this.item.end);
3124
+ this.item.updateDate(start, this.item.end);
3125
+ }
3126
+ }
3127
+ else {
3128
+ const width = this.item.refs.width + distance;
3129
+ const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
3130
+ if (width > dragMinWidth) {
3131
+ this.barElement.style.width = width + 'px';
3132
+ this.openDragBackdrop(this.barElement, this.item.start, end);
3133
+ this.item.updateDate(this.item.start, end);
3134
+ }
3135
+ }
3136
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3137
+ }
2728
3138
  calcLinkLinePositions(target, isBefore) {
2729
3139
  const rootRect = this.dom.root.getBoundingClientRect();
2730
3140
  const targetRect = target.getBoundingClientRect();
@@ -2756,7 +3166,6 @@ class GanttBarDrag {
2756
3166
  this.item = item;
2757
3167
  this.barElement = elementRef.nativeElement;
2758
3168
  this.ganttUpper = ganttUpper;
2759
- // if (!item.draggable || (this.dragDisabled && this.linkDragDisabled)) {
2760
3169
  if (this.dragDisabled && this.linkDragDisabled) {
2761
3170
  return;
2762
3171
  }
@@ -2766,6 +3175,13 @@ class GanttBarDrag {
2766
3175
  const dragRef = this.createBarDrag();
2767
3176
  const dragHandlesRefs = this.createBarHandleDrags();
2768
3177
  this.dragRefs.push(dragRef, ...dragHandlesRefs);
3178
+ // 创建拖拽容器并将所有元素添加到容器中,利用容器来实现自动滚动
3179
+ if (!this.dropListRef) {
3180
+ this.dropListRef = this.dragDrop.createDropList(this.dom.mainContainer);
3181
+ this.dropListRef.autoScrollStep = autoScrollStep;
3182
+ this.dropListRef.withOrientation('horizontal');
3183
+ }
3184
+ this.dropListRef.withItems([dragRef, ...dragHandlesRefs]);
2769
3185
  }
2770
3186
  if (!this.linkDragDisabled) {
2771
3187
  const linkDragRefs = this.createLinkHandleDrags();
@@ -2773,6 +3189,9 @@ class GanttBarDrag {
2773
3189
  }
2774
3190
  }
2775
3191
  }
3192
+ updateItem(item) {
3193
+ this.item = item;
3194
+ }
2776
3195
  ngOnDestroy() {
2777
3196
  this.closeDragBackdrop();
2778
3197
  this.dragRefs.forEach((dragRef) => dragRef.dispose());
@@ -2780,12 +3199,12 @@ class GanttBarDrag {
2780
3199
  this.destroy$.complete();
2781
3200
  }
2782
3201
  }
2783
- GanttBarDrag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, deps: [{ token: i1$1.DragDrop }, { token: GanttDomService }, { token: GanttDragContainer }, { token: NgxGanttRootComponent, skipSelf: true }], target: i0.ɵɵFactoryTarget.Injectable });
3202
+ GanttBarDrag.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, deps: [{ token: i2.DragDrop }, { token: GanttDomService }, { token: GanttDragContainer }, { token: NgxGanttRootComponent, skipSelf: true }], target: i0.ɵɵFactoryTarget.Injectable });
2784
3203
  GanttBarDrag.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag });
2785
3204
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, decorators: [{
2786
3205
  type: Injectable
2787
3206
  }], ctorParameters: function () {
2788
- return [{ type: i1$1.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
3207
+ return [{ type: i2.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
2789
3208
  type: SkipSelf
2790
3209
  }] }];
2791
3210
  } });
@@ -2803,16 +3222,26 @@ class GanttItemUpper {
2803
3222
  this.setPositions();
2804
3223
  });
2805
3224
  }
2806
- ngOnChanges() {
3225
+ ngOnChanges(changes) {
2807
3226
  if (!this.firstChange) {
2808
- this.setPositions();
3227
+ this.itemChange(changes.item.currentValue);
2809
3228
  }
2810
3229
  }
3230
+ itemChange(item) {
3231
+ this.unsubscribe$.next();
3232
+ this.unsubscribe$.complete();
3233
+ this.item = item;
3234
+ this.setPositions();
3235
+ this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3236
+ this.setPositions();
3237
+ });
3238
+ }
2811
3239
  setPositions() {
3240
+ var _a, _b, _c;
2812
3241
  const itemElement = this.elementRef.nativeElement;
2813
- itemElement.style.left = this.item.refs.x + 'px';
2814
- itemElement.style.top = this.item.refs.y + 'px';
2815
- itemElement.style.width = this.item.refs.width + 'px';
3242
+ itemElement.style.left = ((_a = this.item.refs) === null || _a === void 0 ? void 0 : _a.x) + 'px';
3243
+ itemElement.style.top = ((_b = this.item.refs) === null || _b === void 0 ? void 0 : _b.y) + 'px';
3244
+ itemElement.style.width = ((_c = this.item.refs) === null || _c === void 0 ? void 0 : _c.width) + 'px';
2816
3245
  if (this.item.type === GanttItemType.bar) {
2817
3246
  itemElement.style.height = this.ganttUpper.styles.barHeight + 'px';
2818
3247
  }
@@ -2859,6 +3288,12 @@ class NgxGanttBarComponent extends GanttItemUpper {
2859
3288
  this.setContentBackground();
2860
3289
  });
2861
3290
  }
3291
+ ngOnChanges(changes) {
3292
+ super.ngOnChanges(changes);
3293
+ if (!this.firstChange) {
3294
+ this.drag.updateItem(this.item);
3295
+ }
3296
+ }
2862
3297
  ngAfterViewInit() {
2863
3298
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2864
3299
  // the `onStable` will never emit any value.
@@ -2872,7 +3307,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2872
3307
  });
2873
3308
  this.setContentBackground();
2874
3309
  this.handles.changes
2875
- .pipe(startWith(this.handles), switchMap(() =>
3310
+ .pipe(startWith$1(this.handles), switchMap(() =>
2876
3311
  // Note: we need to explicitly subscribe outside of the Angular zone since `addEventListener`
2877
3312
  // is called when the `fromEvent` is subscribed.
2878
3313
  new Observable((subscriber) => this.ngZone.runOutsideAngular(() => merge(...this.handles.toArray().map((handle) => fromEvent(handle.nativeElement, 'mousedown'))).subscribe(subscriber)))), takeUntil(this.unsubscribe$))
@@ -2916,7 +3351,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2916
3351
  }
2917
3352
  }
2918
3353
  NgxGanttBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttBarComponent, deps: [{ token: GanttDragContainer }, { token: GanttBarDrag }, { token: i0.ElementRef }, { token: GANTT_UPPER_TOKEN }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2919
- NgxGanttBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttBarComponent, selector: "ngx-gantt-bar,gantt-bar", outputs: { barClick: "barClick" }, host: { properties: { "class.gantt-bar": "this.ganttItemClass" } }, providers: [GanttBarDrag], viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true }, { propertyName: "handles", predicate: ["handle"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"gantt-bar-layer\">\n <div class=\"drag-handles\">\n <ng-container *ngIf=\"item.draggable && ganttUpper.draggable\">\n <span class=\"handle\" #handle></span>\n <span class=\"handle\" #handle></span>\n </ng-container>\n </div>\n <div *ngIf=\"item.linkable && ganttUpper.linkable\" class=\"link-handles\">\n <span class=\"handle\"><span class=\"point\"></span></span>\n <span class=\"handle\"> <span class=\"point\"></span></span>\n </div>\n</div>\n<div class=\"gantt-bar-border\"></div>\n<div #content class=\"gantt-bar-content\" (click)=\"onBarClick($event)\">\n <div class=\"gantt-bar-content-progress\" *ngIf=\"item.progress >= 0\" [style.width.%]=\"item.progress * 100\"></div>\n <ng-template [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ item: item.origin, refs: item.refs }\"></ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
3354
+ NgxGanttBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttBarComponent, selector: "ngx-gantt-bar,gantt-bar", outputs: { barClick: "barClick" }, host: { properties: { "class.gantt-bar": "this.ganttItemClass" } }, providers: [GanttBarDrag], viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true }, { propertyName: "handles", predicate: ["handle"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"gantt-bar-layer\">\n <div class=\"drag-handles\">\n <ng-container *ngIf=\"item.draggable && ganttUpper.draggable\">\n <span class=\"handle\" #handle></span>\n <span class=\"handle\" #handle></span>\n </ng-container>\n </div>\n <div *ngIf=\"item.linkable && ganttUpper.linkable\" class=\"link-handles\">\n <span class=\"handle\"><span class=\"point\"></span></span>\n <span class=\"handle\"> <span class=\"point\"></span></span>\n </div>\n</div>\n<div class=\"gantt-bar-border\"></div>\n<div #content class=\"gantt-bar-content\" (click)=\"onBarClick($event)\">\n <div class=\"gantt-bar-content-progress\" *ngIf=\"item.progress >= 0\" [style.width.%]=\"item.progress * 100\"></div>\n <ng-template [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ item: item.origin, refs: item.refs }\"></ng-template>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2920
3355
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttBarComponent, decorators: [{
2921
3356
  type: Component,
2922
3357
  args: [{ selector: 'ngx-gantt-bar,gantt-bar', providers: [GanttBarDrag], template: "<div class=\"gantt-bar-layer\">\n <div class=\"drag-handles\">\n <ng-container *ngIf=\"item.draggable && ganttUpper.draggable\">\n <span class=\"handle\" #handle></span>\n <span class=\"handle\" #handle></span>\n </ng-container>\n </div>\n <div *ngIf=\"item.linkable && ganttUpper.linkable\" class=\"link-handles\">\n <span class=\"handle\"><span class=\"point\"></span></span>\n <span class=\"handle\"> <span class=\"point\"></span></span>\n </div>\n</div>\n<div class=\"gantt-bar-border\"></div>\n<div #content class=\"gantt-bar-content\" (click)=\"onBarClick($event)\">\n <div class=\"gantt-bar-content-progress\" *ngIf=\"item.progress >= 0\" [style.width.%]=\"item.progress * 100\"></div>\n <ng-template [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ item: item.origin, refs: item.refs }\"></ng-template>\n</div>\n" }]
@@ -3007,18 +3442,18 @@ class GanttMainComponent {
3007
3442
  }
3008
3443
  }
3009
3444
  GanttMainComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, deps: [{ token: GANTT_UPPER_TOKEN }], target: i0.ɵɵFactoryTarget.Component });
3010
- GanttMainComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttMainComponent, selector: "gantt-main", inputs: { groups: "groups", items: "items", groupHeaderTemplate: "groupHeaderTemplate", itemTemplate: "itemTemplate", barTemplate: "barTemplate", rangeTemplate: "rangeTemplate" }, outputs: { barClick: "barClick", lineClick: "lineClick" }, host: { properties: { "class.gantt-main-container": "this.ganttMainClass" } }, ngImport: i0, template: "<gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<!-- groups -->\n<div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div>\n\n<!-- items -->\n<ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: ["groups", "items"], outputs: ["lineClick"] }, { kind: "component", type: NgxGanttBarComponent, selector: "ngx-gantt-bar,gantt-bar", outputs: ["barClick"] }, { kind: "component", type: NgxGanttRangeComponent, selector: "ngx-gantt-range,gantt-range" }, { kind: "component", type: NgxGanttBaselineComponent, selector: "ngx-gantt-baseline,gantt-baseline", inputs: ["baselineItem"] }, { kind: "pipe", type: IsGanttRangeItemPipe, name: "isGanttRangeItem" }, { kind: "pipe", type: IsGanttBarItemPipe, name: "isGanttBarItem" }, { kind: "pipe", type: IsGanttCustomItemPipe, name: "isGanttCustomItem" }] });
3445
+ GanttMainComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttMainComponent, selector: "gantt-main", inputs: { renderData: "renderData", flatData: "flatData", groupHeaderTemplate: "groupHeaderTemplate", itemTemplate: "itemTemplate", barTemplate: "barTemplate", rangeTemplate: "rangeTemplate" }, outputs: { barClick: "barClick", lineClick: "lineClick" }, host: { properties: { "class.gantt-main-container": "this.ganttMainClass" } }, ngImport: i0, template: "<!-- <gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay> -->\n<!-- groups -->\n<!-- <div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div> -->\n\n<!-- items -->\n<!-- <ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template> -->\n\n<gantt-links-overlay [flatData]=\"flatData\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<div class=\"gantt-main-groups\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let data of renderData; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"data.class\" *ngIf=\"data.items\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: data }\"></ng-template>\n </div>\n <div\n *ngIf=\"!data.items\"\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(data.id)\"\n >\n <ng-container *ngIf=\"data.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: data.origin,\n refs: data.refs,\n baseline: ganttUpper.baselineItemsMap[data.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[data.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(data.type | isGanttRangeItem) || (data.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"data.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"data\"></gantt-range>\n <gantt-bar *ngIf=\"data.type | isGanttBarItem\" [item]=\"data\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[data.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[data.id]\"></gantt-baseline>\n </ng-container>\n </div>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: ["flatData"], outputs: ["lineClick"] }, { kind: "component", type: NgxGanttBarComponent, selector: "ngx-gantt-bar,gantt-bar", outputs: ["barClick"] }, { kind: "component", type: NgxGanttRangeComponent, selector: "ngx-gantt-range,gantt-range" }, { kind: "component", type: NgxGanttBaselineComponent, selector: "ngx-gantt-baseline,gantt-baseline", inputs: ["baselineItem"] }, { kind: "pipe", type: IsGanttRangeItemPipe, name: "isGanttRangeItem" }, { kind: "pipe", type: IsGanttBarItemPipe, name: "isGanttBarItem" }, { kind: "pipe", type: IsGanttCustomItemPipe, name: "isGanttCustomItem" }] });
3011
3446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, decorators: [{
3012
3447
  type: Component,
3013
- args: [{ selector: 'gantt-main', template: "<gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<!-- groups -->\n<div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div>\n\n<!-- items -->\n<ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n" }]
3448
+ args: [{ selector: 'gantt-main', template: "<!-- <gantt-links-overlay [groups]=\"groups\" [items]=\"items\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay> -->\n<!-- groups -->\n<!-- <div class=\"gantt-main-groups\" *ngIf=\"groups && groups.length > 0; else itemsTemplate\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"group.class\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: group }\"></ng-template>\n </div>\n <div *ngIf=\"group.expanded\" class=\"gantt-items\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: group.items }\"></ng-template>\n </div>\n </ng-container>\n</div> -->\n\n<!-- items -->\n<!-- <ng-template #itemsTemplate>\n <div class=\"gantt-main-items\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items }\"></ng-template>\n </div>\n</ng-template>\n\n<ng-template #ganttItems let-items=\"items\">\n <ng-container *ngFor=\"let item of items\">\n <div\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(item.id)\"\n >\n <ng-container *ngIf=\"item.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: item.origin,\n refs: item.refs,\n baseline: ganttUpper.baselineItemsMap[item.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[item.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(item.type | isGanttRangeItem) || (item.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"item.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"item\"></gantt-range>\n <gantt-bar *ngIf=\"item.type | isGanttBarItem\" [item]=\"item\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[item.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[item.id]\"></gantt-baseline>\n </ng-container>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children }\"\n ></ng-template>\n </ng-container>\n</ng-template> -->\n\n<gantt-links-overlay [flatData]=\"flatData\" (lineClick)=\"lineClick.emit($event)\"></gantt-links-overlay>\n<div class=\"gantt-main-groups\" [style.width.px]=\"ganttUpper.view.width\">\n <ng-container *ngFor=\"let data of renderData; trackBy: trackBy\">\n <div class=\"gantt-group\" [ngClass]=\"data.class\" *ngIf=\"data.items\">\n <ng-template [ngTemplateOutlet]=\"groupHeaderTemplate\" [ngTemplateOutletContext]=\"{ group: data }\"></ng-template>\n </div>\n <div\n *ngIf=\"!data.items\"\n class=\"gantt-item\"\n [style.height.px]=\"ganttUpper.styles.lineHeight\"\n [class.gantt-main-item-active]=\"ganttUpper.isSelected(data.id)\"\n >\n <ng-container *ngIf=\"data.type | isGanttCustomItem\">\n <ng-template\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: data.origin,\n refs: data.refs,\n baseline: ganttUpper.baselineItemsMap[data.id]?.origin,\n baselineRefs: ganttUpper.baselineItemsMap[data.id]?.refs\n }\"\n >\n </ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"(data.type | isGanttRangeItem) || (data.type | isGanttBarItem)\">\n <gantt-range *ngIf=\"data.type | isGanttRangeItem\" [template]=\"rangeTemplate\" [item]=\"data\"></gantt-range>\n <gantt-bar *ngIf=\"data.type | isGanttBarItem\" [item]=\"data\" [template]=\"barTemplate\" (barClick)=\"barClick.emit($event)\"></gantt-bar>\n <gantt-baseline *ngIf=\"ganttUpper.baselineItemsMap[data.id]\" [baselineItem]=\"ganttUpper.baselineItemsMap[data.id]\"></gantt-baseline>\n </ng-container>\n </div>\n </ng-container>\n</div>\n" }]
3014
3449
  }], ctorParameters: function () {
3015
3450
  return [{ type: GanttUpper, decorators: [{
3016
3451
  type: Inject,
3017
3452
  args: [GANTT_UPPER_TOKEN]
3018
3453
  }] }];
3019
- }, propDecorators: { groups: [{
3454
+ }, propDecorators: { renderData: [{
3020
3455
  type: Input
3021
- }], items: [{
3456
+ }], flatData: [{
3022
3457
  type: Input
3023
3458
  }], groupHeaderTemplate: [{
3024
3459
  type: Input
@@ -3038,18 +3473,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3038
3473
  }] } });
3039
3474
 
3040
3475
  class NgxGanttComponent extends GanttUpper {
3041
- constructor(elementRef, cdr, ngZone, config) {
3476
+ constructor(elementRef, cdr, ngZone, printService, config) {
3042
3477
  super(elementRef, cdr, ngZone, config);
3478
+ this.printService = printService;
3043
3479
  this.maxLevel = 2;
3044
3480
  this.linkDragStarted = new EventEmitter();
3045
3481
  this.linkDragEnded = new EventEmitter();
3046
3482
  this.lineClick = new EventEmitter();
3047
3483
  this.selectedChange = new EventEmitter();
3048
- this.ngUnsubscribe$ = new Subject();
3049
- this.sideTableWidth = sideWidth;
3484
+ this.flatData = [];
3485
+ this.renderData = [];
3486
+ this.computeAllRefs = false;
3050
3487
  }
3051
3488
  ngOnInit() {
3052
3489
  super.ngOnInit();
3490
+ this.buildVirtualFlatData();
3053
3491
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
3054
3492
  // the `onStable` will never emit any value.
3055
3493
  const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
@@ -3057,24 +3495,84 @@ class NgxGanttComponent extends GanttUpper {
3057
3495
  // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
3058
3496
  this.ngZone.runOutsideAngular(() => {
3059
3497
  onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3060
- this.dragContainer.linkDragStarted.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3498
+ // this.dragContainer.dragEnded.subscribe((event) => {
3499
+ // this.computeTempDataRefs();
3500
+ // });
3501
+ this.dragContainer.linkDragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3061
3502
  this.linkDragStarted.emit(event);
3062
3503
  });
3063
- this.dragContainer.linkDragEnded.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3504
+ this.dragContainer.linkDragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3064
3505
  this.linkDragEnded.emit(event);
3065
3506
  });
3066
3507
  });
3067
3508
  });
3509
+ this.view.start$.pipe(skip(1), takeUntil(this.unsubscribe$)).subscribe(() => {
3510
+ this.computeTempDataRefs();
3511
+ });
3512
+ }
3513
+ ngOnChanges(changes) {
3514
+ super.ngOnChanges(changes);
3515
+ if (!this.firstChange) {
3516
+ if (changes.viewType && changes.viewType.currentValue) {
3517
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3518
+ this.computeTempDataRefs();
3519
+ }
3520
+ if (changes.originItems || changes.originGroups) {
3521
+ this.buildVirtualFlatData();
3522
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3523
+ this.computeTempDataRefs();
3524
+ }
3525
+ }
3068
3526
  }
3069
3527
  ngAfterViewInit() {
3070
- this.columns.changes.pipe(startWith(true), takeUntil(this.ngUnsubscribe$)).subscribe(() => {
3071
- this.columns.forEach((column) => {
3072
- if (!column.columnWidth) {
3073
- column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
3528
+ this.virtualScroll.renderedRangeStream.pipe(takeUntil(this.unsubscribe$)).subscribe((range) => {
3529
+ const linksElement = this.elementRef.nativeElement.querySelector('.gantt-links-overlay');
3530
+ linksElement.style.top = `${-(this.styles.lineHeight * range.start)}px`;
3531
+ this.rangeStart = range.start;
3532
+ this.rangeEnd = range.end;
3533
+ this.renderData = this.flatData.slice(range.start, range.end);
3534
+ this.computeTempDataRefs();
3535
+ });
3536
+ }
3537
+ buildVirtualFlatData() {
3538
+ const virtualData = [];
3539
+ if (this.groups.length) {
3540
+ this.groups.forEach((group) => {
3541
+ virtualData.push(group);
3542
+ if (group.expanded) {
3543
+ const items = recursiveItems(group.items);
3544
+ virtualData.push(...items);
3074
3545
  }
3075
3546
  });
3076
- this.cdr.detectChanges();
3547
+ }
3548
+ if (this.items.length) {
3549
+ virtualData.push(...recursiveItems(this.items));
3550
+ }
3551
+ this.flatData = [...virtualData];
3552
+ this.flatDataMap = keyBy(this.flatData, 'id');
3553
+ }
3554
+ afterExpand() {
3555
+ this.buildVirtualFlatData();
3556
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3557
+ }
3558
+ computeTempDataRefs() {
3559
+ const tempItemData = [];
3560
+ this.renderData.forEach((data) => {
3561
+ if (!data.hasOwnProperty('items')) {
3562
+ const item = data;
3563
+ if (item.links) {
3564
+ item.links.forEach((link) => {
3565
+ if (this.flatDataMap[link.link]) {
3566
+ tempItemData.push(this.flatDataMap[link.link]);
3567
+ }
3568
+ });
3569
+ }
3570
+ tempItemData.push(data);
3571
+ }
3077
3572
  });
3573
+ this.computeItemsRefs(...uniqBy(tempItemData, 'id'));
3574
+ this.flatData = [...this.flatData];
3575
+ this.renderData = [...this.renderData];
3078
3576
  }
3079
3577
  expandChildren(item) {
3080
3578
  if (!item.expanded) {
@@ -3084,6 +3582,7 @@ class NgxGanttComponent extends GanttUpper {
3084
3582
  this.childrenResolve(item.origin)
3085
3583
  .pipe(take(1), finalize(() => {
3086
3584
  item.loading = false;
3585
+ this.afterExpand();
3087
3586
  this.expandChange.emit(item);
3088
3587
  this.cdr.detectChanges();
3089
3588
  }))
@@ -3094,11 +3593,13 @@ class NgxGanttComponent extends GanttUpper {
3094
3593
  }
3095
3594
  else {
3096
3595
  this.computeItemsRefs(...item.children);
3596
+ this.afterExpand();
3097
3597
  this.expandChange.emit(item);
3098
3598
  }
3099
3599
  }
3100
3600
  else {
3101
3601
  item.setExpand(false);
3602
+ this.afterExpand();
3102
3603
  this.expandChange.emit(item);
3103
3604
  }
3104
3605
  }
@@ -3125,8 +3626,22 @@ class NgxGanttComponent extends GanttUpper {
3125
3626
  scrollToDate(date) {
3126
3627
  this.ganttRoot.scrollToDate(date);
3127
3628
  }
3629
+ expandGroups(expanded) {
3630
+ this.groups.forEach((group) => {
3631
+ group.setExpand(expanded);
3632
+ });
3633
+ this.afterExpand();
3634
+ this.expandChange.next(null);
3635
+ this.cdr.detectChanges();
3636
+ }
3637
+ expandGroup(group) {
3638
+ group.setExpand(!group.expanded);
3639
+ this.afterExpand();
3640
+ this.expandChange.emit();
3641
+ this.cdr.detectChanges();
3642
+ }
3128
3643
  }
3129
- NgxGanttComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: GANTT_GLOBAL_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
3644
+ NgxGanttComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: GanttPrintService, optional: true }, { token: GANTT_GLOBAL_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
3130
3645
  NgxGanttComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttComponent, selector: "ngx-gantt", inputs: { maxLevel: "maxLevel", async: "async", childrenResolve: "childrenResolve", linkable: "linkable" }, outputs: { linkDragStarted: "linkDragStarted", linkDragEnded: "linkDragEnded", lineClick: "lineClick", selectedChange: "selectedChange" }, providers: [
3131
3646
  {
3132
3647
  provide: GANTT_UPPER_TOKEN,
@@ -3136,7 +3651,7 @@ NgxGanttComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
3136
3651
  provide: GANTT_ABSTRACT_TOKEN,
3137
3652
  useExisting: forwardRef(() => NgxGanttComponent)
3138
3653
  }
3139
- ], queries: [{ propertyName: "table", first: true, predicate: NgxGanttTableComponent, descendants: true }, { propertyName: "tableEmptyTemplate", first: true, predicate: ["tableEmpty"], descendants: true, static: true }, { propertyName: "columns", predicate: NgxGanttTableColumnComponent, descendants: true }], viewQueries: [{ propertyName: "ganttRoot", first: true, predicate: ["ganttRoot"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ngx-gantt-root #ganttRoot>\n <ng-template #sideTemplate>\n <gantt-table\n [groups]=\"groups\"\n [items]=\"items\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table>\n </ng-template>\n <ng-template #mainTemplate>\n <gantt-main\n [groups]=\"groups\"\n [items]=\"items\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </ng-template>\n</ngx-gantt-root>\n", dependencies: [{ kind: "component", type: GanttTableComponent, selector: "gantt-table", inputs: ["groups", "items", "columns", "groupTemplate", "emptyTemplate", "rowBeforeTemplate", "rowAfterTemplate"], outputs: ["itemClick"] }, { kind: "component", type: GanttMainComponent, selector: "gantt-main", inputs: ["groups", "items", "groupHeaderTemplate", "itemTemplate", "barTemplate", "rangeTemplate"], outputs: ["barClick", "lineClick"] }, { kind: "component", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: ["sideWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3654
+ ], queries: [{ propertyName: "table", first: true, predicate: NgxGanttTableComponent, descendants: true }, { propertyName: "tableEmptyTemplate", first: true, predicate: ["tableEmpty"], descendants: true, static: true }, { propertyName: "columns", predicate: NgxGanttTableColumnComponent, descendants: true }], viewQueries: [{ propertyName: "ganttRoot", first: true, predicate: ["ganttRoot"], descendants: true }, { propertyName: "virtualScroll", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ngx-gantt-root #ganttRoot>\n <div class=\"gantt-header\">\n <gantt-table-header #tableHeader [columns]=\"columns\"></gantt-table-header>\n <div class=\"gantt-container-header\">\n <gantt-calendar-header></gantt-calendar-header>\n </div>\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"gantt-virtual-scroll-viewport\"\n [itemSize]=\"styles.lineHeight\"\n [minBufferPx]=\"styles.lineHeight * 10\"\n [maxBufferPx]=\"styles.lineHeight * 20\"\n >\n <ng-container *cdkVirtualFor=\"let item of flatData; trackBy: trackBy\"></ng-container>\n <div class=\"gantt-side\">\n <div class=\"gantt-side-container\">\n <div class=\"gantt-table\">\n <gantt-table-body\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n [draggable]=\"table.draggable\"\n [dropEnterPredicate]=\"table.dropEnterPredicate\"\n (dragDropped)=\"table.dragDropped.emit($event)\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table-body>\n </div>\n </div>\n </div>\n <div class=\"gantt-container\">\n <gantt-calendar-grid></gantt-calendar-grid>\n <div class=\"gantt-main\">\n <gantt-main\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n <gantt-drag-backdrop [style.left.px]=\"tableHeader.tableWidth + 1\"></gantt-drag-backdrop>\n</ngx-gantt-root>\n", dependencies: [{ kind: "directive", type: i2$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: GanttTableHeaderComponent, selector: "gantt-table-header", inputs: ["columns"] }, { kind: "component", type: GanttTableBodyComponent, selector: "gantt-table-body", inputs: ["renderData", "flatData", "columns", "groupTemplate", "emptyTemplate", "rowBeforeTemplate", "rowAfterTemplate", "draggable", "dropEnterPredicate"], outputs: ["dragDropped", "itemClick"] }, { kind: "component", type: GanttMainComponent, selector: "gantt-main", inputs: ["renderData", "flatData", "groupHeaderTemplate", "itemTemplate", "barTemplate", "rangeTemplate"], outputs: ["barClick", "lineClick"] }, { kind: "component", type: GanttCalendarHeaderComponent, selector: "gantt-calendar-header" }, { kind: "component", type: GanttCalendarGridComponent, selector: "gantt-calendar-grid" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: ["sideWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3140
3655
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, decorators: [{
3141
3656
  type: Component,
3142
3657
  args: [{ selector: 'ngx-gantt', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
@@ -3148,9 +3663,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3148
3663
  provide: GANTT_ABSTRACT_TOKEN,
3149
3664
  useExisting: forwardRef(() => NgxGanttComponent)
3150
3665
  }
3151
- ], template: "<ngx-gantt-root #ganttRoot>\n <ng-template #sideTemplate>\n <gantt-table\n [groups]=\"groups\"\n [items]=\"items\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table>\n </ng-template>\n <ng-template #mainTemplate>\n <gantt-main\n [groups]=\"groups\"\n [items]=\"items\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </ng-template>\n</ngx-gantt-root>\n" }]
3666
+ ], template: "<ngx-gantt-root #ganttRoot>\n <div class=\"gantt-header\">\n <gantt-table-header #tableHeader [columns]=\"columns\"></gantt-table-header>\n <div class=\"gantt-container-header\">\n <gantt-calendar-header></gantt-calendar-header>\n </div>\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"gantt-virtual-scroll-viewport\"\n [itemSize]=\"styles.lineHeight\"\n [minBufferPx]=\"styles.lineHeight * 10\"\n [maxBufferPx]=\"styles.lineHeight * 20\"\n >\n <ng-container *cdkVirtualFor=\"let item of flatData; trackBy: trackBy\"></ng-container>\n <div class=\"gantt-side\">\n <div class=\"gantt-side-container\">\n <div class=\"gantt-table\">\n <gantt-table-body\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n [draggable]=\"table.draggable\"\n [dropEnterPredicate]=\"table.dropEnterPredicate\"\n (dragDropped)=\"table.dragDropped.emit($event)\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table-body>\n </div>\n </div>\n </div>\n <div class=\"gantt-container\">\n <gantt-calendar-grid></gantt-calendar-grid>\n <div class=\"gantt-main\">\n <gantt-main\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n <gantt-drag-backdrop [style.left.px]=\"tableHeader.tableWidth + 1\"></gantt-drag-backdrop>\n</ngx-gantt-root>\n" }]
3152
3667
  }], ctorParameters: function () {
3153
- return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
3668
+ return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: GanttPrintService, decorators: [{
3669
+ type: Optional
3670
+ }] }, { type: undefined, decorators: [{
3154
3671
  type: Inject,
3155
3672
  args: [GANTT_GLOBAL_CONFIG]
3156
3673
  }] }];
@@ -3182,6 +3699,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3182
3699
  }], ganttRoot: [{
3183
3700
  type: ViewChild,
3184
3701
  args: ['ganttRoot']
3702
+ }], virtualScroll: [{
3703
+ type: ViewChild,
3704
+ args: [CdkVirtualScrollViewport]
3185
3705
  }] } });
3186
3706
 
3187
3707
  class NgxGanttModule {
@@ -3190,9 +3710,13 @@ NgxGanttModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
3190
3710
  NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, declarations: [NgxGanttComponent,
3191
3711
  NgxGanttTableComponent,
3192
3712
  NgxGanttTableColumnComponent,
3193
- GanttTableComponent,
3713
+ // GanttTableComponent,
3714
+ GanttTableHeaderComponent,
3715
+ GanttTableBodyComponent,
3194
3716
  GanttMainComponent,
3195
- GanttCalendarComponent,
3717
+ // GanttCalendarComponent,
3718
+ GanttCalendarHeaderComponent,
3719
+ GanttCalendarGridComponent,
3196
3720
  GanttLinksComponent,
3197
3721
  NgxGanttBarComponent,
3198
3722
  GanttIconComponent,
@@ -3203,7 +3727,7 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3203
3727
  NgxGanttToolbarComponent,
3204
3728
  IsGanttRangeItemPipe,
3205
3729
  IsGanttBarItemPipe,
3206
- IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule], exports: [NgxGanttComponent,
3730
+ IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule, ScrollingModule], exports: [NgxGanttComponent,
3207
3731
  NgxGanttTableComponent,
3208
3732
  NgxGanttTableColumnComponent,
3209
3733
  NgxGanttRootComponent,
@@ -3212,15 +3736,16 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3212
3736
  NgxGanttBaselineComponent,
3213
3737
  NgxGanttToolbarComponent] });
3214
3738
  NgxGanttModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, providers: [
3739
+ CdkVirtualScrollViewport,
3215
3740
  {
3216
3741
  provide: GANTT_GLOBAL_CONFIG,
3217
3742
  useValue: defaultConfig
3218
3743
  }
3219
- ], imports: [CommonModule, DragDropModule] });
3744
+ ], imports: [CommonModule, DragDropModule, ScrollingModule] });
3220
3745
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, decorators: [{
3221
3746
  type: NgModule,
3222
3747
  args: [{
3223
- imports: [CommonModule, DragDropModule],
3748
+ imports: [CommonModule, DragDropModule, ScrollingModule],
3224
3749
  exports: [
3225
3750
  NgxGanttComponent,
3226
3751
  NgxGanttTableComponent,
@@ -3235,9 +3760,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3235
3760
  NgxGanttComponent,
3236
3761
  NgxGanttTableComponent,
3237
3762
  NgxGanttTableColumnComponent,
3238
- GanttTableComponent,
3763
+ // GanttTableComponent,
3764
+ GanttTableHeaderComponent,
3765
+ GanttTableBodyComponent,
3239
3766
  GanttMainComponent,
3240
- GanttCalendarComponent,
3767
+ // GanttCalendarComponent,
3768
+ GanttCalendarHeaderComponent,
3769
+ GanttCalendarGridComponent,
3241
3770
  GanttLinksComponent,
3242
3771
  NgxGanttBarComponent,
3243
3772
  GanttIconComponent,
@@ -3251,6 +3780,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3251
3780
  IsGanttCustomItemPipe
3252
3781
  ],
3253
3782
  providers: [
3783
+ CdkVirtualScrollViewport,
3254
3784
  {
3255
3785
  provide: GANTT_GLOBAL_CONFIG,
3256
3786
  useValue: defaultConfig
@@ -3267,5 +3797,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3267
3797
  * Generated bundle index. Do not edit.
3268
3798
  */
3269
3799
 
3270
- export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttBaselineItemInternal, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLinkLineType, GanttLinkType, GanttLoadOnScrollEvent, GanttPrintService, GanttSelectedEvent, GanttTableEvent, GanttUpper, GanttView, GanttViewType, IsGanttBarItemPipe, IsGanttCustomItemPipe, IsGanttRangeItemPipe, LinkColors, NgxGanttBarComponent, NgxGanttBaselineComponent, NgxGanttComponent, NgxGanttModule, NgxGanttRangeComponent, NgxGanttRootComponent, NgxGanttTableColumnComponent, NgxGanttTableComponent, NgxGanttToolbarComponent, defaultConfig, ganttViews, primaryDatePointTop, registerView, secondaryDatePointTop };
3800
+ export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttBaselineItemInternal, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLinkLineType, GanttLinkType, GanttLoadOnScrollEvent, GanttPrintService, GanttSelectedEvent, GanttTableDragDroppedEvent, GanttTableDragEnterPredicateContext, GanttTableEvent, GanttUpper, GanttView, GanttViewType, IsGanttBarItemPipe, IsGanttCustomItemPipe, IsGanttRangeItemPipe, LinkColors, NgxGanttBarComponent, NgxGanttBaselineComponent, NgxGanttComponent, NgxGanttModule, NgxGanttRangeComponent, NgxGanttRootComponent, NgxGanttTableColumnComponent, NgxGanttTableComponent, NgxGanttToolbarComponent, defaultConfig, ganttViews, primaryDatePointTop, registerView, secondaryDatePointTop };
3271
3801
  //# sourceMappingURL=worktile-gantt.mjs.map