@worktile/gantt 15.0.0 → 15.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/class/event.d.ts +13 -0
  2. package/class/item.d.ts +7 -1
  3. package/components/bar/bar-drag.d.ts +10 -0
  4. package/components/bar/bar.component.d.ts +2 -1
  5. package/components/bar/bar.component.scss +22 -0
  6. package/components/calendar/calendar.scss +91 -0
  7. package/components/calendar/grid/calendar-grid.component.d.ts +24 -0
  8. package/components/calendar/header/calendar-header.component.d.ts +21 -0
  9. package/components/icon/icons.d.ts +1 -0
  10. package/components/links/links.component.d.ts +5 -5
  11. package/components/main/gantt-main.component.d.ts +3 -3
  12. package/components/table/body/gantt-table-body.component.d.ts +58 -0
  13. package/components/table/gantt-table.component.scss +169 -85
  14. package/components/table/gantt-table.scss +271 -0
  15. package/components/table/header/gantt-table-header.component.d.ts +31 -0
  16. package/esm2020/class/event.mjs +5 -1
  17. package/esm2020/class/item.mjs +9 -4
  18. package/esm2020/components/bar/bar-drag.mjs +106 -42
  19. package/esm2020/components/bar/bar.component.mjs +8 -2
  20. package/esm2020/components/calendar/grid/calendar-grid.component.mjs +71 -0
  21. package/esm2020/components/calendar/header/calendar-header.component.mjs +67 -0
  22. package/esm2020/components/icon/icons.mjs +4 -2
  23. package/esm2020/components/links/links.component.mjs +72 -54
  24. package/esm2020/components/main/gantt-main.component.mjs +5 -5
  25. package/esm2020/components/table/body/gantt-table-body.component.mjs +286 -0
  26. package/esm2020/components/table/header/gantt-table-header.component.mjs +140 -0
  27. package/esm2020/gantt-dom.service.mjs +8 -12
  28. package/esm2020/gantt-item-upper.mjs +15 -6
  29. package/esm2020/gantt-print.service.mjs +2 -2
  30. package/esm2020/gantt-upper.mjs +18 -15
  31. package/esm2020/gantt.component.mjs +114 -24
  32. package/esm2020/gantt.module.mjs +25 -10
  33. package/esm2020/root.component.mjs +10 -8
  34. package/esm2020/table/gantt-table.component.mjs +12 -4
  35. package/esm2020/utils/helpers.mjs +11 -1
  36. package/fesm2015/worktile-gantt.mjs +900 -377
  37. package/fesm2015/worktile-gantt.mjs.map +1 -1
  38. package/fesm2020/worktile-gantt.mjs +891 -379
  39. package/fesm2020/worktile-gantt.mjs.map +1 -1
  40. package/gantt-dom.service.d.ts +1 -0
  41. package/gantt-item-upper.d.ts +3 -2
  42. package/gantt-upper.d.ts +4 -1
  43. package/gantt.component.d.ts +20 -7
  44. package/gantt.component.scss +35 -0
  45. package/gantt.module.d.ts +18 -15
  46. package/package.json +1 -1
  47. package/root.component.d.ts +1 -1
  48. package/styles/index.scss +4 -2
  49. package/styles/variables.scss +9 -7
  50. package/table/gantt-table.component.d.ts +5 -2
  51. package/components/calendar/calendar.component.d.ts +0 -26
  52. package/components/table/gantt-table.component.d.ts +0 -42
  53. package/esm2020/components/calendar/calendar.component.mjs +0 -88
  54. 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 i2$1 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,172 @@ 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.getChildrenElementsByDragRef(event.source);
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
+ const appendIndex = position === 'after' ? 1 : 0;
1865
+ this.renderData.splice(this.renderData.indexOf(target) + appendIndex, 0, inserted);
1866
+ this.flatData.splice(this.flatData.indexOf(target) + appendIndex, 0, inserted);
1867
+ }
1868
+ insertChildrenItem(target, inserted) {
1869
+ if (target.expanded) {
1870
+ this.renderData.splice(this.renderData.indexOf(target) + target.children.length + 1, 0, inserted);
1871
+ this.flatData.splice(this.flatData.indexOf(target) + target.children.length + 1, 0, inserted);
1529
1872
  }
1530
- this.hideAuxiliaryLine();
1531
- event.source.reset();
1873
+ target.children.push(inserted);
1532
1874
  }
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);
1875
+ getParentByItem(item) {
1876
+ return (this.flatData || []).find((n) => {
1877
+ return n.children?.includes(item);
1543
1878
  });
1544
- if (this.gantt.table) {
1545
- this.gantt.table.columnChanges.emit({ columns: this.columnList });
1879
+ }
1880
+ getChildrenElementsByDragRef(dragRef) {
1881
+ // 通过循环持续查找 next element,如果 element 的 level 小于当前 item 的 level,则为它的 children
1882
+ const children = [];
1883
+ let nextElement = dragRef.getPlaceholderElement().nextElementSibling;
1884
+ let nextDragRef = this.itemDragRefMap.get(nextElement);
1885
+ while (nextDragRef && nextDragRef.data.level > dragRef.data.level) {
1886
+ children.push(nextElement);
1887
+ nextElement = nextElement.nextElementSibling;
1888
+ nextDragRef = this.itemDragRefMap.get(nextElement);
1546
1889
  }
1547
- this.hideAuxiliaryLine();
1548
- event.source.reset();
1890
+ return children;
1549
1891
  }
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';
1892
+ getTargetPosition(target, event) {
1893
+ const targetRect = target.getBoundingClientRect();
1894
+ const beforeOrAfterGap = targetRect.height * 0.3;
1895
+ // Item 高度分为上中下三段,其中上下的 Gap 为 height 的 30%,通过判断鼠标位置在哪一段 gap 来计算对应的位置
1896
+ if (event.pointerPosition.y - targetRect.top < beforeOrAfterGap) {
1897
+ return 'before';
1898
+ }
1899
+ else if (event.pointerPosition.y >= targetRect.bottom - beforeOrAfterGap) {
1900
+ return 'after';
1901
+ }
1902
+ else {
1903
+ return 'inside';
1904
+ }
1554
1905
  }
1555
- hideAuxiliaryLine() {
1556
- this.draglineElementRef.nativeElement.style.display = 'none';
1906
+ showDropPositionPlaceholder(targetElement) {
1907
+ this.cleanupDragArtifacts();
1908
+ if (this.itemDropTarget && targetElement) {
1909
+ targetElement.classList.add(`drop-position-${this.itemDropTarget.position}`);
1910
+ }
1557
1911
  }
1558
- trackBy(index, item) {
1559
- return item.id || index;
1912
+ cleanupDragArtifacts(dropped = false) {
1913
+ if (dropped) {
1914
+ this.itemDropTarget = null;
1915
+ }
1916
+ this.document.querySelectorAll('.drop-position-before').forEach((element) => element.classList.remove('drop-position-before'));
1917
+ this.document.querySelectorAll('.drop-position-after').forEach((element) => element.classList.remove('drop-position-after'));
1918
+ this.document.querySelectorAll('.drop-position-inside').forEach((element) => element.classList.remove('drop-position-inside'));
1919
+ this.document.querySelectorAll('.drag-item-hide').forEach((element) => element.classList.remove('drop-item-hide'));
1560
1920
  }
1561
1921
  }
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: [{
1922
+ 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 });
1923
+ 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" }] });
1924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttTableBodyComponent, decorators: [{
1565
1925
  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" }]
1926
+ 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
1927
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1568
1928
  type: Inject,
1569
1929
  args: [GANTT_ABSTRACT_TOKEN]
1570
1930
  }] }, { type: GanttUpper, decorators: [{
1571
1931
  type: Inject,
1572
1932
  args: [GANTT_UPPER_TOKEN]
1573
- }] }, { type: i0.ElementRef }]; }, propDecorators: { groups: [{
1933
+ }] }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
1934
+ type: Inject,
1935
+ args: [DOCUMENT]
1936
+ }] }]; }, propDecorators: { renderData: [{
1574
1937
  type: Input
1575
- }], items: [{
1938
+ }], flatData: [{
1576
1939
  type: Input
1577
1940
  }], columns: [{
1578
1941
  type: Input
@@ -1584,17 +1947,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1584
1947
  type: Input
1585
1948
  }], rowAfterTemplate: [{
1586
1949
  type: Input
1950
+ }], draggable: [{
1951
+ type: HostBinding,
1952
+ args: ['class.gantt-table-draggable']
1953
+ }, {
1954
+ type: Input
1955
+ }], dropEnterPredicate: [{
1956
+ type: Input
1957
+ }], dragDropped: [{
1958
+ type: Output
1587
1959
  }], itemClick: [{
1588
1960
  type: Output
1589
- }], draglineElementRef: [{
1590
- type: ViewChild,
1591
- args: ['dragLine', { static: true }]
1592
1961
  }], ganttTableClass: [{
1593
1962
  type: HostBinding,
1594
- args: ['class.gantt-table']
1963
+ args: ['class.gantt-table-body']
1595
1964
  }], ganttTableEmptyClass: [{
1596
1965
  type: HostBinding,
1597
1966
  args: ['class.gantt-table-empty']
1967
+ }], ganttTableDragging: [{
1968
+ type: HostBinding,
1969
+ args: ['class.gantt-table-dragging']
1970
+ }], cdkDrags: [{
1971
+ type: ViewChildren,
1972
+ args: [(CdkDrag)]
1598
1973
  }] } });
