@worktile/gantt 15.0.0 → 15.1.0-next.1

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 (59) 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/loader/loader.component.d.ts +5 -0
  12. package/components/loader/loader.component.scss +90 -0
  13. package/components/main/gantt-main.component.d.ts +3 -3
  14. package/components/table/body/gantt-table-body.component.d.ts +58 -0
  15. package/components/table/gantt-table.component.scss +169 -85
  16. package/components/table/gantt-table.scss +271 -0
  17. package/components/table/header/gantt-table-header.component.d.ts +31 -0
  18. package/esm2020/class/event.mjs +5 -1
  19. package/esm2020/class/item.mjs +9 -4
  20. package/esm2020/components/bar/bar-drag.mjs +106 -42
  21. package/esm2020/components/bar/bar.component.mjs +8 -2
  22. package/esm2020/components/calendar/grid/calendar-grid.component.mjs +71 -0
  23. package/esm2020/components/calendar/header/calendar-header.component.mjs +67 -0
  24. package/esm2020/components/icon/icons.mjs +4 -2
  25. package/esm2020/components/links/links.component.mjs +72 -54
  26. package/esm2020/components/loader/loader.component.mjs +29 -0
  27. package/esm2020/components/main/gantt-main.component.mjs +5 -5
  28. package/esm2020/components/table/body/gantt-table-body.component.mjs +298 -0
  29. package/esm2020/components/table/header/gantt-table-header.component.mjs +140 -0
  30. package/esm2020/gantt-dom.service.mjs +8 -12
  31. package/esm2020/gantt-item-upper.mjs +15 -6
  32. package/esm2020/gantt-print.service.mjs +2 -2
  33. package/esm2020/gantt-upper.mjs +18 -15
  34. package/esm2020/gantt.component.mjs +143 -25
  35. package/esm2020/gantt.module.mjs +28 -10
  36. package/esm2020/public-api.mjs +2 -1
  37. package/esm2020/root.component.mjs +10 -8
  38. package/esm2020/table/gantt-table.component.mjs +12 -4
  39. package/esm2020/utils/helpers.mjs +11 -1
  40. package/fesm2015/worktile-gantt.mjs +969 -378
  41. package/fesm2015/worktile-gantt.mjs.map +1 -1
  42. package/fesm2020/worktile-gantt.mjs +959 -380
  43. package/fesm2020/worktile-gantt.mjs.map +1 -1
  44. package/gantt-dom.service.d.ts +1 -0
  45. package/gantt-item-upper.d.ts +3 -2
  46. package/gantt-upper.d.ts +4 -1
  47. package/gantt.component.d.ts +26 -8
  48. package/gantt.component.scss +39 -0
  49. package/gantt.module.d.ts +19 -15
  50. package/package.json +1 -1
  51. package/public-api.d.ts +1 -0
  52. package/root.component.d.ts +1 -1
  53. package/styles/index.scss +5 -2
  54. package/styles/variables.scss +12 -7
  55. package/table/gantt-table.component.d.ts +5 -2
  56. package/components/calendar/calendar.component.d.ts +0 -26
  57. package/components/table/gantt-table.component.d.ts +0 -42
  58. package/esm2020/components/calendar/calendar.component.mjs +0 -88
  59. package/esm2020/components/table/gantt-table.component.mjs +0 -166
@@ -1,15 +1,17 @@
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';
11
+ import * as i3 from '@angular/cdk/scrolling';
12
+ import { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';
13
+ import * as i2 from '@angular/cdk/drag-drop';
14
+ import { CdkDrag, DragDropModule } from '@angular/cdk/drag-drop';
13
15
  import { __decorate, __param } from 'tslib';
14
16
 
15
17
  class GanttDatePoint {
@@ -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?.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) => {
@@ -889,6 +910,7 @@ class GanttUpper {
889
910
  this.barClick = new EventEmitter();
890
911
  this.viewChange = new EventEmitter();
891
912
  this.expandChange = new EventEmitter();
913
+ this.computeAllRefs = true;
892
914
  this.linkDragEnded = new EventEmitter();
893
915
  this.items = [];
894
916
  this.groups = [];
@@ -922,14 +944,14 @@ class GanttUpper {
922
944
  this.originItems.forEach((origin) => {
923
945
  const group = this.groupsMap[origin.group_id];
924
946
  if (group) {
925
- const item = new GanttItemInternal(origin, { fillDays: this.view.options?.fillDays });
947
+ const item = new GanttItemInternal(origin, 0, { fillDays: this.view.options?.fillDays });
926
948
  group.items.push(item);
927
949
  }
928
950
  });
929
951
  }
930
952
  else {
931
953
  this.originItems.forEach((origin) => {
932
- const item = new GanttItemInternal(origin, { fillDays: this.view.options?.fillDays });
954
+ const item = new GanttItemInternal(origin, 0, { fillDays: this.view.options?.fillDays });
933
955
  this.items.push(item);
934
956
  });
935
957
  }
@@ -989,12 +1011,17 @@ class GanttUpper {
989
1011
  };
990
1012
  }
991
1013
  computeRefs() {
992
- this.groups.forEach((group) => {
993
- const groupItems = recursiveItems(group.items);
994
- this.computeItemsRefs(...groupItems);
995
- });
996
- const items = recursiveItems(this.items);
997
- this.computeItemsRefs(...items);
1014
+ if (this.computeAllRefs) {
1015
+ this.groups.forEach((group) => {
1016
+ const groupItems = recursiveItems(group.items);
1017
+ this.computeItemsRefs(...groupItems);
1018
+ });
1019
+ const items = recursiveItems(this.items);
1020
+ this.computeItemsRefs(...items);
1021
+ }
1022
+ }
1023
+ initSelectionModel() {
1024
+ return new SelectionModel(this.multiple, []);
998
1025
  }
999
1026
  expandGroups(expanded) {
1000
1027
  this.groups.forEach((group) => {
@@ -1003,9 +1030,6 @@ class GanttUpper {
1003
1030
  this.expandChange.next(null);
1004
1031
  this.cdr.detectChanges();
1005
1032
  }
1006
- initSelectionModel() {
1007
- return new SelectionModel(this.multiple, []);
1008
- }
1009
1033
  ngOnInit() {
1010
1034
  this.styles = Object.assign({}, defaultStyles, this.styles);
1011
1035
  this.viewOptions.dateFormat = Object.assign({}, defaultConfig.dateFormat, this.config.dateFormat, this.viewOptions.dateFormat);
@@ -1033,8 +1057,8 @@ class GanttUpper {
1033
1057
  });
1034
1058
  this.dragContainer.dragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
1035
1059
  this.dragEnded.emit(event);
1036
- this.computeRefs();
1037
- this.detectChanges();
1060
+ // this.computeRefs();
1061
+ // this.detectChanges();
1038
1062
  });
1039
1063
  });
1040
1064
  });
@@ -1081,12 +1105,12 @@ class GanttUpper {
1081
1105
  detectChanges() {
1082
1106
  this.cdr.detectChanges();
1083
1107
  }
1108
+ // public functions
1084
1109
  expandGroup(group) {
1085
1110
  group.setExpand(!group.expanded);
1086
1111
  this.expandChange.emit(group);
1087
1112
  this.cdr.detectChanges();
1088
1113
  }
1089
- // public functions
1090
1114
  expandAll() {
1091
1115
  this.expandGroups(true);
1092
1116
  }
@@ -1244,18 +1268,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1244
1268
 
1245
1269
  class NgxGanttTableComponent {
1246
1270
  constructor() {
1271
+ this.draggable = false;
1272
+ this.dragDropped = new EventEmitter();
1247
1273
  this.columnChanges = new EventEmitter();
1248
1274
  }
1249
1275
  }
1250
1276
  NgxGanttTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1251
- 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 });
1277
+ 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 });
1252
1278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, decorators: [{
1253
1279
  type: Component,
1254
1280
  args: [{
1255
1281
  selector: 'ngx-gantt-table',
1256
1282
  template: ''
1257
1283
  }]
1258
- }], propDecorators: { columnChanges: [{
1284
+ }], propDecorators: { draggable: [{
1285
+ type: Input
1286
+ }], dropEnterPredicate: [{
1287
+ type: Input
1288
+ }], dragDropped: [{
1289
+ type: Output
1290
+ }], columnChanges: [{
1259
1291
  type: Output
1260
1292
  }], rowBeforeTemplate: [{
1261
1293
  type: ContentChild,
@@ -1267,6 +1299,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1267
1299
 
1268
1300
  const GANTT_ABSTRACT_TOKEN = new InjectionToken('gantt-abstract-token');
1269
1301
 
1302
+ class GanttPrintService {
1303
+ constructor() { }
1304
+ setInlineStyles(targetElem) {
1305
+ const svgElements = Array.from(targetElem.getElementsByTagName('svg'));
1306
+ for (const svgElement of svgElements) {
1307
+ this.recursElementChildren(svgElement);
1308
+ }
1309
+ }
1310
+ recursElementChildren(node) {
1311
+ const transformProperties = [
1312
+ 'fill',
1313
+ 'color',
1314
+ 'font-size',
1315
+ 'stroke',
1316
+ 'font',
1317
+ 'text-anchor',
1318
+ 'stroke-dasharray',
1319
+ 'shape-rendering',
1320
+ 'stroke-width'
1321
+ ];
1322
+ if (!node.style) {
1323
+ return;
1324
+ }
1325
+ const styles = getComputedStyle(node);
1326
+ for (const transformProperty of transformProperties) {
1327
+ node.style[transformProperty] = styles[transformProperty];
1328
+ }
1329
+ for (const child of Array.from(node.childNodes)) {
1330
+ this.recursElementChildren(child);
1331
+ }
1332
+ }
1333
+ register(root) {
1334
+ this.root = root.nativeElement;
1335
+ this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
1336
+ }
1337
+ async print(name = 'download', ignoreElementClass) {
1338
+ const root = this.root;
1339
+ const mainContainer = this.mainContainer;
1340
+ // set print width
1341
+ const printWidth = root.offsetWidth;
1342
+ // set print height
1343
+ const printHeight = root.offsetHeight - mainContainer.offsetHeight + mainContainer.scrollHeight;
1344
+ const html2canvas = (await import(/* webpackChunkName: 'html2canvas' */ 'html2canvas')).default;
1345
+ html2canvas(root, {
1346
+ logging: false,
1347
+ allowTaint: true,
1348
+ useCORS: true,
1349
+ width: printWidth,
1350
+ height: printHeight,
1351
+ ignoreElements: (element) => {
1352
+ if (ignoreElementClass && element.classList.contains(ignoreElementClass)) {
1353
+ return true;
1354
+ }
1355
+ if (element.classList.contains('gantt-calendar-today-overlay')) {
1356
+ return true;
1357
+ }
1358
+ },
1359
+ onclone: (cloneDocument) => {
1360
+ const ganttClass = root.className;
1361
+ const cloneGanttDom = cloneDocument.querySelector(`.${ganttClass.replace(/\s+/g, '.')}`);
1362
+ const cloneGanttContainerDom = cloneDocument.querySelector('.gantt-container');
1363
+ const cloneCalendarOverlay = cloneDocument.querySelector('.gantt-calendar-grid-main');
1364
+ const cloneLinksOverlay = cloneDocument.querySelector('.gantt-links-overlay-main');
1365
+ // change targetDom width
1366
+ cloneGanttDom.style.width = `${printWidth}px`;
1367
+ cloneGanttDom.style.height = `${printHeight}px`;
1368
+ cloneGanttDom.style.overflow = `unset`;
1369
+ cloneGanttContainerDom.style.backgroundColor = '#fff';
1370
+ cloneCalendarOverlay.setAttribute('height', `${printHeight}`);
1371
+ cloneCalendarOverlay.setAttribute('style', `background: transparent`);
1372
+ if (cloneLinksOverlay) {
1373
+ cloneLinksOverlay.setAttribute('height', `${printHeight}`);
1374
+ cloneLinksOverlay.setAttribute('style', `height: ${printHeight}px`);
1375
+ }
1376
+ // setInlineStyles for svg
1377
+ this.setInlineStyles(cloneGanttDom);
1378
+ }
1379
+ }).then((canvas) => {
1380
+ const link = document.createElement('a');
1381
+ const dataUrl = canvas.toDataURL('image/png');
1382
+ link.download = `${name}.png`;
1383
+ link.href = dataUrl;
1384
+ link.click();
1385
+ });
1386
+ }
1387
+ }
1388
+ GanttPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1389
+ GanttPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService });
1390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, decorators: [{
1391
+ type: Injectable
1392
+ }], ctorParameters: function () { return []; } });
1393
+
1270
1394
  const supports = (typeof window !== 'undefined' && !!window.CSS && CSS.supports) || (() => false);