1599
1974
 
1600
1975
  class GanttLinkLine {
@@ -1850,13 +2225,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1850
2225
  }] }]; } });
1851
2226
 
1852
2227
  class GanttLinksComponent {
1853
- constructor(ganttUpper, cdr, elementRef, ganttDragContainer) {
2228
+ constructor(ganttUpper, cdr, elementRef, ganttDragContainer, ngZone) {
1854
2229
  this.ganttUpper = ganttUpper;
1855
2230
  this.cdr = cdr;
1856
2231
  this.elementRef = elementRef;
1857
2232
  this.ganttDragContainer = ganttDragContainer;
1858
- this.groups = [];
1859
- this.items = [];
2233
+ this.ngZone = ngZone;
2234
+ // @Input() groups: GanttGroupInternal[] = [];
2235
+ // @Input() items: GanttItemInternal[] = [];
2236
+ this.flatData = [];
1860
2237
  this.lineClick = new EventEmitter();
1861
2238
  this.links = [];
1862
2239
  this.ganttLinkTypes = GanttLinkType;
@@ -1869,13 +2246,14 @@ class GanttLinksComponent {
1869
2246
  ngOnInit() {
1870
2247
  this.linkLine = createLineGenerator(this.ganttUpper.linkOptions.lineType, this.ganttUpper);
1871
2248
  this.showArrow = this.ganttUpper.linkOptions.showArrow;
1872
- this.buildLinks();
2249
+ // this.buildLinks();
1873
2250
  this.firstChange = false;
2251
+ this.buildLinks();
1874
2252
  this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
1875
2253
  this.elementRef.nativeElement.style.visibility = 'hidden';
1876
2254
  });
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$))
2255
+ 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)))
2256
+ .pipe(skip(1), debounceTime$1(0), takeUntil(this.unsubscribe$))
1879
2257
  .subscribe(() => {
1880
2258
  this.elementRef.nativeElement.style.visibility = 'visible';
1881
2259
  this.buildLinks();
@@ -1891,48 +2269,66 @@ class GanttLinksComponent {
1891
2269
  const lineHeight = this.ganttUpper.styles.lineHeight;
1892
2270
  const barHeight = this.ganttUpper.styles.barHeight;
1893
2271
  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
- });
2272
+ // if (this.groups.length > 0) {
2273
+ // let itemNum = 0;
2274
+ // let groupNum = 0;
2275
+ // this.groups.forEach((group) => {
2276
+ // groupNum++;
2277
+ // if (group.expanded) {
2278
+ // const items = recursiveItems(group.items);
2279
+ // items.forEach((item, itemIndex) => {
2280
+ // const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
2281
+ // this.linkItems.push({
2282
+ // ...item,
2283
+ // before: {
2284
+ // x: item.refs.x,
2285
+ // y
2286
+ // },
2287
+ // after: {
2288
+ // x: item.refs.x + item.refs.width,
2289
+ // y
2290
+ // }
2291
+ // });
2292
+ // });
2293
+ // itemNum += items.length;
2294
+ // }
2295
+ // });
2296
+ // } else {
2297
+ // const items = recursiveItems(this.items);
2298
+ // items.forEach((item, itemIndex) => {
2299
+ // const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
2300
+ // this.linkItems.push({
2301
+ // ...item,
2302
+ // before: {
2303
+ // x: item.refs.x,
2304
+ // y
2305
+ // },
2306
+ // after: {
2307
+ // x: item.refs.x + item.refs.width,
2308
+ // y
2309
+ // }
2310
+ // });
2311
+ // });
2312
+ // }
2313
+ this.flatData.forEach((item, itemIndex) => {
2314
+ if (!item.hasOwnProperty('items')) {
2315
+ const ganttItem = item;
2316
+ if (ganttItem.refs) {
2317
+ const y = itemIndex * lineHeight + ganttItem.refs.y + barHeight / 2;
2318
+ this.linkItems.push({
2319
+ ...ganttItem,
2320
+ before: {
2321
+ x: ganttItem.refs.x,
2322
+ y
2323
+ },
2324
+ after: {
2325
+ x: ganttItem.refs.x + ganttItem.refs.width,
2326
+ y
2327
+ }
1914
2328
  });
1915
- itemNum += items.length;
1916
2329
  }
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
- }
2330
+ }
2331
+ });
1936
2332
  }
1937
2333
  buildLinks() {
1938
2334
  this.computeItemPosition();
@@ -1997,17 +2393,15 @@ class GanttLinksComponent {
1997
2393
  this.unsubscribe$.complete();
1998
2394
  }
1999
2395
  }
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"] }] });
2396
+ 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 });
2397
+ 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
2398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, decorators: [{
2003
2399
  type: Component,
2004
2400
  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
2401
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2006
2402
  type: Inject,
2007
2403
  args: [GANTT_UPPER_TOKEN]
2008
- }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }]; }, propDecorators: { groups: [{
2009
- type: Input
2010
- }], items: [{
2404
+ }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }, { type: i0.NgZone }]; }, propDecorators: { flatData: [{
2011
2405
  type: Input
2012
2406
  }], lineClick: [{
2013
2407
  type: Output
@@ -2065,18 +2459,10 @@ class GanttDomService {
2065
2459
  .subscribe((event) => {
2066
2460
  this.syncScroll(event);
2067
2461
  }));
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
2462
  }
2078
2463
  syncScroll(event) {
2079
2464
  const target = event.currentTarget;
2465
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2080
2466
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2081
2467
  this.sideContainer.scrollTop = target.scrollTop;
2082
2468
  this.mainContainer.scrollTop = target.scrollTop;
@@ -2102,8 +2488,11 @@ class GanttDomService {
2102
2488
  this.container = this.root.getElementsByClassName('gantt-container')[0];
2103
2489
  this.sideContainer = this.root.getElementsByClassName('gantt-side-container')[0];
2104
2490
  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];
2491
+ const mainItems = this.mainContainer.getElementsByClassName('gantt-main-items')[0];
2492
+ const mainGroups = this.mainContainer.getElementsByClassName('gantt-main-groups')[0];
2493
+ this.mainItems = mainItems || mainGroups;
2494
+ this.calendarHeader = this.root.getElementsByClassName('gantt-calendar-header')[0];
2495
+ this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-grid')[0];
2107
2496
  this.monitorScrollChange();
2108
2497
  this.disableBrowserWheelEvent();
2109
2498
  }
@@ -2140,6 +2529,7 @@ class GanttDomService {
2140
2529
  if (isNumber(left)) {
2141
2530
  const scrollLeft = left - this.mainContainer.clientWidth / 2;
2142
2531
  this.mainContainer.scrollLeft = scrollLeft > scrollThreshold ? scrollLeft : 0;
2532
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2143
2533
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2144
2534
  }
2145
2535
  }
@@ -2168,100 +2558,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2168
2558
  }, 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
2559
  }] });
2170
2560
 
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
- }
2561
+ class GanttCalendarHeaderComponent {
2562
+ get view() {
2563
+ return this.ganttUpper.view;
2178
2564
  }
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
- }
2565
+ constructor(ganttUpper, ngZone, elementRef) {
2566
+ this.ganttUpper = ganttUpper;
2567
+ this.ngZone = ngZone;
2568
+ this.elementRef = elementRef;
2569
+ this.unsubscribe$ = new Subject();
2570
+ this.headerHeight = headerHeight;
2571
+ this.viewTypes = GanttViewType;
2572
+ this.className = `gantt-calendar gantt-calendar-header`;
2201
2573
  }
2202
- register(root) {
2203
- this.root = root.nativeElement;
2204
- this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2574
+ ngOnInit() {
2575
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2576
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2577
+ .pipe(takeUntil(this.unsubscribe$))
2578
+ .subscribe(() => {
2579
+ if (this.ganttUpper.viewType === GanttViewType.day)
2580
+ this.setTodayPoint();
2581
+ });
2582
+ });
2205
2583
  }
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);
2584
+ setTodayPoint() {
2585
+ const x = this.view.getTodayXPoint();
2586
+ const today = new GanttDate().getDate();
2587
+ const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2588
+ const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2589
+ if (isNumber(x)) {
2590
+ if (rect) {
2591
+ rect.style.left = `${x - todayWidth / 2}px`;
2592
+ rect.style.top = `${headerHeight - todayHeight}px`;
2593
+ rect.innerHTML = today.toString();
2247
2594
  }
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
- });
2595
+ }
2596
+ else {
2597
+ todayEle.style.display = 'none';
2598
+ }
2599
+ }
2600
+ trackBy(point, index) {
2601
+ return point.text || index;
2255
2602
  }
2256
2603
  }
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 []; } });
2604
+ 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 });
2605
+ 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"] }] });
2606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarHeaderComponent, decorators: [{
2607
+ type: Component,
2608
+ 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" }]
2609
+ }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2610
+ type: Inject,
2611
+ args: [GANTT_UPPER_TOKEN]
2612
+ }] }, { type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { className: [{
2613
+ type: HostBinding,
2614
+ args: ['class']
2615
+ }] } });
2262
2616
 
2263
2617
  const mainHeight = 5000;
2264
- class GanttCalendarComponent {
2618
+ class GanttCalendarGridComponent {
2265
2619
  get view() {
2266
2620
  return this.ganttUpper.view;
2267
2621
  }
@@ -2269,30 +2623,21 @@ class GanttCalendarComponent {
2269
2623
  this.ganttUpper = ganttUpper;
2270
2624
  this.ngZone = ngZone;
2271
2625
  this.elementRef = elementRef;
2626
+ this.unsubscribe$ = new Subject();
2272
2627
  this.headerHeight = headerHeight;
2273
2628
  this.mainHeight = mainHeight;
2274
- this.todayHeight = todayHeight;
2275
- this.todayWidth = todayWidth;
2276
2629
  this.todayBorderRadius = todayBorderRadius;
2277
2630
  this.viewTypes = GanttViewType;
2278
- this.className = true;
2279
- this.unsubscribe$ = new Subject();
2631
+ this.className = `gantt-calendar gantt-calendar-grid`;
2280
2632
  }
2281
2633
  setTodayPoint() {
2282
2634
  const x = this.view.getTodayXPoint();
2283
- const today = new GanttDate().getDate();
2284
2635
  const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2285
- const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2286
2636
  const line = this.elementRef.nativeElement.getElementsByClassName('today-line')[0];
2287
2637
  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
2638
  if (line) {
2294
2639
  line.style.left = `${x}px`;
2295
- line.style.top = `${headerHeight}px`;
2640
+ line.style.top = `0px`;
2296
2641
  line.style.bottom = `${-mainHeight}px`;
2297
2642
  }
2298
2643
  }
@@ -2301,22 +2646,15 @@ class GanttCalendarComponent {
2301
2646
  }
2302
2647
  }
2303
2648
  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
- });
2649
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2650
+ merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2651
+ .pipe(takeUntil(this.unsubscribe$))
2652
+ .subscribe(() => {
2653
+ this.setTodayPoint();
2316
2654
  });
2317
2655
  });
2318
2656
  }
2319
- trackBy(index, point) {
2657
+ trackBy(point, index) {
2320
2658
  return point.text || index;
2321
2659
  }
2322
2660
  ngOnDestroy() {
@@ -2324,17 +2662,17 @@ class GanttCalendarComponent {
2324
2662
  this.unsubscribe$.complete();
2325
2663
  }
2326
2664
  }
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: [{
2665
+ 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 });
2666
+ 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"] }] });
2667
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttCalendarGridComponent, decorators: [{
2330
2668
  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" }]
2669
+ 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
2670
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2333
2671
  type: Inject,
2334
2672
  args: [GANTT_UPPER_TOKEN]
2335
2673
  }] }, { type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { className: [{
2336
2674
  type: HostBinding,
2337
- args: ['class.gantt-calendar-overlay']
2675
+ args: ['class']
2338
2676
  }] } });