1271
1395
  /**
1272
1396
  * Note: we don't need to add vendor prefixes within `.scss` files since they're added automatically.
@@ -1282,6 +1406,138 @@ function setStyleWithVendorPrefix({ element, style, value }) {
1282
1406
  }
1283
1407
  }
1284
1408
 
1409
+ const defaultColumnWidth = 100;
1410
+ const minColumnWidth = 80;
1411
+ class GanttTableHeaderComponent {
1412
+ constructor(elementRef, gantt, cdr) {
1413
+ this.elementRef = elementRef;
1414
+ this.gantt = gantt;
1415
+ this.cdr = cdr;
1416
+ this.tableWidth = 0;
1417
+ this.unsubscribe$ = new Subject();
1418
+ this.className = `gantt-table-header `;
1419
+ }
1420
+ ngOnInit() {
1421
+ this.columnsChange();
1422
+ this.columns.changes.pipe(takeUntil$1(this.unsubscribe$)).subscribe(() => {
1423
+ this.columnsChange();
1424
+ this.cdr.detectChanges();
1425
+ });
1426
+ }
1427
+ columnsChange() {
1428
+ let tableWidth = 0;
1429
+ this.columns.forEach((column) => {
1430
+ if (!column.columnWidth) {
1431
+ column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1432
+ }
1433
+ tableWidth += Number(column.columnWidth.replace('px', ''));
1434
+ });
1435
+ this.tableWidth = tableWidth;
1436
+ }
1437
+ dragFixed(config) {
1438
+ if (config.movedWidth < config.minWidth) {
1439
+ setStyleWithVendorPrefix({
1440
+ element: config.target,
1441
+ style: 'transform',
1442
+ value: `translate3d(${config.minWidth - config.originWidth}px, 0, 0)`
1443
+ });
1444
+ }
1445
+ }
1446
+ onResizeStarted(event) {
1447
+ const target = event.source.element.nativeElement;
1448
+ this.dragStartLeft = target.getBoundingClientRect().left;
1449
+ }
1450
+ onResizeMoved(event, column) {
1451
+ const target = event.source.element.nativeElement;
1452
+ const left = target.getBoundingClientRect().left;
1453
+ let originWidth;
1454
+ let movedWidth;
1455
+ let minWidth;
1456
+ if (column) {
1457
+ originWidth = parseInt(column.columnWidth, 10);
1458
+ movedWidth = originWidth + (left - this.dragStartLeft);
1459
+ minWidth = minColumnWidth;
1460
+ }
1461
+ else {
1462
+ originWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1463
+ movedWidth = originWidth + (left - this.dragStartLeft);
1464
+ minWidth = minColumnWidth * this.columns.length;
1465
+ }
1466
+ this.dragFixed({
1467
+ target,
1468
+ originWidth,
1469
+ movedWidth,
1470
+ minWidth
1471
+ });
1472
+ this.showAuxiliaryLine(event);
1473
+ }
1474
+ onResizeEnded(event, column) {
1475
+ const beforeWidth = parseInt(column.columnWidth, 10);
1476
+ const target = event.source.element.nativeElement;
1477
+ const left = target.getBoundingClientRect().left;
1478
+ const width = parseInt(column.columnWidth, 10) + (left - this.dragStartLeft);
1479
+ const columnWidth = Math.max(width || 0, minColumnWidth);
1480
+ column.columnWidth = coerceCssPixelValue(columnWidth);
1481
+ if (this.gantt.table) {
1482
+ this.gantt.table.columnChanges.emit({ columns: this.columns });
1483
+ }
1484
+ this.tableWidth = this.tableWidth - beforeWidth + columnWidth;
1485
+ this.hideAuxiliaryLine();
1486
+ event.source.reset();
1487
+ }
1488
+ onOverallResizeEnded(event) {
1489
+ const target = event.source.element.nativeElement;
1490
+ const left = target.getBoundingClientRect().left;
1491
+ const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1492
+ const dragWidth = left - this.dragStartLeft;
1493
+ let tempWidth = 0;
1494
+ this.columns.forEach((column) => {
1495
+ const lastColumnWidth = parseInt(column.columnWidth, 10);
1496
+ const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10);
1497
+ const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth);
1498
+ column.columnWidth = coerceCssPixelValue(columnWidth);
1499
+ tempWidth += columnWidth;
1500
+ });
1501
+ this.tableWidth = tempWidth;
1502
+ if (this.gantt.table) {
1503
+ this.gantt.table.columnChanges.emit({ columns: this.columns });
1504
+ }
1505
+ this.hideAuxiliaryLine();
1506
+ event.source.reset();
1507
+ }
1508
+ showAuxiliaryLine(event) {
1509
+ const tableRect = this.elementRef.nativeElement.getBoundingClientRect();
1510
+ const targetRect = event.source.element.nativeElement.getBoundingClientRect();
1511
+ const distance = { x: targetRect.left - tableRect.left, y: targetRect.top - tableRect.top };
1512
+ this.resizeLineElementRef.nativeElement.style.left = `${distance.x}px`;
1513
+ this.resizeLineElementRef.nativeElement.style.display = 'block';
1514
+ }
1515
+ hideAuxiliaryLine() {
1516
+ this.resizeLineElementRef.nativeElement.style.display = 'none';
1517
+ }
1518
+ ngOnDestroy() {
1519
+ this.unsubscribe$.next();
1520
+ this.unsubscribe$.complete();
1521
+ }
1522
+ }
1523
+ 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 });
1524
+ 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"] }] });
1525
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableHeaderComponent, decorators: [{
1526
+ type: Component,
1527
+ 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" }]
1528
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
1529
+ type: Inject,
1530
+ args: [GANTT_ABSTRACT_TOKEN]
1531
+ }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { columns: [{
1532
+ type: Input
1533
+ }], resizeLineElementRef: [{
1534
+ type: ViewChild,
1535
+ args: ['resizeLine', { static: true }]
1536
+ }], className: [{
1537
+ type: HostBinding,
1538
+ args: ['class']
1539
+ }] } });
1540
+
1285
1541
  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>`;
1286
1542
  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>`;
1287
1543
  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>`;
@@ -1360,13 +1616,15 @@ xmlns:xlink="http://www.w3.org/1999/xlink"
1360
1616
  </g>
1361
1617
  </g>
1362
1618
  </svg>`;
1619
+ 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>`;
1363
1620
  const icons = {
1364
1621
  'angle-right': angleRight,
1365
1622
  'angle-down': angleDown,
1366
1623
  'plus-square': plusSquare,
1367
1624
  'minus-square': minusSquare,
1368
1625
  loading: loadingIcon,
1369
- empty: emptyIcon
1626
+ empty: emptyIcon,
1627
+ drag: dragIcon
1370
1628
  };
1371
1629
 
1372
1630
  class GanttIconComponent {
@@ -1442,46 +1700,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1442
1700
  }]
1443
1701
  }] });
1444
1702
 
1445
- const defaultColumnWidth = 100;
1446
- const minColumnWidth = 80;
1447
- class GanttTableComponent {
1448
- set columns(columns) {
1449
- this.hasShowExpandIcon = false;
1450
- columns.forEach((column) => {
1451
- if (!column.columnWidth) {
1452
- column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1453
- }
1454
- if (column.showExpandIcon) {
1455
- this.hasShowExpandIcon = true;
1456
- }
1457
- });
1458
- this.columnList = columns;
1703
+ class GanttTableBodyComponent {
1704
+ set renderData(data) {
1705
+ const firstData = data[0];
1706
+ if (firstData && firstData.hasOwnProperty('items')) {
1707
+ this.hasGroup = true;
1708
+ }
1709
+ this.ganttTableEmptyClass = data?.length ? false : true;
1710
+ this._renderData = data;
1711
+ }
1712
+ get renderData() {
1713
+ return this._renderData;
1459
1714
  }
1460
- constructor(gantt, ganttUpper, elementRef) {
1715
+ constructor(gantt, ganttUpper, cdr, document) {
1461
1716
  this.gantt = gantt;
1462
1717
  this.ganttUpper = ganttUpper;
1463
- this.elementRef = elementRef;
1464
- this.hasShowExpandIcon = false;
1718
+ this.cdr = cdr;
1719
+ this.document = document;
1720
+ this.draggable = false;
1721
+ this.dragDropped = new EventEmitter();
1465
1722
  this.itemClick = new EventEmitter();
1466
1723
  this.ganttTableClass = true;
1467
1724
  this.ganttTableEmptyClass = false;
1725
+ this.ganttTableDragging = false;
1726
+ this.hasExpandIcon = false;
1727
+ // 缓存 Element 和 DragRef 的关系,方便在 Item 拖动时查找
1728
+ this.itemDragRefMap = new Map();
1729
+ this.itemDragMoved = new Subject();
1730
+ this.destroy$ = new Subject();
1468
1731
  }
1469
- ngOnChanges(changes) {
1470
- if (!changes.groups.currentValue?.length && !changes.items.currentValue?.length) {
1471
- this.ganttTableEmptyClass = true;
1472
- }
1473
- else {
1474
- this.ganttTableEmptyClass = false;
1475
- }
1732
+ ngOnInit() {
1733
+ this.columns.changes.pipe(startWith(this.columns), takeUntil$1(this.destroy$)).subscribe(() => {
1734
+ this.hasExpandIcon = false;
1735
+ this.columns.forEach((column) => {
1736
+ if (!column.columnWidth) {
1737
+ column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1738
+ }
1739
+ if (column.showExpandIcon) {
1740
+ this.hasExpandIcon = true;
1741
+ }
1742
+ });
1743
+ this.cdr.detectChanges();
1744
+ });
1476
1745
  }
1477
- dragFixed(config) {
1478
- if (config.movedWidth < config.minWidth) {
1479
- setStyleWithVendorPrefix({
1480
- element: config.target,
1481
- style: 'transform',
1482
- value: `translate3d(${config.minWidth - config.originWidth}px, 0, 0)`
1746
+ ngAfterViewInit() {
1747
+ this.cdkDrags.changes
1748
+ .pipe(startWith(this.cdkDrags), takeUntil$1(this.destroy$))
1749
+ .subscribe((drags) => {
1750
+ this.itemDragRefMap.clear();
1751
+ drags.forEach((drag) => {
1752
+ if (drag.data) {
1753
+ // cdkDrag 变化时,缓存 Element 与 DragRef 的关系,方便 Drag Move 时查找
1754
+ this.itemDragRefMap.set(drag.element.nativeElement, drag);
1755
+ }
1483
1756
  });
1484
- }
1757
+ });
1758
+ this.itemDragMoved
1759
+ .pipe(debounceTime(30),
1760
+ // debounce 可能会导致拖动结束后仍然执行 moved ,所以通过判断 dragging 状态来过滤无效 moved
1761
+ filter((event) => event.source._dragRef.isDragging()), takeUntil$1(this.destroy$))
1762
+ .subscribe((event) => {
1763
+ this.onItemDragMoved(event);
1764
+ });
1485
1765
  }
1486
1766
  expandGroup(group) {
1487
1767
  this.gantt.expandGroup(group);
@@ -1490,89 +1770,184 @@ class GanttTableComponent {
1490
1770
  event.stopPropagation();
1491
1771
  this.gantt.expandChildren(item);
1492
1772
  }
1493
- dragStarted(event) {
1494
- const target = event.source.element.nativeElement;
1495
- this.dragStartLeft = target.getBoundingClientRect().left;
1773
+ onItemDragStarted(event) {
1774
+ this.ganttTableDragging = true;
1775
+ // 拖动开始时隐藏所有的子项
1776
+ const children = this.getChildrenElementsByElement(event.source.getPlaceholderElement());
1777
+ children.forEach((element) => {
1778
+ element.classList.add('drag-item-hide');
1779
+ });
1496
1780
  }
1497
- dragMoved(event, column) {
1498
- const target = event.source.element.nativeElement;
1499
- const left = target.getBoundingClientRect().left;
1500
- let originWidth;
1501
- let movedWidth;
1502
- let minWidth;
1503
- if (column) {
1504
- originWidth = parseInt(column.columnWidth, 10);
1505
- movedWidth = originWidth + (left - this.dragStartLeft);
1506
- minWidth = minColumnWidth;
1781
+ emitItemDragMoved(event) {
1782
+ this.itemDragMoved.next(event);
1783
+ }
1784
+ onItemDragMoved(event) {
1785
+ // 通过鼠标位置查找对应的目标 Item 元素
1786
+ let currentPointElement = this.document.elementFromPoint(event.pointerPosition.x, event.pointerPosition.y);
1787
+ if (!currentPointElement) {
1788
+ this.cleanupDragArtifacts();
1789
+ return;
1507
1790
  }
1508
- else {
1509
- originWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1510
- movedWidth = originWidth + (left - this.dragStartLeft);
1511
- minWidth = minColumnWidth * this.columnList.length;
1791
+ let targetElement = currentPointElement.classList.contains('gantt-table-item')
1792
+ ? currentPointElement
1793
+ : currentPointElement.closest('.gantt-table-item');
1794
+ if (!targetElement) {
1795
+ this.cleanupDragArtifacts();
1796
+ return;
1512
1797
  }
1513
- this.dragFixed({
1514
- target,
1515
- originWidth,
1516
- movedWidth,
1517
- minWidth
1798
+ // 缓存放置目标Id 并计算鼠标相对应的位置
1799
+ this.itemDropTarget = {
1800
+ id: this.itemDragRefMap.get(targetElement)?.data.id,
1801
+ position: this.getTargetPosition(targetElement, event)
1802
+ };
1803
+ // 执行外部传入的 dropEnterPredicate 判断是否允许拖入目标项
1804
+ if (this.dropEnterPredicate) {
1805
+ const targetDragRef = this.itemDragRefMap.get(targetElement);
1806
+ if (this.dropEnterPredicate({
1807
+ source: event.source.data.origin,
1808
+ target: targetDragRef.data.origin,
1809
+ dropPosition: this.itemDropTarget.position
1810
+ })) {
1811
+ this.showDropPositionPlaceholder(targetElement);
1812
+ }
1813
+ else {
1814
+ this.itemDropTarget = null;
1815
+ }
1816
+ }
1817
+ else {
1818
+ this.showDropPositionPlaceholder(targetElement);
1819
+ }
1820
+ }
1821
+ onItemDragEnded(event) {
1822
+ this.ganttTableDragging = false;
1823
+ }
1824
+ onListDropped(event) {
1825
+ if (!this.itemDropTarget) {
1826
+ return;
1827
+ }
1828
+ const targetDragRef = this.cdkDrags.find((item) => item.data?.id === this.itemDropTarget.id);
1829
+ const sourceItem = event.item.data;
1830
+ const targetItem = targetDragRef?.data;
1831
+ this.removeItem(sourceItem);
1832
+ switch (this.itemDropTarget.position) {
1833
+ case 'before':
1834
+ case 'after':
1835
+ this.insertItem(targetItem, sourceItem, this.itemDropTarget.position);
1836
+ sourceItem.updateLevel(targetItem.level);
1837
+ break;
1838
+ case 'inside':
1839
+ this.insertChildrenItem(targetItem, sourceItem);
1840
+ sourceItem.updateLevel(targetItem.level + 1);
1841
+ break;
1842
+ }
1843
+ this.dragDropped.emit({
1844
+ source: sourceItem.origin,
1845
+ sourceParent: this.getParentByItem(sourceItem)?.origin,
1846
+ target: targetItem.origin,
1847
+ targetParent: this.getParentByItem(targetItem)?.origin,
1848
+ dropPosition: this.itemDropTarget.position
1518
1849
  });
1519
- this.showAuxiliaryLine(event);
1850
+ this.cleanupDragArtifacts(true);
1520
1851
  }
1521
- columnDragEnded(event, column) {
1522
- const target = event.source.element.nativeElement;
1523
- const left = target.getBoundingClientRect().left;
1524
- const width = parseInt(column.columnWidth, 10) + (left - this.dragStartLeft);
1525
- const columnWidth = Math.max(width || 0, minColumnWidth);
1526
- column.columnWidth = coerceCssPixelValue(columnWidth);
1527
- if (this.gantt.table) {
1528
- this.gantt.table.columnChanges.emit({ columns: this.columnList });
1852
+ trackBy(index, item) {
1853
+ return item.id || index;
1854
+ }
1855
+ ngOnDestroy() {
1856
+ this.destroy$.next();
1857
+ this.destroy$.complete();
1858
+ }
1859
+ removeItem(item) {
1860
+ this.renderData.splice(this.renderData.indexOf(item), 1);
1861
+ this.flatData.splice(this.flatData.indexOf(item), 1);
1862
+ }
1863
+ insertItem(target, inserted, position) {
1864
+ if (position === 'before') {
1865
+ this.renderData.splice(this.renderData.indexOf(target), 0, inserted);
1866
+ this.flatData.splice(this.flatData.indexOf(target), 0, inserted);
1867
+ }
1868
+ else {
1869
+ const dragRef = this.cdkDrags.find((drag) => drag.data === target);
1870
+ // 如果目标项是展开的,插入的 index 位置需要考虑子项的数量
1871
+ let childrenCount = 0;
1872
+ if (target.expanded) {
1873
+ childrenCount = this.getChildrenElementsByElement(dragRef.element.nativeElement)?.length || 0;
1874
+ }
1875
+ this.renderData.splice(this.renderData.indexOf(target) + 1 + childrenCount, 0, inserted);
1876
+ this.flatData.splice(this.flatData.indexOf(target) + 1 + childrenCount, 0, inserted);
1529
1877
  }
1530
- this.hideAuxiliaryLine();
1531
- event.source.reset();
1532
1878
  }
1533
- tableDragEnded(event) {
1534
- const target = event.source.element.nativeElement;
1535
- const left = target.getBoundingClientRect().left;
1536
- const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1537
- const dragWidth = left - this.dragStartLeft;
1538
- this.columnList.forEach((column) => {
1539
- const lastColumnWidth = parseInt(column.columnWidth, 10);
1540
- const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10);
1541
- const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth);
1542
- column.columnWidth = coerceCssPixelValue(columnWidth);
1879
+ insertChildrenItem(target, inserted) {
1880
+ if (target.expanded) {
1881
+ this.renderData.splice(this.renderData.indexOf(target) + target.children.length + 1, 0, inserted);
1882
+ this.flatData.splice(this.flatData.indexOf(target) + target.children.length + 1, 0, inserted);
1883
+ }
1884
+ target.children.push(inserted);
1885
+ }
1886
+ getParentByItem(item) {
1887
+ return (this.flatData || []).find((n) => {
1888
+ return n.children?.includes(item);
1543
1889
  });
1544
- if (this.gantt.table) {
1545
- this.gantt.table.columnChanges.emit({ columns: this.columnList });
1890
+ }
1891
+ getChildrenElementsByElement(element) {
1892
+ // 通过循环持续查找 next element,如果 element 的 level 小于当前 item 的 level,则为它的 children
1893
+ const children = [];
1894
+ const dragRef = this.itemDragRefMap.get(element);
1895
+ let nextElement = element.nextElementSibling;
1896
+ let nextDragRef = this.itemDragRefMap.get(nextElement);
1897
+ while (nextDragRef && nextDragRef.data.level > dragRef.data.level) {
1898
+ children.push(nextElement);
1899
+ nextElement = nextElement.nextElementSibling;
1900
+ nextDragRef = this.itemDragRefMap.get(nextElement);
1546
1901
  }
1547
- this.hideAuxiliaryLine();
1548
- event.source.reset();
1902
+ return children;
1549
1903
  }
1550
- showAuxiliaryLine(event) {
1551
- const tableRect = this.elementRef.nativeElement.getBoundingClientRect();
1552
- this.draglineElementRef.nativeElement.style.left = `${event.event.clientX - tableRect.left}px`;
1553
- this.draglineElementRef.nativeElement.style.display = 'block';
1904
+ getTargetPosition(target, event) {
1905
+ const targetRect = target.getBoundingClientRect();
1906
+ const beforeOrAfterGap = targetRect.height * 0.3;
1907
+ // Item 高度分为上中下三段,其中上下的 Gap 为 height 的 30%,通过判断鼠标位置在哪一段 gap 来计算对应的位置
1908
+ if (event.pointerPosition.y - targetRect.top < beforeOrAfterGap) {
1909
+ return 'before';
1910
+ }
1911
+ else if (event.pointerPosition.y >= targetRect.bottom - beforeOrAfterGap) {
1912
+ return 'after';
1913
+ }
1914
+ else {
1915
+ return 'inside';
1916
+ }
1554
1917
  }
1555
- hideAuxiliaryLine() {
1556
- this.draglineElementRef.nativeElement.style.display = 'none';
1918
+ showDropPositionPlaceholder(targetElement) {
1919
+ this.cleanupDragArtifacts();
1920
+ if (this.itemDropTarget && targetElement) {
1921
+ targetElement.classList.add(`drop-position-${this.itemDropTarget.position}`);
1922
+ }
1557
1923
  }
1558
- trackBy(index, item) {
1559
- return item.id || index;
1924
+ cleanupDragArtifacts(dropped = false) {
1925
+ if (dropped) {
1926
+ this.itemDropTarget = null;
1927
+ }
1928
+ this.document.querySelectorAll('.drop-position-before').forEach((element) => element.classList.remove('drop-position-before'));
1929
+ this.document.querySelectorAll('.drop-position-after').forEach((element) => element.classList.remove('drop-position-after'));
1930
+ this.document.querySelectorAll('.drop-position-inside').forEach((element) => element.classList.remove('drop-position-inside'));
1931
+ this.document.querySelectorAll('.drag-item-hide').forEach((element) => element.classList.remove('drop-item-hide'));
1560
1932
  }
1561
1933
  }
1562
- 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 });
1563
- 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=\"column?.showExpandIcon || (!hasShowExpandIcon && 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" }] });
1564
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableComponent, decorators: [{
1934
+ 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 });
1935
+ 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" }] });
1936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, decorators: [{
1565
1937
  type: Component,
1566
- 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=\"column?.showExpandIcon || (!hasShowExpandIcon && 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" }]
1938
+ 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" }]
1567
1939
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1568
1940
  type: Inject,
1569
1941
  args: [GANTT_ABSTRACT_TOKEN]
1570
1942
  }] }, { type: GanttUpper, decorators: [{
1571
1943
  type: Inject,
1572
1944
  args: [GANTT_UPPER_TOKEN]
1573
- }] }, { type: i0.ElementRef }]; }, propDecorators: { groups: [{
1945
+ }] }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
1946
+ type: Inject,
1947
+ args: [DOCUMENT]
1948
+ }] }]; }, propDecorators: { renderData: [{
1574
1949
  type: Input
1575
- }], items: [{
1950
+ }], flatData: [{
1576
1951
  type: Input
1577
1952
  }], columns: [{
1578
1953
  type: Input
@@ -1584,17 +1959,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1584
1959
  type: Input
1585
1960
  }], rowAfterTemplate: [{
1586
1961
  type: Input
1962
+ }], draggable: [{
1963
+ type: HostBinding,
1964
+ args: ['class.gantt-table-draggable']
1965
+ }, {
1966
+ type: Input
1967
+ }], dropEnterPredicate: [{
1968
+ type: Input
1969
+ }], dragDropped: [{
1970
+ type: Output
1587
1971
  }], itemClick: [{
1588
1972
  type: Output
1589
- }], draglineElementRef: [{
1590
- type: ViewChild,
1591
- args: ['dragLine', { static: true }]
1592
1973
  }], ganttTableClass: [{
1593
1974
  type: HostBinding,
1594
- args: ['class.gantt-table']
1975
+ args: ['class.gantt-table-body']
1595
1976
  }], ganttTableEmptyClass: [{
1596
1977
  type: HostBinding,
1597
1978
  args: ['class.gantt-table-empty']
1979
+ }], ganttTableDragging: [{
1980
+ type: HostBinding,
1981
+ args: ['class.gantt-table-dragging']
1982
+ }], cdkDrags: [{
1983
+ type: ViewChildren,
1984
+ args: [(CdkDrag)]
1598
1985
  }] } });
1599
1986
 
1600
1987
  class GanttLinkLine {
@@ -1850,13 +2237,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1850
2237
  }] }]; } });
1851
2238
 
1852
2239
  class GanttLinksComponent {
1853
- constructor(ganttUpper, cdr, elementRef, ganttDragContainer) {
2240
+ constructor(ganttUpper, cdr, elementRef, ganttDragContainer, ngZone) {
1854
2241
  this.ganttUpper = ganttUpper;
1855
2242
  this.cdr = cdr;
1856
2243
  this.elementRef = elementRef;
1857
2244
  this.ganttDragContainer = ganttDragContainer;
1858
- this.groups = [];
1859
- this.items = [];
2245
+ this.ngZone = ngZone;
2246
+ // @Input() groups: GanttGroupInternal[] = [];
2247
+ // @Input() items: GanttItemInternal[] = [];
2248
+ this.flatData = [];
1860
2249
  this.lineClick = new EventEmitter();
1861
2250
  this.links = [];
1862
2251
  this.ganttLinkTypes = GanttLinkType;
@@ -1869,13 +2258,14 @@ class GanttLinksComponent {
1869
2258
  ngOnInit() {
1870
2259
  this.linkLine = createLineGenerator(this.ganttUpper.linkOptions.lineType, this.ganttUpper);
1871
2260
  this.showArrow = this.ganttUpper.linkOptions.showArrow;
1872
- this.buildLinks();
2261
+ // this.buildLinks();
1873
2262
  this.firstChange = false;
2263
+ this.buildLinks();
1874
2264
  this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
1875
2265
  this.elementRef.nativeElement.style.visibility = 'hidden';
1876
2266
  });
1877
- merge(this.ganttUpper.viewChange, this.ganttUpper.expandChange, this.ganttUpper.view.start$, this.ganttUpper.dragEnded, this.ganttUpper.linkDragEnded)
1878
- .pipe(skip(1), debounceTime(0), takeUntil(this.unsubscribe$))
2267
+ 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(() => this.ganttUpper.table?.dragDropped || EMPTY)))
2268
+ .pipe(skip(1), debounceTime$1(0), takeUntil(this.unsubscribe$))
1879
2269
  .subscribe(() => {
1880
2270
  this.elementRef.nativeElement.style.visibility = 'visible';
1881
2271
  this.buildLinks();
@@ -1891,48 +2281,66 @@ class GanttLinksComponent {
1891
2281
  const lineHeight = this.ganttUpper.styles.lineHeight;
1892
2282
  const barHeight = this.ganttUpper.styles.barHeight;
1893
2283
  this.linkItems = [];
1894
- if (this.groups.length > 0) {
1895
- let itemNum = 0;
1896
- let groupNum = 0;
1897
- this.groups.forEach((group) => {
1898
- groupNum++;
1899
- if (group.expanded) {
1900
- const items = recursiveItems(group.items);
1901
- items.forEach((item, itemIndex) => {
1902
- const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
1903
- this.linkItems.push({
1904
- ...item,
1905
- before: {
1906
- x: item.refs.x,
1907
- y
1908
- },
1909
- after: {
1910
- x: item.refs.x + item.refs.width,
1911
- y
1912
- }
1913
- });
2284
+ // if (this.groups.length > 0) {
2285
+ // let itemNum = 0;
2286
+ // let groupNum = 0;
2287
+ // this.groups.forEach((group) => {
2288
+ // groupNum++;
2289
+ // if (group.expanded) {
2290
+ // const items = recursiveItems(group.items);
2291
+ // items.forEach((item, itemIndex) => {
2292
+ // const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
2293
+ // this.linkItems.push({
2294
+ // ...item,
2295
+ // before: {
2296
+ // x: item.refs.x,
2297
+ // y
2298
+ // },
2299
+ // after: {
2300
+ // x: item.refs.x + item.refs.width,
2301
+ // y
2302
+ // }
2303
+ // });
2304
+ // });
2305
+ // itemNum += items.length;
2306
+ // }
2307
+ // });
2308
+ // } else {
2309
+ // const items = recursiveItems(this.items);
2310
+ // items.forEach((item, itemIndex) => {
2311
+ // const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
2312
+ // this.linkItems.push({
2313
+ // ...item,
2314
+ // before: {
2315
+ // x: item.refs.x,
2316
+ // y
2317
+ // },
2318
+ // after: {
2319
+ // x: item.refs.x + item.refs.width,
2320
+ // y
2321
+ // }
2322
+ // });
2323
+ // });
2324
+ // }
2325
+ this.flatData.forEach((item, itemIndex) => {
2326
+ if (!item.hasOwnProperty('items')) {
2327
+ const ganttItem = item;
2328
+ if (ganttItem.refs) {
2329
+ const y = itemIndex * lineHeight + ganttItem.refs.y + barHeight / 2;
2330
+ this.linkItems.push({
2331
+ ...ganttItem,
2332
+ before: {
2333
+ x: ganttItem.refs.x,
2334
+ y
2335
+ },
2336
+ after: {
2337
+ x: ganttItem.refs.x + ganttItem.refs.width,
2338
+ y
2339
+ }
1914
2340
  });
1915
- itemNum += items.length;
1916
2341
  }
1917
- });
1918
- }
1919
- else {
1920
- const items = recursiveItems(this.items);
1921
- items.forEach((item, itemIndex) => {
1922
- const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
1923
- this.linkItems.push({
1924
- ...item,
1925
- before: {
1926
- x: item.refs.x,
1927
- y
1928
- },
1929
- after: {
1930
- x: item.refs.x + item.refs.width,
1931
- y
1932
- }
1933
- });
1934
- });
1935
- }
2342
+ }
2343
+ });
1936
2344
  }
1937
2345
  buildLinks() {
1938
2346
  this.computeItemPosition();
@@ -1997,17 +2405,15 @@ class GanttLinksComponent {
1997
2405
  this.unsubscribe$.complete();
1998
2406
  }
1999
2407
  }
2000
- 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 });
2001
- 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"] }] });
2408
+ 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 });
2409
+ 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"] }] });
2002
2410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, decorators: [{
2003
2411
  type: Component,
2004
2412
  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
2413
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2006
2414
  type: Inject,
2007
2415
  args: [GANTT_UPPER_TOKEN]
2008
- }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }]; }, propDecorators: { groups: [{
2009
- type: Input
2010
- }], items: [{
2416
+ }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }, { type: i0.NgZone }]; }, propDecorators: { flatData: [{
2011
2417
  type: Input
2012
2418
  }], lineClick: [{
2013
2419
  type: Output
@@ -2065,18 +2471,10 @@ class GanttDomService {
2065
2471
  .subscribe((event) => {
2066
2472
  this.syncScroll(event);
2067
2473
  }));
2068
- // fromEvent(this.mainContainer, 'scroll')
2069
- // .pipe(startWith(), takeUntil(this.unsubscribe$))
2070
- // .subscribe((event) => {
2071
- // // if (this.mainContainer.scrollLeft > 0) {
2072
- // // this.side.classList.add('gantt-side-has-shadow');
2073
- // // } else {
2074
- // // this.side.classList.remove('gantt-side-has-shadow');
2075
- // // }
2076
- // });
2077
2474
  }
2078
2475
  syncScroll(event) {
2079
2476
  const target = event.currentTarget;
2477
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2080
2478
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2081
2479
  this.sideContainer.scrollTop = target.scrollTop;
2082
2480
  this.mainContainer.scrollTop = target.scrollTop;
@@ -2102,8 +2500,11 @@ class GanttDomService {
2102
2500
  this.container = this.root.getElementsByClassName('gantt-container')[0];
2103
2501
  this.sideContainer = this.root.getElementsByClassName('gantt-side-container')[0];
2104
2502
  this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2105
- this.mainItems = this.root.getElementsByClassName('gantt-main-items')[0];
2106
- this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-overlay')[0];
2503
+ const mainItems = this.mainContainer.getElementsByClassName('gantt-main-items')[0];
2504
+ const mainGroups = this.mainContainer.getElementsByClassName('gantt-main-groups')[0];
2505
+ this.mainItems = mainItems || mainGroups;
2506
+ this.calendarHeader = this.root.getElementsByClassName('gantt-calendar-header')[0];
2507
+ this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-grid')[0];
2107
2508
  this.monitorScrollChange();
2108
2509
  this.disableBrowserWheelEvent();
2109
2510
  }
@@ -2140,6 +2541,7 @@ class GanttDomService {
2140
2541
  if (isNumber(left)) {
2141
2542
  const scrollLeft = left - this.mainContainer.clientWidth / 2;
2142
2543
  this.mainContainer.scrollLeft = scrollLeft > scrollThreshold ? scrollLeft : 0;
2544
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2143
2545
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2144
2546
  }
2145
2547
  }
@@ -2168,100 +2570,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2168
2570
  }, 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" }]
2169
2571
  }] });
2170
2572
 
2171
- class GanttPrintService {
2172
- constructor() { }
2173
- setInlineStyles(targetElem) {
2174
- const svgElements = Array.from(targetElem.getElementsByTagName('svg'));
2175
- for (const svgElement of svgElements) {
2176
- this.recursElementChildren(svgElement);
2177
- }
2573
+ class GanttCalendarHeaderComponent {
2574
+ get view() {
2575
+ return this.ganttUpper.view;
2178
2576
  }
2179
- recursElementChildren(node) {
2180
- const transformProperties = [
2181
- 'fill',
2182
- 'color',
2183
- 'font-size',
2184
- 'stroke',
2185
- 'font',
2186
- 'text-anchor',
2187
- 'stroke-dasharray',
2188
- 'shape-rendering',
2189
- 'stroke-width'
2190
- ];
2191
- if (!node.style) {
2192
- return;
2193
- }
2194
- const styles = getComputedStyle(node);
2195
- for (const transformProperty of transformProperties) {
2196
- node.style[transformProperty] = styles[transformProperty];
2197
- }
2198
- for (const child of Array.from(node.childNodes)) {
2199
- this.recursElementChildren(child);
2200
- }
2577
+ constructor(ganttUpper, ngZone, elementRef) {
2578
+ this.ganttUpper = ganttUpper;
2579
+ this.ngZone = ngZone;
2580
+ this.elementRef = elementRef;
2581
+ this.unsubscribe$ = new Subject();
2582
+ this.headerHeight = headerHeight;
2583
+ this.viewTypes = GanttViewType;
2584
+ this.className = `gantt-calendar gantt-calendar-header`;
2201
2585
  }
2202
- register(root) {
2203
- this.root = root.nativeElement;
2204
- this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2586
+ ngOnInit() {
2587
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2588
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2589
+ .pipe(takeUntil(this.unsubscribe$))
2590
+ .subscribe(() => {
2591
+ if (this.ganttUpper.viewType === GanttViewType.day)
2592
+ this.setTodayPoint();
2593
+ });
2594
+ });
2205
2595
  }
2206
- async print(name = 'download', ignoreElementClass) {
2207
- const root = this.root;
2208
- const mainContainer = this.mainContainer;
2209
- // set print width
2210
- const printWidth = root.offsetWidth;
2211
- // set print height
2212
- const printHeight = root.offsetHeight - mainContainer.offsetHeight + mainContainer.scrollHeight;
2213
- const html2canvas = (await import(/* webpackChunkName: 'html2canvas' */ 'html2canvas')).default;
2214
- html2canvas(root, {
2215
- logging: false,
2216
- allowTaint: true,
2217
- useCORS: true,
2218
- width: printWidth,
2219
- height: printHeight,
2220
- ignoreElements: (element) => {
2221
- if (ignoreElementClass && element.classList.contains(ignoreElementClass)) {
2222
- return true;
2223
- }
2224
- if (element.classList.contains('gantt-calendar-today-overlay')) {
2225
- return true;
2226
- }
2227
- },
2228
- onclone: (cloneDocument) => {
2229
- const ganttClass = root.className;
2230
- const cloneGanttDom = cloneDocument.querySelector(`.${ganttClass.replace(/\s+/g, '.')}`);
2231
- const cloneGanttContainerDom = cloneDocument.querySelector('.gantt-container');
2232
- const cloneCalendarOverlay = cloneDocument.querySelector('.gantt-calendar-overlay-main');
2233
- const cloneLinksOverlay = cloneDocument.querySelector('.gantt-links-overlay-main');
2234
- // change targetDom width
2235
- cloneGanttDom.style.width = `${printWidth}px`;
2236
- cloneGanttDom.style.height = `${printHeight}px`;
2237
- cloneGanttDom.style.overflow = `unset`;
2238
- cloneGanttContainerDom.style.backgroundColor = '#fff';
2239
- cloneCalendarOverlay.setAttribute('height', `${printHeight}`);
2240
- cloneCalendarOverlay.setAttribute('style', `background: transparent`);
2241
- if (cloneLinksOverlay) {
2242
- cloneLinksOverlay.setAttribute('height', `${printHeight}`);
2243
- cloneLinksOverlay.setAttribute('style', `height: ${printHeight}px`);
2244
- }
2245
- // setInlineStyles for svg
2246
- this.setInlineStyles(cloneGanttDom);
2596
+ setTodayPoint() {
2597
+ const x = this.view.getTodayXPoint();
2598
+ const today = new GanttDate().getDate();
2599
+ const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2600
+ const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2601
+ if (isNumber(x)) {
2602
+ if (rect) {
2603
+ rect.style.left = `${x - todayWidth / 2}px`;
2604
+ rect.style.top = `${headerHeight - todayHeight}px`;
2605
+ rect.innerHTML = today.toString();
2247
2606
  }
2248
- }).then((canvas) => {
2249
- const link = document.createElement('a');
2250
- const dataUrl = canvas.toDataURL('image/png');
2251
- link.download = `${name}.png`;
2252
- link.href = dataUrl;
2253
- link.click();
2254
- });
2607
+ }
2608
+ else {
2609
+ todayEle.style.display = 'none';
2610
+ }
2611
+ }
2612
+ trackBy(point, index) {
2613
+ return point.text || index;
2255
2614
  }
2256
2615
  }