2339
2677
 
2340
2678
  class NgxGanttToolbarComponent {
@@ -2393,7 +2731,7 @@ class NgxGanttRootComponent {
2393
2731
  this.setupViewScroll();
2394
2732
  // 优化初始化时Scroll滚动体验问题,通过透明度解决,默认透明度为0,滚动结束后恢复
2395
2733
  this.elementRef.nativeElement.style.opacity = '1';
2396
- this.ganttUpper.viewChange.pipe(startWith(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2734
+ this.ganttUpper.viewChange.pipe(startWith$1(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2397
2735
  this.scrollToToday();
2398
2736
  });
2399
2737
  });
@@ -2462,12 +2800,12 @@ class NgxGanttRootComponent {
2462
2800
  }
2463
2801
  }
2464
2802
  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"] }] });
2803
+ NgxGanttRootComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: { sideWidth: "sideWidth" }, host: { classAttribute: "gantt" }, providers: [GanttDomService, GanttDragContainer], queries: [{ propertyName: "sideTemplate", first: true, predicate: ["sideTemplate"], descendants: true, static: true }, { propertyName: "mainTemplate", first: true, predicate: ["mainTemplate"], descendants: true, static: true }], viewQueries: [{ propertyName: "backdrop", first: true, predicate: GanttDragBackdropComponent, descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div class=\"gantt-side\" *ngIf=\"sideTemplate\" [style.width.px]=\"sideWidth\">\n <div class=\"gantt-side-container\" cdkScrollable>\n <ng-template [ngTemplateOutlet]=\"sideTemplate\"></ng-template>\n </div>\n</div>\n<div class=\"gantt-container\" *ngIf=\"mainTemplate\">\n <gantt-calendar-header></gantt-calendar-header>\n <gantt-calendar-grid></gantt-calendar-grid>\n <gantt-drag-backdrop></gantt-drag-backdrop>\n <div class=\"gantt-main\">\n <ng-template [ngTemplateOutlet]=\"mainTemplate\"></ng-template>\n </div>\n</div>\n<ng-content></ng-content>\n<gantt-toolbar *ngIf=\"ganttUpper.showToolbar || ganttUpper.toolbarTemplate\" [template]=\"ganttUpper.toolbarTemplate\"> </gantt-toolbar>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: GanttCalendarHeaderComponent, selector: "gantt-calendar-header" }, { kind: "component", type: GanttCalendarGridComponent, selector: "gantt-calendar-grid" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttToolbarComponent, selector: "ngx-gantt-toolbar,gantt-toolbar", inputs: ["template"] }] });
2466
2804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttRootComponent, decorators: [{
2467
2805
  type: Component,
2468
2806
  args: [{ selector: 'ngx-gantt-root', providers: [GanttDomService, GanttDragContainer], host: {
2469
2807
  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" }]
2808
+ }, 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
2809
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: GanttDomService }, { type: GanttDragContainer }, { type: GanttUpper, decorators: [{
2472
2810
  type: Inject,
2473
2811
  args: [GANTT_UPPER_TOKEN]
@@ -2487,6 +2825,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2487
2825
  }] } });
2488
2826
 
2489
2827
  const dragMinWidth = 10;
2828
+ const autoScrollStep = 10;
2490
2829
  const activeClass = 'gantt-bar-active';
2491
2830
  const dropActiveClass = 'gantt-bar-drop-active';
2492
2831
  const singleDropActiveClass = 'gantt-bar-single-drop-active';
@@ -2509,6 +2848,16 @@ class GanttBarDrag {
2509
2848
  this.root = root;
2510
2849
  this.dragRefs = [];
2511
2850
  this.destroy$ = new Subject();
2851
+ // scrolling state when drag
2852
+ this.dragScrolling = false;
2853
+ }
2854
+ createDragRef(element) {
2855
+ const dragRef = this.dragDrop.createDrag(element);
2856
+ // dragRef.withPreviewContainer(this.dom.mainContainer as HTMLElement);
2857
+ return dragRef;
2858
+ }
2859
+ createDragScrollEvent(dragRef) {
2860
+ return fromEvent(this.dom.mainContainer, 'scroll', passiveListenerOptions).pipe(takeUntil(dragRef.ended));
2512
2861
  }
2513
2862
  createMouseEvents() {
2514
2863
  const dropClass = this.ganttUpper.config.linkOptions?.dependencyTypes?.length === 1 &&
@@ -2544,33 +2893,38 @@ class GanttBarDrag {
2544
2893
  });
2545
2894
  }
2546
2895
  createBarDrag() {
2547
- const dragRef = this.dragDrop.createDrag(this.barElement);
2896
+ const dragRef = this.createDragRef(this.barElement);
2548
2897
  dragRef.lockAxis = 'x';
2549
2898
  dragRef.withBoundaryElement(this.dom.mainItems);
2550
2899
  dragRef.started.subscribe(() => {
2551
2900
  this.setDraggingStyles();
2901
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2902
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2903
+ if (this.dropListRef.isDragging()) {
2904
+ this.dragScrolling = true;
2905
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2906
+ this.barDragMove(dragRef, scrollDistance + this.barDragMoveDistance);
2907
+ }
2908
+ });
2552
2909
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2553
2910
  });
2554
2911
  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);
2912
+ this.barDragMove(dragRef, event.distance.x);
2913
+ if (!this.dragScrolling) {
2914
+ this.barDragMoveDistance = event.distance.x;
2565
2915
  }
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
2916
  });
2570
2917
  dragRef.ended.subscribe((event) => {
2918
+ this.item.updateRefs({
2919
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
2920
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
2921
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
2922
+ });
2571
2923
  this.clearDraggingStyles();
2572
2924
  this.closeDragBackdrop();
2573
2925
  event.source.reset();
2926
+ this.dragScrolling = false;
2927
+ this.barDragMoveDistance = 0;
2574
2928
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2575
2929
  });
2576
2930
  this.barDragRef = dragRef;
@@ -2581,36 +2935,26 @@ class GanttBarDrag {
2581
2935
  const handles = this.barElement.querySelectorAll('.drag-handles .handle');
2582
2936
  handles.forEach((handle, index) => {
2583
2937
  const isBefore = index === 0;
2584
- const dragRef = this.dragDrop.createDrag(handle);
2938
+ const dragRef = this.createDragRef(handle);
2585
2939
  dragRef.lockAxis = 'x';
2586
2940
  dragRef.withBoundaryElement(this.dom.mainItems);
2587
2941
  dragRef.started.subscribe(() => {
2588
2942
  this.setDraggingStyles();
2943
+ this.containerScrollLeft = this.dom.mainContainer.scrollLeft;
2944
+ this.createDragScrollEvent(dragRef).subscribe(() => {
2945
+ if (this.dropListRef.isDragging()) {
2946
+ this.dragScrolling = true;
2947
+ const scrollDistance = this.dom.mainContainer.scrollLeft - this.containerScrollLeft;
2948
+ this.barHandleDragMove(scrollDistance + this.barHandleDragMoveDistance, isBefore);
2949
+ }
2950
+ });
2589
2951
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2590
2952
  });
2591
2953
  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
- }
2954
+ this.barHandleDragMove(event.distance.x, isBefore);
2955
+ if (!this.dragScrolling) {
2956
+ this.barHandleDragMoveDistance = event.distance.x;
2611
2957
  }
2612
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2613
- event.source.reset();
2614
2958
  });