2257
- GanttPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2258
- GanttPrintServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService });
2259
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, decorators: [{
2260
- type: Injectable
2261
- }], ctorParameters: function () { return []; } });
2616
+ 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 });
2617
+ 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"] }] });
2618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarHeaderComponent, decorators: [{
2619
+ type: Component,
2620
+ 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" }]
2621
+ }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2622
+ type: Inject,
2623
+ args: [GANTT_UPPER_TOKEN]
2624
+ }] }, { type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { className: [{
2625
+ type: HostBinding,
2626
+ args: ['class']
2627
+ }] } });
2262
2628
 
2263
2629
  const mainHeight = 5000;
2264
- class GanttCalendarComponent {
2630
+ class GanttCalendarGridComponent {
2265
2631
  get view() {
2266
2632
  return this.ganttUpper.view;
2267
2633
  }
@@ -2269,30 +2635,21 @@ class GanttCalendarComponent {
2269
2635
  this.ganttUpper = ganttUpper;
2270
2636
  this.ngZone = ngZone;
2271
2637
  this.elementRef = elementRef;
2638
+ this.unsubscribe$ = new Subject();
2272
2639
  this.headerHeight = headerHeight;
2273
2640
  this.mainHeight = mainHeight;
2274
- this.todayHeight = todayHeight;
2275
- this.todayWidth = todayWidth;
2276
2641
  this.todayBorderRadius = todayBorderRadius;
2277
2642
  this.viewTypes = GanttViewType;
2278
- this.className = true;
2279
- this.unsubscribe$ = new Subject();
2643
+ this.className = `gantt-calendar gantt-calendar-grid`;
2280
2644
  }
2281
2645
  setTodayPoint() {
2282
2646
  const x = this.view.getTodayXPoint();
2283
- const today = new GanttDate().getDate();
2284
2647
  const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2285
- const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2286
2648
  const line = this.elementRef.nativeElement.getElementsByClassName('today-line')[0];
2287
2649
  if (isNumber(x)) {
2288
- if (rect) {
2289
- rect.style.left = `${x - todayWidth / 2}px`;
2290
- rect.style.top = `${headerHeight - todayHeight}px`;
2291
- rect.innerHTML = today.toString();
2292
- }
2293
2650
  if (line) {
2294
2651
  line.style.left = `${x}px`;
2295
- line.style.top = `${headerHeight}px`;
2652
+ line.style.top = `0px`;
2296
2653
  line.style.bottom = `${-mainHeight}px`;
2297
2654
  }
2298
2655
  }
@@ -2301,22 +2658,15 @@ class GanttCalendarComponent {
2301
2658
  }
2302
2659
  }
2303
2660
  ngOnInit() {
2304
- // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2305
- // the `onStable` will never emit any value.
2306
- const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
2307
- // Normally this isn't in the zone, but it can cause performance regressions for apps
2308
- // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
2309
- this.ngZone.runOutsideAngular(() => {
2310
- onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
2311
- merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2312
- .pipe(takeUntil(this.unsubscribe$))
2313
- .subscribe(() => {
2314
- this.setTodayPoint();
2315
- });
2661
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2662
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2663
+ .pipe(takeUntil(this.unsubscribe$))
2664
+ .subscribe(() => {
2665
+ this.setTodayPoint();
2316
2666
  });
2317
2667
  });
2318
2668
  }
2319
- trackBy(index, point) {
2669
+ trackBy(point, index) {
2320
2670
  return point.text || index;
2321
2671
  }
2322
2672
  ngOnDestroy() {
@@ -2324,17 +2674,17 @@ class GanttCalendarComponent {
2324
2674
  this.unsubscribe$.complete();
2325
2675
  }
2326
2676
  }
2327
- 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 });
2328
- 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"] }] });
2329
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarComponent, decorators: [{
2677
+ 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 });
2678
+ 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"] }] });
2679
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarGridComponent, decorators: [{
2330
2680
  type: Component,
2331
- 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" }]
2681
+ 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" }]
2332
2682
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2333
2683
  type: Inject,
2334
2684
  args: [GANTT_UPPER_TOKEN]
2335
2685
  }] }, { type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { className: [{
2336
2686
  type: HostBinding,
2337
- args: ['class.gantt-calendar-overlay']
2687
+ args: ['class']
2338
2688
  }] } });