2615
2959
  dragRef.ended.subscribe((event) => {
2616
2960
  if (isBefore) {
@@ -2625,8 +2969,16 @@ class GanttBarDrag {
2625
2969
  this.item.updateDate(this.item.start, this.item.start.endOfDay());
2626
2970
  }
2627
2971
  }
2972
+ this.item.updateRefs({
2973
+ width: this.ganttUpper.view.getDateRangeWidth(this.item.start.startOfDay(), this.item.end.endOfDay()),
2974
+ x: this.ganttUpper.view.getXPointByDate(this.item.start),
2975
+ y: (this.ganttUpper.styles.lineHeight - this.ganttUpper.styles.barHeight) / 2 - 1
2976
+ });
2628
2977
  this.clearDraggingStyles();
2629
2978
  this.closeDragBackdrop();
2979
+ event.source.reset();
2980
+ this.dragScrolling = false;
2981
+ this.barHandleDragMoveDistance = 0;
2630
2982
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2631
2983
  });
2632
2984
  dragRefs.push(dragRef);
@@ -2687,8 +3039,10 @@ class GanttBarDrag {
2687
3039
  return dragRefs;
2688
3040
  }
2689
3041
  openDragBackdrop(dragElement, start, end) {
2690
- const dragBackdropElement = this.root.backdrop.nativeElement;
2691
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3042
+ // const dragBackdropElement = this.root.backdrop.nativeElement;
3043
+ // const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask') as HTMLElement;
3044
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3045
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2692
3046
  const rootRect = this.dom.root.getBoundingClientRect();
2693
3047
  const dragRect = dragElement.getBoundingClientRect();
2694
3048
  const left = dragRect.left - rootRect.left - this.dom.side.clientWidth;
@@ -2703,8 +3057,8 @@ class GanttBarDrag {
2703
3057
  dragMaskElement.querySelector('.end').innerHTML = end.format('MM-dd');
2704
3058
  }
2705
3059
  closeDragBackdrop() {
2706
- const dragBackdropElement = this.root.backdrop.nativeElement;
2707
- const dragMaskElement = dragBackdropElement.querySelector('.gantt-drag-mask');
3060
+ const dragBackdropElement = this.dom.root.querySelector('.gantt-drag-backdrop');
3061
+ const dragMaskElement = this.dom.root.querySelector('.gantt-drag-mask');
2708
3062
  dragMaskElement.style.display = 'none';
2709
3063
  dragBackdropElement.style.display = 'none';
2710
3064
  }
@@ -2716,6 +3070,45 @@ class GanttBarDrag {
2716
3070
  this.barElement.style.pointerEvents = '';
2717
3071
  this.barElement.classList.remove('gantt-bar-draggable-drag');
2718
3072
  }
3073
+ barDragMove(dragRef, distance) {
3074
+ const currentX = this.item.refs.x + distance;
3075
+ const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
3076
+ const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
3077
+ const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
3078
+ const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
3079
+ let start = currentDate;
3080
+ let end = currentDate.addDays(diffDays);
3081
+ if (currentX > currentStartX + dayWidth / 2) {
3082
+ start = start.addDays(1);
3083
+ end = end.addDays(1);
3084
+ }
3085
+ this.openDragBackdrop(dragRef['_preview'], this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
3086
+ this.item.updateDate(start, end);
3087
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3088
+ }
3089
+ barHandleDragMove(distance, isBefore) {
3090
+ if (isBefore) {
3091
+ const x = this.item.refs.x + distance;
3092
+ const width = this.item.refs.width + distance * -1;
3093
+ const start = this.ganttUpper.view.getDateByXPoint(x);
3094
+ if (width > dragMinWidth) {
3095
+ this.barElement.style.width = width + 'px';
3096
+ this.barElement.style.left = x + 'px';
3097
+ this.openDragBackdrop(this.barElement, start, this.item.end);
3098
+ this.item.updateDate(start, this.item.end);
3099
+ }
3100
+ }
3101
+ else {
3102
+ const width = this.item.refs.width + distance;
3103
+ const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
3104
+ if (width > dragMinWidth) {
3105
+ this.barElement.style.width = width + 'px';
3106
+ this.openDragBackdrop(this.barElement, this.item.start, end);
3107
+ this.item.updateDate(this.item.start, end);
3108
+ }
3109
+ }
3110
+ this.dragContainer.dragMoved.emit({ item: this.item.origin });
3111
+ }
2719
3112
  calcLinkLinePositions(target, isBefore) {
2720
3113
  const rootRect = this.dom.root.getBoundingClientRect();
2721
3114
  const targetRect = target.getBoundingClientRect();
@@ -2747,7 +3140,6 @@ class GanttBarDrag {
2747
3140
  this.item = item;
2748
3141
  this.barElement = elementRef.nativeElement;
2749
3142
  this.ganttUpper = ganttUpper;
2750
- // if (!item.draggable || (this.dragDisabled && this.linkDragDisabled)) {
2751
3143
  if (this.dragDisabled && this.linkDragDisabled) {
2752
3144
  return;
2753
3145
  }
@@ -2757,6 +3149,13 @@ class GanttBarDrag {
2757
3149
  const dragRef = this.createBarDrag();
2758
3150
  const dragHandlesRefs = this.createBarHandleDrags();
2759
3151
  this.dragRefs.push(dragRef, ...dragHandlesRefs);
3152
+ // 创建拖拽容器并将所有元素添加到容器中,利用容器来实现自动滚动
3153
+ if (!this.dropListRef) {
3154
+ this.dropListRef = this.dragDrop.createDropList(this.dom.mainContainer);
3155
+ this.dropListRef.autoScrollStep = autoScrollStep;
3156
+ this.dropListRef.withOrientation('horizontal');
3157
+ }
3158
+ this.dropListRef.withItems([dragRef, ...dragHandlesRefs]);
2760
3159
  }
2761
3160
  if (!this.linkDragDisabled) {
2762
3161
  const linkDragRefs = this.createLinkHandleDrags();
@@ -2764,6 +3163,9 @@ class GanttBarDrag {
2764
3163
  }
2765
3164
  }
2766
3165
  }
3166
+ updateItem(item) {
3167
+ this.item = item;
3168
+ }
2767
3169
  ngOnDestroy() {
2768
3170
  this.closeDragBackdrop();
2769
3171
  this.dragRefs.forEach((dragRef) => dragRef.dispose());
@@ -2771,11 +3173,11 @@ class GanttBarDrag {
2771
3173
  this.destroy$.complete();
2772
3174
  }
2773
3175
  }
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 });
3176
+ 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
3177
  GanttBarDrag.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag });
2776
3178
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, decorators: [{
2777
3179
  type: Injectable
2778
- }], ctorParameters: function () { return [{ type: i1$1.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
3180
+ }], ctorParameters: function () { return [{ type: i2.DragDrop }, { type: GanttDomService }, { type: GanttDragContainer }, { type: NgxGanttRootComponent, decorators: [{
2779
3181
  type: SkipSelf
2780
3182
  }] }]; } });
2781
3183
 
@@ -2792,16 +3194,25 @@ class GanttItemUpper {
2792
3194
  this.setPositions();
2793
3195
  });
2794
3196
  }
2795
- ngOnChanges() {
3197
+ ngOnChanges(changes) {
2796
3198
  if (!this.firstChange) {
2797
- this.setPositions();
3199
+ this.itemChange(changes.item.currentValue);
2798
3200
  }
2799
3201
  }
3202
+ itemChange(item) {
3203
+ this.unsubscribe$.next();
3204
+ this.unsubscribe$.complete();
3205
+ this.item = item;
3206
+ this.setPositions();
3207
+ this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3208
+ this.setPositions();
3209
+ });
3210
+ }
2800
3211
  setPositions() {
2801
3212
  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';
3213
+ itemElement.style.left = this.item.refs?.x + 'px';
3214
+ itemElement.style.top = this.item.refs?.y + 'px';
3215
+ itemElement.style.width = this.item.refs?.width + 'px';
2805
3216
  if (this.item.type === GanttItemType.bar) {
2806
3217
  itemElement.style.height = this.ganttUpper.styles.barHeight + 'px';
2807
3218
  }
@@ -2846,6 +3257,12 @@ class NgxGanttBarComponent extends GanttItemUpper {
2846
3257
  this.setContentBackground();
2847
3258
  });
2848
3259
  }
3260
+ ngOnChanges(changes) {
3261
+ super.ngOnChanges(changes);
3262
+ if (!this.firstChange) {
3263
+ this.drag.updateItem(this.item);
3264
+ }
3265
+ }
2849
3266
  ngAfterViewInit() {
2850
3267
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2851
3268
  // the `onStable` will never emit any value.
@@ -2859,7 +3276,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2859
3276
  });
2860
3277
  this.setContentBackground();
2861
3278
  this.handles.changes
2862
- .pipe(startWith(this.handles), switchMap(() =>
3279
+ .pipe(startWith$1(this.handles), switchMap(() =>
2863
3280
  // Note: we need to explicitly subscribe outside of the Angular zone since `addEventListener`
2864
3281
  // is called when the `fromEvent` is subscribed.
2865
3282
  new Observable((subscriber) => this.ngZone.runOutsideAngular(() => merge(...this.handles.toArray().map((handle) => fromEvent(handle.nativeElement, 'mousedown'))).subscribe(subscriber)))), takeUntil(this.unsubscribe$))
@@ -2903,7 +3320,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2903
3320
  }
2904
3321
  }
2905
3322
  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"] }] });
3323
+ 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
3324
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttBarComponent, decorators: [{
2908
3325
  type: Component,
2909
3326
  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 +3405,16 @@ class GanttMainComponent {
2988
3405
  }
2989
3406
  }
2990
3407
  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" }] });
3408
+ 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
3409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, decorators: [{
2993
3410
  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" }]
3411
+ 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
3412
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2996
3413
  type: Inject,
2997
3414
  args: [GANTT_UPPER_TOKEN]
2998
- }] }]; }, propDecorators: { groups: [{
3415
+ }] }]; }, propDecorators: { renderData: [{
2999
3416
  type: Input
3000
- }], items: [{
3417
+ }], flatData: [{
3001
3418
  type: Input
3002
3419
  }], groupHeaderTemplate: [{
3003
3420
  type: Input
@@ -3017,18 +3434,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3017
3434
  }] } });
3018
3435
 
3019
3436
  class NgxGanttComponent extends GanttUpper {
3020
- constructor(elementRef, cdr, ngZone, config) {
3437
+ constructor(elementRef, cdr, ngZone, printService, config) {
3021
3438
  super(elementRef, cdr, ngZone, config);
3439
+ this.printService = printService;
3022
3440
  this.maxLevel = 2;
3023
3441
  this.linkDragStarted = new EventEmitter();
3024
3442
  this.linkDragEnded = new EventEmitter();
3025
3443
  this.lineClick = new EventEmitter();
3026
3444
  this.selectedChange = new EventEmitter();
3027
- this.ngUnsubscribe$ = new Subject();
3028
- this.sideTableWidth = sideWidth;
3445
+ this.flatData = [];
3446
+ this.renderData = [];
3447
+ this.computeAllRefs = false;
3029
3448
  }
3030
3449
  ngOnInit() {
3031
3450
  super.ngOnInit();
3451
+ this.buildVirtualFlatData();
3032
3452
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
3033
3453
  // the `onStable` will never emit any value.
3034
3454
  const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
@@ -3036,24 +3456,84 @@ class NgxGanttComponent extends GanttUpper {
3036
3456
  // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
3037
3457
  this.ngZone.runOutsideAngular(() => {
3038
3458
  onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3039
- this.dragContainer.linkDragStarted.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3459
+ // this.dragContainer.dragEnded.subscribe((event) => {
3460
+ // this.computeTempDataRefs();
3461
+ // });
3462
+ this.dragContainer.linkDragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3040
3463
  this.linkDragStarted.emit(event);
3041
3464
  });
3042
- this.dragContainer.linkDragEnded.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3465
+ this.dragContainer.linkDragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3043
3466
  this.linkDragEnded.emit(event);
3044
3467
  });
3045
3468
  });
3046
3469
  });
3470
+ this.view.start$.pipe(skip(1), takeUntil(this.unsubscribe$)).subscribe(() => {
3471
+ this.computeTempDataRefs();
3472
+ });
3473
+ }
3474
+ ngOnChanges(changes) {
3475
+ super.ngOnChanges(changes);
3476
+ if (!this.firstChange) {
3477
+ if (changes.viewType && changes.viewType.currentValue) {
3478
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3479
+ this.computeTempDataRefs();
3480
+ }
3481
+ if (changes.originItems || changes.originGroups) {
3482
+ this.buildVirtualFlatData();
3483
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3484
+ this.computeTempDataRefs();
3485
+ }
3486
+ }
3047
3487
  }
3048
3488
  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);