2339
2689
 
2340
2690
  class NgxGanttToolbarComponent {
@@ -2393,7 +2743,7 @@ class NgxGanttRootComponent {
2393
2743
  this.setupViewScroll();
2394
2744
  // 优化初始化时Scroll滚动体验问题,通过透明度解决,默认透明度为0,滚动结束后恢复
2395
2745
  this.elementRef.nativeElement.style.opacity = '1';
2396
- this.ganttUpper.viewChange.pipe(startWith(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2746
+ this.ganttUpper.viewChange.pipe(startWith$1(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2397
2747
  this.scrollToToday();
2398
2748
  });
2399
2749
  });
@@ -2462,12 +2812,12 @@ class NgxGanttRootComponent {
2462
2812
  }
2463
2813
  }
2464
2814
  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 });
2465
- 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"] }] });
2815
+ 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: i3.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"] }] });
2466
2816
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttRootComponent, decorators: [{
2467
2817
  type: Component,
2468
2818
  args: [{ selector: 'ngx-gantt-root', providers: [GanttDomService, GanttDragContainer], host: {
2469
2819
  class: 'gantt'
2470
- }, 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" }]
2820
+ }, 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" }]
2471
2821
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: GanttDomService }, { type: GanttDragContainer }, { type: GanttUpper, decorators: [{
2472
2822
  type: Inject,
2473
2823
  args: [GANTT_UPPER_TOKEN]
@@ -2487,6 +2837,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2487
2837
  }] } });
2488
2838
 
2489
2839
  const dragMinWidth = 10;
2840
+ const autoScrollStep = 10;
2490
2841
  const activeClass = 'gantt-bar-active';
2491
2842
  const dropActiveClass = 'gantt-bar-drop-active';
2492
2843
  const singleDropActiveClass = 'gantt-bar-single-drop-active';
@@ -2509,6 +2860,16 @@ class GanttBarDrag {
2509
2860
  this.root = root;
2510
2861
  this.dragRefs = [];
2511
2862
  this.destroy$ = new Subject();
2863
+ // scrolling state when drag
2864
+ this.dragScrolling = false;
2865
+ }
2866
+ createDragRef(element) {
2867
+ const dragRef = this.dragDrop.createDrag(element);
2868
+ // dragRef.withPreviewContainer(this.dom.mainContainer as HTMLElement);
2869
+ return dragRef;
2870
+ }
2871
+ createDragScrollEvent(dragRef) {
2872
+ return fromEvent(this.dom.mainContainer, 'scroll', passiveListenerOptions).pipe(takeUntil(dragRef.ended));
2512
2873
  }
2513
2874
  createMouseEvents() {
2514
2875
  const dropClass = this.ganttUpper.config.linkOptions?.dependencyTypes?.length === 1 &&
@@ -2544,33 +2905,38 @@ class GanttBarDrag {
2544
2905
  });