3489
+ this.virtualScroll.renderedRangeStream.pipe(takeUntil(this.unsubscribe$)).subscribe((range) => {
3490
+ const linksElement = this.elementRef.nativeElement.querySelector('.gantt-links-overlay');
3491
+ linksElement.style.top = `${-(this.styles.lineHeight * range.start)}px`;
3492
+ this.rangeStart = range.start;
3493
+ this.rangeEnd = range.end;
3494
+ this.renderData = this.flatData.slice(range.start, range.end);
3495
+ this.computeTempDataRefs();
3496
+ });
3497
+ }
3498
+ buildVirtualFlatData() {
3499
+ const virtualData = [];
3500
+ if (this.groups.length) {
3501
+ this.groups.forEach((group) => {
3502
+ virtualData.push(group);
3503
+ if (group.expanded) {
3504
+ const items = recursiveItems(group.items);
3505
+ virtualData.push(...items);
3053
3506
  }
3054
3507
  });
3055
- this.cdr.detectChanges();
3508
+ }
3509
+ if (this.items.length) {
3510
+ virtualData.push(...recursiveItems(this.items));
3511
+ }
3512
+ this.flatData = [...virtualData];
3513
+ this.flatDataMap = keyBy(this.flatData, 'id');
3514
+ }
3515
+ afterExpand() {
3516
+ this.buildVirtualFlatData();
3517
+ this.renderData = this.flatData.slice(this.rangeStart, this.rangeEnd);
3518
+ }
3519
+ computeTempDataRefs() {
3520
+ const tempItemData = [];
3521
+ this.renderData.forEach((data) => {
3522
+ if (!data.hasOwnProperty('items')) {
3523
+ const item = data;
3524
+ if (item.links) {
3525
+ item.links.forEach((link) => {
3526
+ if (this.flatDataMap[link.link]) {
3527
+ tempItemData.push(this.flatDataMap[link.link]);
3528
+ }
3529
+ });
3530
+ }
3531
+ tempItemData.push(data);
3532
+ }
3056
3533
  });
3534
+ this.computeItemsRefs(...uniqBy(tempItemData, 'id'));
3535
+ this.flatData = [...this.flatData];
3536
+ this.renderData = [...this.renderData];
3057
3537
  }
3058
3538
  expandChildren(item) {
3059
3539
  if (!item.expanded) {
@@ -3063,6 +3543,7 @@ class NgxGanttComponent extends GanttUpper {
3063
3543
  this.childrenResolve(item.origin)
3064
3544
  .pipe(take(1), finalize(() => {
3065
3545
  item.loading = false;
3546
+ this.afterExpand();
3066
3547
  this.expandChange.emit(item);
3067
3548
  this.cdr.detectChanges();
3068
3549
  }))
@@ -3073,11 +3554,13 @@ class NgxGanttComponent extends GanttUpper {
3073
3554
  }
3074
3555
  else {
3075
3556
  this.computeItemsRefs(...item.children);
3557
+ this.afterExpand();
3076
3558
  this.expandChange.emit(item);
3077
3559
  }
3078
3560
  }
3079
3561
  else {
3080
3562
  item.setExpand(false);
3563
+ this.afterExpand();
3081
3564
  this.expandChange.emit(item);
3082
3565
  }
3083
3566
  }
@@ -3103,8 +3586,22 @@ class NgxGanttComponent extends GanttUpper {
3103
3586
  scrollToDate(date) {
3104
3587
  this.ganttRoot.scrollToDate(date);
3105
3588
  }
3589
+ expandGroups(expanded) {
3590
+ this.groups.forEach((group) => {
3591
+ group.setExpand(expanded);
3592
+ });
3593
+ this.afterExpand();
3594
+ this.expandChange.next(null);
3595
+ this.cdr.detectChanges();
3596
+ }
3597
+ expandGroup(group) {
3598
+ group.setExpand(!group.expanded);
3599
+ this.afterExpand();
3600
+ this.expandChange.emit();
3601
+ this.cdr.detectChanges();
3602
+ }
3106
3603
  }
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 });
3604
+ 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 });
3108
3605
  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: [
3109
3606
  {
3110
3607
  provide: GANTT_UPPER_TOKEN,
@@ -3114,7 +3611,7 @@ NgxGanttComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
3114
3611
  provide: GANTT_ABSTRACT_TOKEN,
3115
3612
  useExisting: forwardRef(() => NgxGanttComponent)
3116
3613
  }
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 });
3614
+ ], queries: [{ propertyName: "table", first: true, predicate: NgxGanttTableComponent, descendants: true }, { propertyName: "tableEmptyTemplate", first: true, predicate: ["tableEmpty"], descendants: true, static: true }, { propertyName: "columns", predicate: NgxGanttTableColumnComponent, descendants: true }], viewQueries: [{ propertyName: "ganttRoot", first: true, predicate: ["ganttRoot"], descendants: true }, { propertyName: "virtualScroll", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ngx-gantt-root #ganttRoot>\n <div class=\"gantt-header\">\n <gantt-table-header #tableHeader [columns]=\"columns\"></gantt-table-header>\n <div class=\"gantt-container-header\">\n <gantt-calendar-header></gantt-calendar-header>\n </div>\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"gantt-virtual-scroll-viewport\"\n [itemSize]=\"styles.lineHeight\"\n [minBufferPx]=\"styles.lineHeight * 10\"\n [maxBufferPx]=\"styles.lineHeight * 20\"\n >\n <ng-container *cdkVirtualFor=\"let item of flatData; trackBy: trackBy\"></ng-container>\n <div class=\"gantt-side\">\n <div class=\"gantt-side-container\">\n <div class=\"gantt-table\">\n <gantt-table-body\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n [draggable]=\"table.draggable\"\n [dropEnterPredicate]=\"table.dropEnterPredicate\"\n (dragDropped)=\"table.dragDropped.emit($event)\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table-body>\n </div>\n </div>\n </div>\n <div class=\"gantt-container\">\n <gantt-calendar-grid></gantt-calendar-grid>\n <div class=\"gantt-main\">\n <gantt-main\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n <gantt-drag-backdrop [style.left.px]=\"tableHeader.tableWidth + 1\"></gantt-drag-backdrop>\n</ngx-gantt-root>\n", dependencies: [{ kind: "directive", type: i2$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: GanttTableHeaderComponent, selector: "gantt-table-header", inputs: ["columns"] }, { kind: "component", type: GanttTableBodyComponent, selector: "gantt-table-body", inputs: ["renderData", "flatData", "columns", "groupTemplate", "emptyTemplate", "rowBeforeTemplate", "rowAfterTemplate", "draggable", "dropEnterPredicate"], outputs: ["dragDropped", "itemClick"] }, { kind: "component", type: GanttMainComponent, selector: "gantt-main", inputs: ["renderData", "flatData", "groupHeaderTemplate", "itemTemplate", "barTemplate", "rangeTemplate"], outputs: ["barClick", "lineClick"] }, { kind: "component", type: GanttCalendarHeaderComponent, selector: "gantt-calendar-header" }, { kind: "component", type: GanttCalendarGridComponent, selector: "gantt-calendar-grid" }, { kind: "component", type: GanttDragBackdropComponent, selector: "gantt-drag-backdrop" }, { kind: "component", type: NgxGanttRootComponent, selector: "ngx-gantt-root", inputs: ["sideWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3118
3615
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, decorators: [{
3119
3616
  type: Component,
3120
3617
  args: [{ selector: 'ngx-gantt', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
@@ -3126,8 +3623,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3126
3623
  provide: GANTT_ABSTRACT_TOKEN,
3127
3624
  useExisting: forwardRef(() => NgxGanttComponent)
3128
3625
  }
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: [{
3626
+ ], template: "<ngx-gantt-root #ganttRoot>\n <div class=\"gantt-header\">\n <gantt-table-header #tableHeader [columns]=\"columns\"></gantt-table-header>\n <div class=\"gantt-container-header\">\n <gantt-calendar-header></gantt-calendar-header>\n </div>\n </div>\n\n <cdk-virtual-scroll-viewport\n class=\"gantt-virtual-scroll-viewport\"\n [itemSize]=\"styles.lineHeight\"\n [minBufferPx]=\"styles.lineHeight * 10\"\n [maxBufferPx]=\"styles.lineHeight * 20\"\n >\n <ng-container *cdkVirtualFor=\"let item of flatData; trackBy: trackBy\"></ng-container>\n <div class=\"gantt-side\">\n <div class=\"gantt-side-container\">\n <div class=\"gantt-table\">\n <gantt-table-body\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [columns]=\"columns\"\n [groupTemplate]=\"groupTemplate\"\n [emptyTemplate]=\"tableEmptyTemplate\"\n [rowBeforeTemplate]=\"table?.rowBeforeTemplate\"\n [rowAfterTemplate]=\"table?.rowAfterTemplate\"\n [draggable]=\"table.draggable\"\n [dropEnterPredicate]=\"table.dropEnterPredicate\"\n (dragDropped)=\"table.dragDropped.emit($event)\"\n (itemClick)=\"selectItem($event)\"\n ></gantt-table-body>\n </div>\n </div>\n </div>\n <div class=\"gantt-container\">\n <gantt-calendar-grid></gantt-calendar-grid>\n <div class=\"gantt-main\">\n <gantt-main\n [flatData]=\"flatData\"\n [renderData]=\"renderData\"\n [groupHeaderTemplate]=\"groupHeaderTemplate\"\n [itemTemplate]=\"itemTemplate\"\n [barTemplate]=\"barTemplate\"\n [rangeTemplate]=\"rangeTemplate\"\n (barClick)=\"barClick.emit($event)\"\n (lineClick)=\"lineClick.emit($event)\"\n >\n </gantt-main>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n <gantt-drag-backdrop [style.left.px]=\"tableHeader.tableWidth + 1\"></gantt-drag-backdrop>\n</ngx-gantt-root>\n" }]
3627
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: GanttPrintService, decorators: [{
3628
+ type: Optional
3629
+ }] }, { type: undefined, decorators: [{
3131
3630
  type: Inject,
3132
3631
  args: [GANTT_GLOBAL_CONFIG]
3133
3632
  }] }]; }, propDecorators: { maxLevel: [{
@@ -3158,6 +3657,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3158
3657
  }], ganttRoot: [{
3159
3658
  type: ViewChild,
3160
3659
  args: ['ganttRoot']
3660
+ }], virtualScroll: [{
3661
+ type: ViewChild,
3662
+ args: [CdkVirtualScrollViewport]
3161
3663
  }] } });