2545
2906
  }
2546
2907
  createBarDrag() {
2547
- const dragRef = this.dragDrop.createDrag(this.barElement);
2908
+ const dragRef = this.createDragRef(this.barElement);
2548
2909
  dragRef.lockAxis = 'x';
2549
2910
  dragRef.withBoundaryElement(this.dom.mainItems);
2550
2911
  dragRef.started.subscribe(() => {
2551
2912
  this.setDraggingStyles();
2913
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2914
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2915
+ if (this.dropListRef.isDragging()) {
2916
+ this.dragScrolling = true;
2917
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2918
+ this.barDragMove(dragRef, scrollDistance + this.barDragMoveDistance);
2919
+ }
2920
+ });
2552
2921
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2553
2922
  });
2554
2923
  dragRef.moved.subscribe((event) => {
2555
- const currentX = this.item.refs.x + event.distance.x;
2556
- const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
2557
- const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
2558
- const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
2559
- const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2560
- let start = currentDate;
2561
- let end = currentDate.addDays(diffDays);
2562
- if (currentX > currentStartX + dayWidth / 2) {
2563
- start = start.addDays(1);
2564
- end = end.addDays(1);
2924
+ this.barDragMove(dragRef, event.distance.x);
2925
+ if (!this.dragScrolling) {
2926
+ this.barDragMoveDistance = event.distance.x;
2565
2927
  }
2566
- this.openDragBackdrop(this.barElement, this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
2567
- this.item.updateDate(start, end);
2568
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2569
2928
  });
2570
2929
  dragRef.ended.subscribe((event) => {
2930
+ this.item.updateRefs({
2931
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
2932
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
2933
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
2934
+ });
2571
2935
  this.clearDraggingStyles();
2572
2936
  this.closeDragBackdrop();
2573
2937
  event.source.reset();
2938
+ this.dragScrolling = false;
2939
+ this.barDragMoveDistance = 0;
2574
2940
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2575
2941
  });
2576
2942
  this.barDragRef = dragRef;
@@ -2581,36 +2947,26 @@ class GanttBarDrag {
2581
2947
  const handles = this.barElement.querySelectorAll('.drag-handles .handle');
2582
2948
  handles.forEach((handle, index) => {
2583
2949
  const isBefore = index === 0;
2584
- const dragRef = this.dragDrop.createDrag(handle);
2950
+ const dragRef = this.createDragRef(handle);
2585
2951
  dragRef.lockAxis = 'x';
2586
2952
  dragRef.withBoundaryElement(this.dom.mainItems);
2587
2953
  dragRef.started.subscribe(() => {
2588
2954
  this.setDraggingStyles();
2955
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2956
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2957
+ if (this.dropListRef.isDragging()) {
2958
+ this.dragScrolling = true;
2959
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2960
+ this.barHandleDragMove(scrollDistance + this.barHandleDragMoveDistance, isBefore);
2961
+ }
2962
+ });
2589
2963
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2590
2964
  });
2591
2965
  dragRef.moved.subscribe((event) => {
2592
- if (isBefore) {
2593
- const x = this.item.refs.x + event.distance.x;
2594
- const width = this.item.refs.width + event.distance.x * -1;
2595
- const start = this.ganttUpper.view.getDateByXPoint(x);
2596
- if (width > dragMinWidth) {
2597
- this.barElement.style.width = width + 'px';
2598
- this.barElement.style.left = x + 'px';
2599
- this.openDragBackdrop(this.barElement, start, this.item.end);
2600
- this.item.updateDate(start, this.item.end);
2601
- }
2602
- }
2603
- else {
2604
- const width = this.item.refs.width + event.distance.x;
2605
- const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
2606
- if (width > dragMinWidth) {
2607
- this.barElement.style.width = width + 'px';
2608
- this.openDragBackdrop(this.barElement, this.item.start, end);
2609
- this.item.updateDate(this.item.start, end);
2610
- }
2966
+ this.barHandleDragMove(event.distance.x, isBefore);
2967
+ if (!this.dragScrolling) {
2968
+ this.barHandleDragMoveDistance = event.distance.x;
2611
2969
  }
2612
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2613
- event.source.reset();
2614
2970
  });
2615
2971
  dragRef.ended.subscribe((event) => {
2616
2972
  if (isBefore) {
@@ -2625,8 +2981,16 @@ class GanttBarDrag {
2625
2981
  this.item.updateDate(this.item.start, this.item.start.endOfDay());
2626
2982
  }
2627
2983
  }
2984
+ this.item.updateRefs({
2985
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
2986
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
2987
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
2988
+ });
2628
2989
  this.clearDraggingStyles();
2629
2990
  this.closeDragBackdrop();
2991
+ event.source.reset();
2992
+ this.dragScrolling = false;
2993
+ this.barHandleDragMoveDistance = 0;
2630
2994
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2631
2995
  });
2632
2996
  dragRefs.push(dragRef);
@@ -2687,8 +3051,10 @@ class GanttBarDrag {
2687
3051
  return dragRefs;
2688
3052
  }
2689
3053
  openDragBackdrop(dragElement, start, end) {
2690
- const dragBackdropElement = this.root.backdrop.nativeElement;
2691
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3054
+ // const dragBackdropElement = this.root.backdrop.nativeElement;
3055
+ // const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask') as HTMLElement;
3056
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3057
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2692
3058
  const rootRect = this.dom.root.getBoundingClientRect();
2693
3059
  const dragRect = dragElement.getBoundingClientRect();
2694
3060
  const left = dragRect.left - rootRect.left - this.dom.side.clientWidth;
@@ -2703,8 +3069,8 @@ class GanttBarDrag {
2703
3069
  dragMaskElement.querySelector('.end').innerHTML = end.format('MM-dd');
2704
3070
  }
2705
3071
  closeDragBackdrop() {
2706
- const dragBackdropElement = this.root.backdrop.nativeElement;
2707
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3072
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3073
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2708
3074
  dragMaskElement.style.display = 'none';
2709
3075
  dragBackdropElement.style.display = 'none';
2710
3076
  }
@@ -2716,6 +3082,45 @@ class GanttBarDrag {
2716
3082
  this.barElement.style.pointerEvents = '';
2717
3083
  this.barElement.classList.remove('gantt-bar-draggable-drag');
2718
3084
  }
3085
+ barDragMove(dragRef, distance) {
3086
+ const currentX = this.item.refs.x + distance;
3087
+ const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
3088
+ const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
3089
+ const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
3090
+ const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
3091
+ let start = currentDate;
3092
+ let end = currentDate.addDays(diffDays);
3093
+ if (currentX > currentStartX + dayWidth / 2) {
3094
+ start = start.addDays(1);
3095
+ end = end.addDays(1);
3096
+ }
3097
+ this.openDragBackdrop(dragRef['_preview'], this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
3098
+ this.item.updateDate(start, end);
3099
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3100
+ }
3101
+ barHandleDragMove(distance, isBefore) {
3102
+ if (isBefore) {
3103
+ const x = this.item.refs.x + distance;
3104
+ const width = this.item.refs.width + distance * -1;
3105
+ const start = this.ganttUpper.view.getDateByXPoint(x);
3106
+ if (width > dragMinWidth) {
3107
+ this.barElement.style.width = width + 'px';
3108
+ this.barElement.style.left = x + 'px';
3109
+ this.openDragBackdrop(this.barElement, start, this.item.end);
3110
+ this.item.updateDate(start, this.item.end);
3111
+ }
3112
+ }
3113
+ else {
3114
+ const width = this.item.refs.width + distance;
3115
+ const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
3116
+ if (width > dragMinWidth) {
3117
+ this.barElement.style.width = width + 'px';
3118
+ this.openDragBackdrop(this.barElement, this.item.start, end);
3119
+ this.item.updateDate(this.item.start, end);
3120
+ }
3121
+ }
3122
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3123
+ }
2719
3124
  calcLinkLinePositions(target, isBefore) {
2720
3125
  const rootRect = this.dom.root.getBoundingClientRect();
2721
3126
  const targetRect = target.getBoundingClientRect();
@@ -2747,7 +3152,6 @@ class GanttBarDrag {
2747
3152
  this.item = item;
2748
3153
  this.barElement = elementRef.nativeElement;
2749
3154
  this.ganttUpper = ganttUpper;
2750
- // if (!item.draggable || (this.dragDisabled && this.linkDragDisabled)) {
2751
3155
  if (this.dragDisabled && this.linkDragDisabled) {
2752
3156
  return;
2753
3157
  }
@@ -2757,6 +3161,13 @@ class GanttBarDrag {
2757
3161
  const dragRef = this.createBarDrag();
2758
3162
  const dragHandlesRefs = this.createBarHandleDrags();
2759
3163
  this.dragRefs.push(dragRef, ...dragHandlesRefs);
3164
+ // 创建拖拽容器并将所有元素添加到容器中,利用容器来实现自动滚动
3165
+ if (!this.dropListRef) {
3166
+ this.dropListRef = this.dragDrop.createDropList(this.dom.mainContainer);
3167
+ this.dropListRef.autoScrollStep = autoScrollStep;
3168
+ this.dropListRef.withOrientation('horizontal');
3169
+ }
3170
+ this.dropListRef.withItems([dragRef, ...dragHandlesRefs]);
2760
3171
  }
2761
3172
  if (!this.linkDragDisabled) {
2762
3173
  const linkDragRefs = this.createLinkHandleDrags();
@@ -2764,6 +3175,9 @@ class GanttBarDrag {
2764
3175
  }
2765
3176
  }
2766
3177
  }
3178
+ updateItem(item) {
3179
+ this.item = item;
3180
+ }
2767
3181
  ngOnDestroy() {
2768
3182
  this.closeDragBackdrop();
2769
3183
  this.dragRefs.forEach((dragRef) => dragRef.dispose());
@@ -2771,11 +3185,11 @@ class GanttBarDrag {
2771
3185
  this.destroy$.complete();
2772
3186
  }
2773
3187
  }
2774
- 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 });
3188
+ 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 });
2775
3189
  GanttBarDrag.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag });
2776
3190
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, decorators: [{
2777
3191
  type: Injectable
2778
- }], ctorParameters: function () { return [{ type: i1$1.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
3192
+ }], ctorParameters: function () { return [{ type: i2.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
2779
3193
  type: SkipSelf
2780
3194
  }] }]; } });
2781
3195
 
@@ -2792,16 +3206,25 @@ class GanttItemUpper {
2792
3206
  this.setPositions();
2793
3207
  });
2794
3208
  }
2795
- ngOnChanges() {
3209
+ ngOnChanges(changes) {
2796
3210
  if (!this.firstChange) {
2797
- this.setPositions();
3211
+ this.itemChange(changes.item.currentValue);
2798
3212
  }
2799
3213
  }
3214
+ itemChange(item) {
3215
+ this.unsubscribe$.next();
3216
+ this.unsubscribe$.complete();
3217
+ this.item = item;
3218
+ this.setPositions();
3219
+ this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3220
+ this.setPositions();
3221
+ });
3222
+ }
2800
3223
  setPositions() {
2801
3224
  const itemElement = this.elementRef.nativeElement;
2802
- itemElement.style.left = this.item.refs.x + 'px';
2803
- itemElement.style.top = this.item.refs.y + 'px';
2804
- itemElement.style.width = this.item.refs.width + 'px';
3225
+ itemElement.style.left = this.item.refs?.x + 'px';
3226
+ itemElement.style.top = this.item.refs?.y + 'px';
3227
+ itemElement.style.width = this.item.refs?.width + 'px';
2805
3228
  if (this.item.type === GanttItemType.bar) {
2806
3229
  itemElement.style.height = this.ganttUpper.styles.barHeight + 'px';
2807
3230
  }
@@ -2846,6 +3269,12 @@ class NgxGanttBarComponent extends GanttItemUpper {
2846
3269
  this.setContentBackground();
2847
3270
  });
2848
3271
  }
3272
+ ngOnChanges(changes) {
3273
+ super.ngOnChanges(changes);
3274
+ if (!this.firstChange) {
3275
+ this.drag.updateItem(this.item);
3276
+ }
3277
+ }
2849
3278
  ngAfterViewInit() {
2850
3279
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2851
3280
  // the `onStable` will never emit any value.
@@ -2859,7 +3288,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2859
3288
  });
2860
3289
  this.setContentBackground();
2861
3290
  this.handles.changes
2862
- .pipe(startWith(this.handles), switchMap(() =>
3291
+ .pipe(startWith$1(this.handles), switchMap(() =>
2863
3292
  // Note: we need to explicitly subscribe outside of the Angular zone since `addEventListener`
2864
3293
  // is called when the `fromEvent` is subscribed.
2865
3294
  new Observable((subscriber) => this.ngZone.runOutsideAngular(() => merge(...this.handles.toArray().map((handle) => fromEvent(handle.nativeElement, 'mousedown'))).subscribe(subscriber)))), takeUntil(this.unsubscribe$))
@@ -2903,7 +3332,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2903
3332
  }
2904
3333
  }
2905
3334
  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 });
2906
- 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"] }] });
3335
+ 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"] }] });
2907
3336
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttBarComponent, decorators: [{
2908
3337
  type: Component,
2909
3338
  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" }]
@@ -2988,16 +3417,16 @@ class GanttMainComponent {
2988
3417
  }
2989
3418
  }
2990
3419
  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 });
2991
- 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" }] });
3420
+ 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" }] });
2992
3421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, decorators: [{
2993
3422
  type: Component,
2994
- 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" }]
3423
+ 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" }]
2995
3424
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2996
3425
  type: Inject,
2997
3426
  args: [GANTT_UPPER_TOKEN]
2998
- }] }]; }, propDecorators: { groups: [{
3427
+ }] }]; }, propDecorators: { renderData: [{
2999
3428
  type: Input
3000
- }], items: [{
3429
+ }], flatData: [{
3001
3430
  type: Input
3002
3431
  }], groupHeaderTemplate: [{
3003
3432
  type: Input
@@ -3016,19 +3445,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3016
3445
  args: ['class.gantt-main-container']
3017
3446
  }] } });
3018
3447
 
3448
+ class GanttLoaderComponent {
3449
+ }
3450
+ GanttLoaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3451
+ GanttLoaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttLoaderComponent, selector: "gantt-loader", host: { classAttribute: "gantt-loader gantt-loader-overlay" }, ngImport: i0, template: `
3452
+ <div class="gantt-loader-wrapper">
3453
+ <div class="gantt-loader-loading">
3454
+ <span class="gantt-loader-loading-spot"></span>
3455
+ </div>
3456
+ </div>
3457
+ `, isInline: true });
3458
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLoaderComponent, decorators: [{
3459
+ type: Component,
3460
+ args: [{
3461
+ selector: 'gantt-loader',
3462
+ template: `
3463
+ <div class="gantt-loader-wrapper">
3464
+ <div class="gantt-loader-loading">
3465
+ <span class="gantt-loader-loading-spot"></span>
3466
+ </div>
3467
+ </div>
3468
+ `,
3469
+ host: {
3470
+ class: 'gantt-loader gantt-loader-overlay'
3471
+ }
3472
+ }]
3473
+ }] });
3474
+
3019
3475
  class NgxGanttComponent extends GanttUpper {
3020
- constructor(elementRef, cdr, ngZone, config) {
3476
+ set loading(loading) {
3477
+ if (loading) {
3478
+ if (this.loadingDelay > 0) {
3479
+ this.loadingTimer = setTimeout(() => {
3480
+ this._loading = loading;
3481
+ this.cdr.markForCheck();
3482
+ }, this.loadingDelay);
3483
+ }
3484
+ else {
3485
+ this._loading = loading;
3486
+ }
3487
+ }
3488
+ else {
3489
+ clearTimeout(this.loadingTimer);
3490
+ this._loading = loading;
3491
+ }
3492
+ }
3493
+ get loading() {
3494
+ return this._loading;
3495
+ }
3496
+ constructor(elementRef, cdr, ngZone, printService, config) {
3021
3497
  super(elementRef, cdr, ngZone, config);
3498
+ this.printService = printService;
3022
3499
  this.maxLevel = 2;
3500
+ this.loadingDelay = 0;
3023
3501
  this.linkDragStarted = new EventEmitter();
3024
3502
  this.linkDragEnded = new EventEmitter();
3025
3503
  this.lineClick = new EventEmitter();
3026
3504
  this.selectedChange = new EventEmitter();
3027
- this.ngUnsubscribe$ = new Subject();
3028
- this.sideTableWidth = sideWidth;
3505
+ this.flatData = [];
3506
+ this.renderData = [];
3507
+ this._loading = false;
3508
+ this.computeAllRefs = false;
3029
3509
  }
3030
3510
  ngOnInit() {
3031
3511
  super.ngOnInit();
3512
+ this.buildVirtualFlatData();
3032
3513
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
3033
3514
  // the `onStable` will never emit any value.
3034
3515
  const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
@@ -3036,24 +3517,84 @@ class NgxGanttComponent extends GanttUpper {
3036
3517
  // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
3037
3518
  this.ngZone.runOutsideAngular(() => {
3038
3519
  onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3039
- this.dragContainer.linkDragStarted.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3520
+ // this.dragContainer.dragEnded.subscribe((event) => {
3521
+ // this.computeTempDataRefs();
3522
+ // });
3523
+ this.dragContainer.linkDragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3040
3524
  this.linkDragStarted.emit(event);
3041
3525
  });
3042
- this.dragContainer.linkDragEnded.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3526
+ this.dragContainer.linkDragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3043
3527
  this.linkDragEnded.emit(event);
3044
3528
  });
3045
3529
  });
3046
3530
  });
3531
+ this.view.start$.pipe(skip(1), takeUntil(this.unsubscribe$)).subscribe(() => {
3532
+ this.computeTempDataRefs();
3533
+ });
3534
+ }
3535
+ ngOnChanges(changes) {
3536
+ super.ngOnChanges(changes);
3537
+ if (!this.firstChange) {
3538
+ if (changes.viewType && changes.viewType.currentValue) {
3539
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3540
+ this.computeTempDataRefs();
3541
+ }
3542
+ if (changes.originItems || changes.originGroups) {
3543
+ this.buildVirtualFlatData();
3544
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3545
+ this.computeTempDataRefs();
3546
+ }
3547
+ }
3047
3548
  }