3162
3664
 
3163
3665
  class NgxGanttModule {
@@ -3166,9 +3668,13 @@ NgxGanttModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
3166
3668
  NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, declarations: [NgxGanttComponent,
3167
3669
  NgxGanttTableComponent,
3168
3670
  NgxGanttTableColumnComponent,
3169
- GanttTableComponent,
3671
+ // GanttTableComponent,
3672
+ GanttTableHeaderComponent,
3673
+ GanttTableBodyComponent,
3170
3674
  GanttMainComponent,
3171
- GanttCalendarComponent,
3675
+ // GanttCalendarComponent,
3676
+ GanttCalendarHeaderComponent,
3677
+ GanttCalendarGridComponent,
3172
3678
  GanttLinksComponent,
3173
3679
  NgxGanttBarComponent,
3174
3680
  GanttIconComponent,
@@ -3179,7 +3685,7 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3179
3685
  NgxGanttToolbarComponent,
3180
3686
  IsGanttRangeItemPipe,
3181
3687
  IsGanttBarItemPipe,
3182
- IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule], exports: [NgxGanttComponent,
3688
+ IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule, ScrollingModule], exports: [NgxGanttComponent,
3183
3689
  NgxGanttTableComponent,
3184
3690
  NgxGanttTableColumnComponent,
3185
3691
  NgxGanttRootComponent,
@@ -3188,15 +3694,16 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3188
3694
  NgxGanttBaselineComponent,
3189
3695
  NgxGanttToolbarComponent] });
3190
3696
  NgxGanttModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, providers: [
3697
+ CdkVirtualScrollViewport,
3191
3698
  {
3192
3699
  provide: GANTT_GLOBAL_CONFIG,
3193
3700
  useValue: defaultConfig
3194
3701
  }
3195
- ], imports: [CommonModule, DragDropModule] });
3702
+ ], imports: [CommonModule, DragDropModule, ScrollingModule] });
3196
3703
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, decorators: [{
3197
3704
  type: NgModule,
3198
3705
  args: [{
3199
- imports: [CommonModule, DragDropModule],
3706
+ imports: [CommonModule, DragDropModule, ScrollingModule],
3200
3707
  exports: [
3201
3708
  NgxGanttComponent,
3202
3709
  NgxGanttTableComponent,
@@ -3211,9 +3718,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3211
3718
  NgxGanttComponent,
3212
3719
  NgxGanttTableComponent,
3213
3720
  NgxGanttTableColumnComponent,
3214
- GanttTableComponent,
3721
+ // GanttTableComponent,
3722
+ GanttTableHeaderComponent,
3723
+ GanttTableBodyComponent,
3215
3724
  GanttMainComponent,
3216
- GanttCalendarComponent,
3725
+ // GanttCalendarComponent,
3726
+ GanttCalendarHeaderComponent,
3727
+ GanttCalendarGridComponent,
3217
3728
  GanttLinksComponent,
3218
3729
  NgxGanttBarComponent,
3219
3730
  GanttIconComponent,
@@ -3227,6 +3738,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3227
3738
  IsGanttCustomItemPipe
3228
3739
  ],
3229
3740
  providers: [
3741
+ CdkVirtualScrollViewport,
3230
3742
  {
3231
3743
  provide: GANTT_GLOBAL_CONFIG,
3232
3744
  useValue: defaultConfig
@@ -3243,5 +3755,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3243
3755
  * Generated bundle index. Do not edit.
3244
3756
  */
3245
3757
 
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 };
3758
+ export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttBaselineItemInternal, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLinkLineType, GanttLinkType, GanttLoadOnScrollEvent, GanttPrintService, GanttSelectedEvent, GanttTableDragDroppedEvent, GanttTableDragEnterPredicateContext, GanttTableEvent, GanttUpper, GanttView, GanttViewType, IsGanttBarItemPipe, IsGanttCustomItemPipe, IsGanttRangeItemPipe, LinkColors, NgxGanttBarComponent, NgxGanttBaselineComponent, NgxGanttComponent, NgxGanttModule, NgxGanttRangeComponent, NgxGanttRootComponent, NgxGanttTableColumnComponent, NgxGanttTableComponent, NgxGanttToolbarComponent, defaultConfig, ganttViews, primaryDatePointTop, registerView, secondaryDatePointTop };
3247
3759
  //# sourceMappingURL=worktile-gantt.mjs.map