3048
3549
  ngAfterViewInit() {
3049
- this.columns.changes.pipe(startWith(true), takeUntil(this.ngUnsubscribe$)).subscribe(() => {
3050
- this.columns.forEach((column) => {
3051
- if (!column.columnWidth) {
3052
- column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
3550
+ this.virtualScroll.renderedRangeStream.pipe(takeUntil(this.unsubscribe$)).subscribe((range) => {
3551
+ const linksElement = this.elementRef.nativeElement.querySelector('.gantt-links-overlay');
3552
+ linksElement.style.top = `${-(this.styles.lineHeight * range.start)}px`;
3553
+ this.rangeStart = range.start;
3554
+ this.rangeEnd = range.end;
3555
+ this.renderData = this.flatData.slice(range.start, range.end);
3556
+ this.computeTempDataRefs();
3557
+ });
3558
+ }
3559
+ buildVirtualFlatData() {
3560
+ const virtualData = [];
3561
+ if (this.groups.length) {
3562
+ this.groups.forEach((group) => {
3563
+ virtualData.push(group);
3564
+ if (group.expanded) {
3565
+ const items = recursiveItems(group.items);
3566
+ virtualData.push(...items);
3053
3567
  }
3054
3568
  });
3055
- this.cdr.detectChanges();
3569
+ }
3570
+ if (this.items.length) {
3571
+ virtualData.push(...recursiveItems(this.items));
3572
+ }
3573
+ this.flatData = [...virtualData];
3574
+ this.flatDataMap = keyBy(this.flatData, 'id');
3575
+ }
3576
+ afterExpand() {
3577
+ this.buildVirtualFlatData();
3578
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3579
+ }
3580
+ computeTempDataRefs() {
3581
+ const tempItemData = [];
3582
+ this.renderData.forEach((data) => {
3583
+ if (!data.hasOwnProperty('items')) {
3584
+ const item = data;
3585
+ if (item.links) {
3586
+ item.links.forEach((link) => {
3587
+ if (this.flatDataMap[link.link]) {
3588
+ tempItemData.push(this.flatDataMap[link.link]);
3589
+ }
3590
+ });
3591
+ }
3592
+ tempItemData.push(data);
3593
+ }
3056
3594
  });
3595
+ this.computeItemsRefs(...uniqBy(tempItemData, 'id'));
3596
+ this.flatData = [...this.flatData];
3597
+ this.renderData = [...this.renderData];
3057
3598
  }
3058
3599
  expandChildren(item) {
3059
3600
  if (!item.expanded) {
@@ -3063,6 +3604,7 @@ class NgxGanttComponent extends GanttUpper {
3063
3604
  this.childrenResolve(item.origin)
3064
3605
  .pipe(take(1), finalize(() => {
3065
3606
  item.loading = false;
3607
+ this.afterExpand();
3066
3608
  this.expandChange.emit(item);
3067
3609
  this.cdr.detectChanges();
3068
3610
  }))
@@ -3073,11 +3615,13 @@ class NgxGanttComponent extends GanttUpper {
3073
3615
  }
3074
3616
  else {
3075
3617
  this.computeItemsRefs(...item.children);
3618
+ this.afterExpand();
3076
3619
  this.expandChange.emit(item);
3077
3620
  }
3078
3621
  }
3079
3622
  else {
3080
3623
  item.setExpand(false);
3624
+ this.afterExpand();
3081
3625
  this.expandChange.emit(item);
3082
3626
  }
3083
3627
  }
@@ -3103,9 +3647,23 @@ class NgxGanttComponent extends GanttUpper {
3103
3647
  scrollToDate(date) {
3104
3648
  this.ganttRoot.scrollToDate(date);
3105
3649
  }
3650
+ expandGroups(expanded) {
3651
+ this.groups.forEach((group) => {
3652
+ group.setExpand(expanded);
3653
+ });
3654
+ this.afterExpand();
3655
+ this.expandChange.next(null);
3656
+ this.cdr.detectChanges();
3657
+ }
3658
+ expandGroup(group) {
3659
+ group.setExpand(!group.expanded);
3660
+ this.afterExpand();
3661
+ this.expandChange.emit();
3662
+ this.cdr.detectChanges();
3663
+ }
3106
3664
  }
3107
- 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 });
3108
- 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: [
3665
+ 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 });
3666
+ 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", loading: "loading", loadingDelay: "loadingDelay" }, outputs: { linkDragStarted: "linkDragStarted", linkDragEnded: "linkDragEnded", lineClick: "lineClick", selectedChange: "selectedChange" }, providers: [
3109
3667
  {
3110
3668
  provide: GANTT_UPPER_TOKEN,
3111
3669
  useExisting: NgxGanttComponent
@@ -3114,7 +3672,7 @@ NgxGanttComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
3114
3672
  provide: GANTT_ABSTRACT_TOKEN,
3115
3673
  useExisting: forwardRef(() => NgxGanttComponent)
3116
3674
  }
3117
- ], 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 });
3675
+ ], 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 <gantt-loader *ngIf=\"loading\"></gantt-loader>\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\" [style.width.px]=\"tableHeader.tableWidth + 1\">\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: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3.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: GanttLoaderComponent, selector: "gantt-loader" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: ["sideWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3118
3676
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, decorators: [{
3119
3677
  type: Component,
3120
3678
  args: [{ selector: 'ngx-gantt', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
@@ -3126,8 +3684,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3126
3684
  provide: GANTT_ABSTRACT_TOKEN,
3127
3685
  useExisting: forwardRef(() => NgxGanttComponent)
3128
3686
  }
3129
- ], 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" }]
3130
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
3687
+ ], 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 <gantt-loader *ngIf=\"loading\"></gantt-loader>\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\" [style.width.px]=\"tableHeader.tableWidth + 1\">\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" }]
3688
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: GanttPrintService, decorators: [{
3689
+ type: Optional
3690
+ }] }, { type: undefined, decorators: [{
3131
3691
  type: Inject,
3132
3692
  args: [GANTT_GLOBAL_CONFIG]
3133
3693
  }] }]; }, propDecorators: { maxLevel: [{
@@ -3138,6 +3698,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3138
3698
  type: Input
3139
3699
  }], linkable: [{
3140
3700
  type: Input
3701
+ }], loading: [{
3702
+ type: Input
3703
+ }], loadingDelay: [{
3704
+ type: Input
3141
3705
  }], linkDragStarted: [{
3142
3706
  type: Output
3143
3707
  }], linkDragEnded: [{
@@ -3158,6 +3722,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3158
3722
  }], ganttRoot: [{
3159
3723
  type: ViewChild,
3160
3724
  args: ['ganttRoot']
3725
+ }], virtualScroll: [{
3726
+ type: ViewChild,
3727
+ args: [CdkVirtualScrollViewport]
3161
3728
  }] } });
3162
3729
 
3163
3730
  class NgxGanttModule {
@@ -3166,10 +3733,15 @@ NgxGanttModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
3166
3733
  NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, declarations: [NgxGanttComponent,
3167
3734
  NgxGanttTableComponent,
3168
3735
  NgxGanttTableColumnComponent,
3169
- GanttTableComponent,
3736
+ // GanttTableComponent,
3737
+ GanttTableHeaderComponent,
3738
+ GanttTableBodyComponent,
3170
3739
  GanttMainComponent,
3171
- GanttCalendarComponent,
3740
+ // GanttCalendarComponent,
3741
+ GanttCalendarHeaderComponent,
3742
+ GanttCalendarGridComponent,
3172
3743
  GanttLinksComponent,
3744
+ GanttLoaderComponent,
3173
3745
  NgxGanttBarComponent,
3174
3746
  GanttIconComponent,
3175
3747
  GanttDragBackdropComponent,
@@ -3179,7 +3751,7 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3179
3751
  NgxGanttToolbarComponent,
3180
3752
  IsGanttRangeItemPipe,
3181
3753
  IsGanttBarItemPipe,
3182
- IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule], exports: [NgxGanttComponent,
3754
+ IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule, ScrollingModule], exports: [NgxGanttComponent,
3183
3755
  NgxGanttTableComponent,
3184
3756
  NgxGanttTableColumnComponent,
3185
3757
  NgxGanttRootComponent,
@@ -3188,15 +3760,16 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3188
3760
  NgxGanttBaselineComponent,
3189
3761
  NgxGanttToolbarComponent] });
3190
3762
  NgxGanttModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, providers: [
3763
+ CdkVirtualScrollViewport,
3191
3764
  {
3192
3765
  provide: GANTT_GLOBAL_CONFIG,
3193
3766
  useValue: defaultConfig
3194
3767
  }
3195
- ], imports: [CommonModule, DragDropModule] });
3768
+ ], imports: [CommonModule, DragDropModule, ScrollingModule] });
3196
3769
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, decorators: [{
3197
3770
  type: NgModule,
3198
3771
  args: [{
3199
- imports: [CommonModule, DragDropModule],
3772
+ imports: [CommonModule, DragDropModule, ScrollingModule],
3200
3773
  exports: [
3201
3774
  NgxGanttComponent,
3202
3775
  NgxGanttTableComponent,
@@ -3211,10 +3784,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3211
3784
  NgxGanttComponent,
3212
3785
  NgxGanttTableComponent,
3213
3786
  NgxGanttTableColumnComponent,
3214
- GanttTableComponent,
3787
+ // GanttTableComponent,
3788
+ GanttTableHeaderComponent,
3789
+ GanttTableBodyComponent,
3215
3790
  GanttMainComponent,
3216
- GanttCalendarComponent,
3791
+ // GanttCalendarComponent,
3792
+ GanttCalendarHeaderComponent,
3793
+ GanttCalendarGridComponent,
3217
3794
  GanttLinksComponent,
3795
+ GanttLoaderComponent,
3218
3796
  NgxGanttBarComponent,
3219
3797
  GanttIconComponent,
3220
3798
  GanttDragBackdropComponent,
@@ -3227,6 +3805,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3227
3805
  IsGanttCustomItemPipe
3228
3806
  ],
3229
3807
  providers: [
3808
+ CdkVirtualScrollViewport,
3230
3809
  {
3231
3810
  provide: GANTT_GLOBAL_CONFIG,
3232
3811
  useValue: defaultConfig
@@ -3243,5 +3822,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3243
3822
  * Generated bundle index. Do not edit.
3244
3823
  */
3245
3824
 
3246
- 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 };
3825
+ export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttBaselineItemInternal, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLinkLineType, GanttLinkType, GanttLoadOnScrollEvent, GanttLoaderComponent, 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 };
3247
3826
  //# sourceMappingURL=worktile-gantt.mjs.map