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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/class/event.d.ts +13 -0
  2. package/class/item.d.ts +7 -1
  3. package/components/bar/bar-drag.d.ts +10 -0
  4. package/components/bar/bar.component.d.ts +2 -1
  5. package/components/bar/bar.component.scss +22 -0
  6. package/components/calendar/calendar.scss +91 -0
  7. package/components/calendar/grid/calendar-grid.component.d.ts +24 -0
  8. package/components/calendar/header/calendar-header.component.d.ts +21 -0
  9. package/components/icon/icons.d.ts +1 -0
  10. package/components/links/links.component.d.ts +5 -5
  11. package/components/main/gantt-main.component.d.ts +3 -3
  12. package/components/table/body/gantt-table-body.component.d.ts +58 -0
  13. package/components/table/gantt-table.component.scss +169 -85
  14. package/components/table/gantt-table.scss +271 -0
  15. package/components/table/header/gantt-table-header.component.d.ts +31 -0
  16. package/esm2020/class/event.mjs +5 -1
  17. package/esm2020/class/item.mjs +9 -4
  18. package/esm2020/components/bar/bar-drag.mjs +106 -42
  19. package/esm2020/components/bar/bar.component.mjs +8 -2
  20. package/esm2020/components/calendar/grid/calendar-grid.component.mjs +71 -0
  21. package/esm2020/components/calendar/header/calendar-header.component.mjs +67 -0
  22. package/esm2020/components/icon/icons.mjs +4 -2
  23. package/esm2020/components/links/links.component.mjs +72 -54
  24. package/esm2020/components/main/gantt-main.component.mjs +5 -5
  25. package/esm2020/components/table/body/gantt-table-body.component.mjs +286 -0
  26. package/esm2020/components/table/header/gantt-table-header.component.mjs +140 -0
  27. package/esm2020/gantt-dom.service.mjs +8 -12
  28. package/esm2020/gantt-item-upper.mjs +15 -6
  29. package/esm2020/gantt-print.service.mjs +2 -2
  30. package/esm2020/gantt-upper.mjs +18 -15
  31. package/esm2020/gantt.component.mjs +114 -24
  32. package/esm2020/gantt.module.mjs +25 -10
  33. package/esm2020/root.component.mjs +10 -8
  34. package/esm2020/table/gantt-column.component.mjs +4 -2
  35. package/esm2020/table/gantt-table.component.mjs +12 -4
  36. package/esm2020/utils/helpers.mjs +11 -1
  37. package/fesm2015/worktile-gantt.mjs +903 -373
  38. package/fesm2015/worktile-gantt.mjs.map +1 -1
  39. package/fesm2020/worktile-gantt.mjs +894 -375
  40. package/fesm2020/worktile-gantt.mjs.map +1 -1
  41. package/gantt-dom.service.d.ts +1 -0
  42. package/gantt-item-upper.d.ts +3 -2
  43. package/gantt-upper.d.ts +4 -1
  44. package/gantt.component.d.ts +20 -7
  45. package/gantt.component.scss +35 -0
  46. package/gantt.module.d.ts +18 -15
  47. package/package.json +1 -1
  48. package/root.component.d.ts +1 -1
  49. package/styles/index.scss +4 -2
  50. package/styles/variables.scss +9 -7
  51. package/table/gantt-column.component.d.ts +2 -1
  52. package/table/gantt-table.component.d.ts +5 -2
  53. package/components/calendar/calendar.component.d.ts +0 -26
  54. package/components/table/gantt-table.component.d.ts +0 -41
  55. package/esm2020/components/calendar/calendar.component.mjs +0 -88
  56. package/esm2020/components/table/gantt-table.component.mjs +0 -161
@@ -1,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
  }
@@ -1218,7 +1242,7 @@ class NgxGanttTableColumnComponent {
1218
1242
  }
1219
1243
  }
1220
1244
  NgxGanttTableColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableColumnComponent, deps: [{ token: GANTT_UPPER_TOKEN }], target: i0.ɵɵFactoryTarget.Component });
1221
- NgxGanttTableColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableColumnComponent, selector: "ngx-gantt-column", inputs: { width: "width", name: "name" }, queries: [{ propertyName: "templateRef", first: true, predicate: ["cell"], descendants: true, static: true }, { propertyName: "headerTemplateRef", first: true, predicate: ["header"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1245
+ NgxGanttTableColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: NgxGanttTableColumnComponent, selector: "ngx-gantt-column", inputs: { width: "width", name: "name", showExpandIcon: "showExpandIcon" }, queries: [{ propertyName: "templateRef", first: true, predicate: ["cell"], descendants: true, static: true }, { propertyName: "headerTemplateRef", first: true, predicate: ["header"], descendants: true, static: true }], ngImport: i0, template: '', isInline: true });
1222
1246
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableColumnComponent, decorators: [{
1223
1247
  type: Component,
1224
1248
  args: [{
@@ -1232,6 +1256,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1232
1256
  type: Input
1233
1257
  }], name: [{
1234
1258
  type: Input
1259
+ }], showExpandIcon: [{
1260
+ type: Input
1235
1261
  }], templateRef: [{
1236
1262
  type: ContentChild,
1237
1263
  args: ['cell', { static: true }]
@@ -1242,18 +1268,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1242
1268
 
1243
1269
  class NgxGanttTableComponent {
1244
1270
  constructor() {
1271
+ this.draggable = false;
1272
+ this.dragDropped = new EventEmitter();
1245
1273
  this.columnChanges = new EventEmitter();
1246
1274
  }
1247
1275
  }
1248
1276
  NgxGanttTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1249
- 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 });
1250
1278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttTableComponent, decorators: [{
1251
1279
  type: Component,
1252
1280
  args: [{
1253
1281
  selector: 'ngx-gantt-table',
1254
1282
  template: ''
1255
1283
  }]
1256
- }], propDecorators: { columnChanges: [{
1284
+ }], propDecorators: { draggable: [{
1285
+ type: Input
1286
+ }], dropEnterPredicate: [{
1287
+ type: Input
1288
+ }], dragDropped: [{
1289
+ type: Output
1290
+ }], columnChanges: [{
1257
1291
  type: Output
1258
1292
  }], rowBeforeTemplate: [{
1259
1293
  type: ContentChild,
@@ -1265,6 +1299,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1265
1299
 
1266
1300
  const GANTT_ABSTRACT_TOKEN = new InjectionToken('gantt-abstract-token');
1267
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
+
1268
1394
  const supports = (typeof window !== 'undefined' && !!window.CSS && CSS.supports) || (() => false);
1269
1395
  /**
1270
1396
  * Note: we don't need to add vendor prefixes within `.scss` files since they're added automatically.
@@ -1280,6 +1406,138 @@ function setStyleWithVendorPrefix({ element, style, value }) {
1280
1406
  }
1281
1407
  }
1282
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
+
1283
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>`;
1284
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>`;
1285
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>`;
@@ -1358,13 +1616,15 @@ xmlns:xlink="http://www.w3.org/1999/xlink"
1358
1616
  </g>
1359
1617
  </g>
1360
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>`;
1361
1620
  const icons = {
1362
1621
  'angle-right': angleRight,
1363
1622
  'angle-down': angleDown,
1364
1623
  'plus-square': plusSquare,
1365
1624
  'minus-square': minusSquare,
1366
1625
  loading: loadingIcon,
1367
- empty: emptyIcon
1626
+ empty: emptyIcon,
1627
+ drag: dragIcon
1368
1628
  };
1369
1629
 
1370
1630
  class GanttIconComponent {
@@ -1440,41 +1700,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1440
1700
  }]
1441
1701
  }] });
1442
1702
 
1443
- const defaultColumnWidth = 100;
1444
- const minColumnWidth = 80;
1445
- class GanttTableComponent {
1446
- set columns(columns) {
1447
- columns.forEach((column) => {
1448
- if (!column.columnWidth) {
1449
- column.columnWidth = coerceCssPixelValue(defaultColumnWidth);
1450
- }
1451
- });
1452
- 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;
1453
1714
  }
1454
- constructor(gantt, ganttUpper, elementRef) {
1715
+ constructor(gantt, ganttUpper, cdr, document) {
1455
1716
  this.gantt = gantt;
1456
1717
  this.ganttUpper = ganttUpper;
1457
- this.elementRef = elementRef;
1718
+ this.cdr = cdr;
1719
+ this.document = document;
1720
+ this.draggable = false;
1721
+ this.dragDropped = new EventEmitter();
1458
1722
  this.itemClick = new EventEmitter();
1459
1723
  this.ganttTableClass = true;
1460
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();
1461
1731
  }
1462
- ngOnChanges(changes) {
1463
- if (!changes.groups.currentValue?.length && !changes.items.currentValue?.length) {
1464
- this.ganttTableEmptyClass = true;
1465
- }
1466
- else {
1467
- this.ganttTableEmptyClass = false;
1468
- }
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
+ });
1469
1745
  }
1470
- dragFixed(config) {
1471
- if (config.movedWidth < config.minWidth) {
1472
- setStyleWithVendorPrefix({
1473
- element: config.target,
1474
- style: 'transform',
1475
- 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
+ }
1476
1756
  });
1477
- }
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
+ });
1478
1765
  }
1479
1766
  expandGroup(group) {
1480
1767
  this.gantt.expandGroup(group);
@@ -1483,89 +1770,172 @@ class GanttTableComponent {
1483
1770
  event.stopPropagation();
1484
1771
  this.gantt.expandChildren(item);
1485
1772
  }
1486
- dragStarted(event) {
1487
- const target = event.source.element.nativeElement;
1488
- 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
+ });
1489
1780
  }
1490
- dragMoved(event, column) {
1491
- const target = event.source.element.nativeElement;
1492
- const left = target.getBoundingClientRect().left;
1493
- let originWidth;
1494
- let movedWidth;
1495
- let minWidth;
1496
- if (column) {
1497
- originWidth = parseInt(column.columnWidth, 10);
1498
- movedWidth = originWidth + (left - this.dragStartLeft);
1499
- 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;
1500
1790
  }
1501
- else {
1502
- originWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1503
- movedWidth = originWidth + (left - this.dragStartLeft);
1504
- 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;
1505
1797
  }
1506
- this.dragFixed({
1507
- target,
1508
- originWidth,
1509
- movedWidth,
1510
- 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
1511
1849
  });
1512
- this.showAuxiliaryLine(event);
1850
+ this.cleanupDragArtifacts(true);
1513
1851
  }
1514
- columnDragEnded(event, column) {
1515
- const target = event.source.element.nativeElement;
1516
- const left = target.getBoundingClientRect().left;
1517
- const width = parseInt(column.columnWidth, 10) + (left - this.dragStartLeft);
1518
- const columnWidth = Math.max(width || 0, minColumnWidth);
1519
- column.columnWidth = coerceCssPixelValue(columnWidth);
1520
- if (this.gantt.table) {
1521
- 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);
1522
1872
  }
1523
- this.hideAuxiliaryLine();
1524
- event.source.reset();
1873
+ target.children.push(inserted);
1525
1874
  }
1526
- tableDragEnded(event) {
1527
- const target = event.source.element.nativeElement;
1528
- const left = target.getBoundingClientRect().left;
1529
- const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width;
1530
- const dragWidth = left - this.dragStartLeft;
1531
- this.columnList.forEach((column) => {
1532
- const lastColumnWidth = parseInt(column.columnWidth, 10);
1533
- const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10);
1534
- const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth);
1535
- column.columnWidth = coerceCssPixelValue(columnWidth);
1875
+ getParentByItem(item) {
1876
+ return (this.flatData || []).find((n) => {
1877
+ return n.children?.includes(item);
1536
1878
  });
1537
- if (this.gantt.table) {
1538
- 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);
1539
1889
  }
1540
- this.hideAuxiliaryLine();
1541
- event.source.reset();
1890
+ return children;
1542
1891
  }
1543
- showAuxiliaryLine(event) {
1544
- const tableRect = this.elementRef.nativeElement.getBoundingClientRect();
1545
- this.draglineElementRef.nativeElement.style.left = `${event.event.clientX - tableRect.left}px`;
1546
- 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
+ }
1547
1905
  }
1548
- hideAuxiliaryLine() {
1549
- 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
+ }
1550
1911
  }
1551
- trackBy(index, item) {
1552
- 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'));
1553
1920
  }
1554
1921
  }
1555
- 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 });
1556
- GanttTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: GanttTableComponent, selector: "gantt-table", inputs: { groups: "groups", items: "items", columns: "columns", groupTemplate: "groupTemplate", emptyTemplate: "emptyTemplate", rowBeforeTemplate: "rowBeforeTemplate", rowAfterTemplate: "rowAfterTemplate" }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.gantt-table": "this.ganttTableClass", "class.gantt-table-empty": "this.ganttTableEmptyClass" } }, viewQueries: [{ propertyName: "draglineElementRef", first: true, predicate: ["dragLine"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"gantt-table-header gantt-table-row\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"></ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event, column)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"columnDragEnded($event, column)\"\n ></div>\n </div>\n</div>\n<div class=\"gantt-table-body\">\n <ng-container *ngIf=\"!groups.length && !items.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"groups && groups.length > 0; else itemsTemplate\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"group.class\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"group.expanded\" (click)=\"expandGroup(group)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"group.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: group.origin, group: group.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ group.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <ng-container *ngIf=\"group.expanded\">\n <ng-template\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ group: group, items: group.items, level: 0 }\"\n ></ng-template>\n </ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"tableDragEnded($event)\"\n></div>\n\n<div #dragLine class=\"gantt-table-drag-auxiliary-line\"></div>\n\n<ng-template #itemsTemplate>\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items, level: 0 }\"></ng-template>\n</ng-template>\n\n<ng-template #ganttItems let-group=\"group\" let-items=\"items\" let-level=\"level\">\n <ng-container *ngFor=\"let item of items; trackBy: trackBy\">\n <div\n (click)=\"itemClick.emit({ event: $event, selectedValue: this.item.origin })\"\n class=\"gantt-table-item gantt-table-row\"\n [class.gantt-table-item-first-level-group]=\"level === 0 && (item.type | isGanttRangeItem)\"\n [class.gantt-table-item-with-group]=\"group\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let first = first\" [style.width]=\"column.columnWidth\">\n <div *ngIf=\"first\" class=\"gantt-expand-icon\" [style.marginLeft.px]=\"level * 20\">\n <ng-container *ngIf=\"level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n ></gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children, level: level + 1, group: group }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: GanttIconComponent, selector: "gantt-icon", inputs: ["iconName"] }, { kind: "pipe", type: IsGanttRangeItemPipe, name: "isGanttRangeItem" }] });
1557
- 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: [{
1558
1925
  type: Component,
1559
- args: [{ selector: 'gantt-table', template: "<div class=\"gantt-table-header gantt-table-row\">\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let i = index\" [style.width]=\"column.columnWidth\">\n <ng-container *ngIf=\"column.headerTemplateRef; else default\" [ngTemplateOutlet]=\"column.headerTemplateRef\"></ng-container>\n <ng-template #default>\n {{ column.name }}\n </ng-template>\n <div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event, column)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"columnDragEnded($event, column)\"\n ></div>\n </div>\n</div>\n<div class=\"gantt-table-body\">\n <ng-container *ngIf=\"!groups.length && !items.length\">\n <ng-container *ngIf=\"!emptyTemplate\">\n <gantt-icon class=\"empty-icon\" iconName=\"empty\"></gantt-icon>\n <div class=\"empty-text\">\u6CA1\u6709\u6570\u636E</div>\n </ng-container>\n <ng-template [ngTemplateOutlet]=\"emptyTemplate\"></ng-template>\n </ng-container>\n\n <ng-container *ngIf=\"groups && groups.length > 0; else itemsTemplate\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackBy\">\n <div class=\"gantt-table-group\" [ngClass]=\"group.class\">\n <div class=\"gantt-table-group-title\" [class.expanded]=\"group.expanded\" (click)=\"expandGroup(group)\">\n <gantt-icon class=\"expand-icon\" [iconName]=\"group.expanded ? 'angle-down' : 'angle-right'\"></gantt-icon>\n <ng-container *ngIf=\"groupTemplate; else default\">\n <ng-template\n [ngTemplateOutlet]=\"groupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: group.origin, group: group.origin }\"\n ></ng-template>\n </ng-container>\n <ng-template #default>\n <span class=\"group-title\">{{ group.title }}</span>\n </ng-template>\n </div>\n </div>\n\n <ng-container *ngIf=\"group.expanded\">\n <ng-template\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ group: group, items: group.items, level: 0 }\"\n ></ng-template>\n </ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<div\n class=\"gantt-table-drag-trigger\"\n cdkDrag\n cdkDragLockAxis=\"x\"\n cdkDragBoundary=\".gantt\"\n (cdkDragMoved)=\"dragMoved($event)\"\n (cdkDragStarted)=\"dragStarted($event)\"\n (cdkDragEnded)=\"tableDragEnded($event)\"\n></div>\n\n<div #dragLine class=\"gantt-table-drag-auxiliary-line\"></div>\n\n<ng-template #itemsTemplate>\n <ng-template [ngTemplateOutlet]=\"ganttItems\" [ngTemplateOutletContext]=\"{ items: items, level: 0 }\"></ng-template>\n</ng-template>\n\n<ng-template #ganttItems let-group=\"group\" let-items=\"items\" let-level=\"level\">\n <ng-container *ngFor=\"let item of items; trackBy: trackBy\">\n <div\n (click)=\"itemClick.emit({ event: $event, selectedValue: this.item.origin })\"\n class=\"gantt-table-item gantt-table-row\"\n [class.gantt-table-item-first-level-group]=\"level === 0 && (item.type | isGanttRangeItem)\"\n [class.gantt-table-item-with-group]=\"group\"\n [class.gantt-table-item-active]=\"ganttUpper.isSelected(item.id)\"\n [style.height.px]=\"gantt.styles.lineHeight\"\n [style.lineHeight.px]=\"gantt.styles.lineHeight\"\n >\n <ng-template\n [ngTemplateOutlet]=\"rowBeforeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n <div class=\"gantt-table-column\" *ngFor=\"let column of columnList; let first = first\" [style.width]=\"column.columnWidth\">\n <div *ngIf=\"first\" class=\"gantt-expand-icon\" [style.marginLeft.px]=\"level * 20\">\n <ng-container *ngIf=\"level < gantt.maxLevel - 1 && item.expandable\">\n <gantt-icon\n *ngIf=\"!item.loading\"\n class=\"expand-icon\"\n [iconName]=\"item.expanded ? 'angle-down' : 'angle-right'\"\n (click)=\"expandChildren($event, item)\"\n ></gantt-icon>\n <gantt-icon *ngIf=\"item.loading\" [iconName]=\"'loading'\"></gantt-icon>\n </ng-container>\n </div>\n <div class=\"gantt-table-column-content\">\n <ng-template\n [ngTemplateOutlet]=\"column.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n </div>\n <ng-template\n [ngTemplateOutlet]=\"rowAfterTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.origin, item: item.origin }\"\n ></ng-template>\n </div>\n <ng-template\n *ngIf=\"item.children && item.expanded\"\n [ngTemplateOutlet]=\"ganttItems\"\n [ngTemplateOutletContext]=\"{ items: item.children, level: level + 1, group: group }\"\n ></ng-template>\n </ng-container>\n</ng-template>\n" }]
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" }]
1560
1927
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1561
1928
  type: Inject,
1562
1929
  args: [GANTT_ABSTRACT_TOKEN]
1563
1930
  }] }, { type: GanttUpper, decorators: [{
1564
1931
  type: Inject,
1565
1932
  args: [GANTT_UPPER_TOKEN]
1566
- }] }, { type: i0.ElementRef }]; }, propDecorators: { groups: [{
1933
+ }] }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
1934
+ type: Inject,
1935
+ args: [DOCUMENT]
1936
+ }] }]; }, propDecorators: { renderData: [{
1567
1937
  type: Input
1568
- }], items: [{
1938
+ }], flatData: [{
1569
1939
  type: Input
1570
1940
  }], columns: [{
1571
1941
  type: Input
@@ -1577,17 +1947,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1577
1947
  type: Input
1578
1948
  }], rowAfterTemplate: [{
1579
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
1580
1959
  }], itemClick: [{
1581
1960
  type: Output
1582
- }], draglineElementRef: [{
1583
- type: ViewChild,
1584
- args: ['dragLine', { static: true }]
1585
1961
  }], ganttTableClass: [{
1586
1962
  type: HostBinding,
1587
- args: ['class.gantt-table']
1963
+ args: ['class.gantt-table-body']
1588
1964
  }], ganttTableEmptyClass: [{
1589
1965
  type: HostBinding,
1590
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)]
1591
1973
  }] } });
1592
1974
 
1593
1975
  class GanttLinkLine {
@@ -1843,13 +2225,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1843
2225
  }] }]; } });
1844
2226
 
1845
2227
  class GanttLinksComponent {
1846
- constructor(ganttUpper, cdr, elementRef, ganttDragContainer) {
2228
+ constructor(ganttUpper, cdr, elementRef, ganttDragContainer, ngZone) {
1847
2229
  this.ganttUpper = ganttUpper;
1848
2230
  this.cdr = cdr;
1849
2231
  this.elementRef = elementRef;
1850
2232
  this.ganttDragContainer = ganttDragContainer;
1851
- this.groups = [];
1852
- this.items = [];
2233
+ this.ngZone = ngZone;
2234
+ // @Input() groups: GanttGroupInternal[] = [];
2235
+ // @Input() items: GanttItemInternal[] = [];
2236
+ this.flatData = [];
1853
2237
  this.lineClick = new EventEmitter();
1854
2238
  this.links = [];
1855
2239
  this.ganttLinkTypes = GanttLinkType;
@@ -1862,13 +2246,14 @@ class GanttLinksComponent {
1862
2246
  ngOnInit() {
1863
2247
  this.linkLine = createLineGenerator(this.ganttUpper.linkOptions.lineType, this.ganttUpper);
1864
2248
  this.showArrow = this.ganttUpper.linkOptions.showArrow;
1865
- this.buildLinks();
2249
+ // this.buildLinks();
1866
2250
  this.firstChange = false;
2251
+ this.buildLinks();
1867
2252
  this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
1868
2253
  this.elementRef.nativeElement.style.visibility = 'hidden';
1869
2254
  });
1870
- merge(this.ganttUpper.viewChange, this.ganttUpper.expandChange, this.ganttUpper.view.start$, this.ganttUpper.dragEnded, this.ganttUpper.linkDragEnded)
1871
- .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$))
1872
2257
  .subscribe(() => {
1873
2258
  this.elementRef.nativeElement.style.visibility = 'visible';
1874
2259
  this.buildLinks();
@@ -1884,48 +2269,66 @@ class GanttLinksComponent {
1884
2269
  const lineHeight = this.ganttUpper.styles.lineHeight;
1885
2270
  const barHeight = this.ganttUpper.styles.barHeight;
1886
2271
  this.linkItems = [];
1887
- if (this.groups.length > 0) {
1888
- let itemNum = 0;
1889
- let groupNum = 0;
1890
- this.groups.forEach((group) => {
1891
- groupNum++;
1892
- if (group.expanded) {
1893
- const items = recursiveItems(group.items);
1894
- items.forEach((item, itemIndex) => {
1895
- const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
1896
- this.linkItems.push({
1897
- ...item,
1898
- before: {
1899
- x: item.refs.x,
1900
- y
1901
- },
1902
- after: {
1903
- x: item.refs.x + item.refs.width,
1904
- y
1905
- }
1906
- });
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
+ }
1907
2328
  });
1908
- itemNum += items.length;
1909
2329
  }
1910
- });
1911
- }
1912
- else {
1913
- const items = recursiveItems(this.items);
1914
- items.forEach((item, itemIndex) => {
1915
- const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
1916
- this.linkItems.push({
1917
- ...item,
1918
- before: {
1919
- x: item.refs.x,
1920
- y
1921
- },
1922
- after: {
1923
- x: item.refs.x + item.refs.width,
1924
- y
1925
- }
1926
- });
1927
- });
1928
- }
2330
+ }
2331
+ });
1929
2332
  }
1930
2333
  buildLinks() {
1931
2334
  this.computeItemPosition();
@@ -1990,17 +2393,15 @@ class GanttLinksComponent {
1990
2393
  this.unsubscribe$.complete();
1991
2394
  }
1992
2395
  }
1993
- 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 });
1994
- 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"] }] });
1995
2398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttLinksComponent, decorators: [{
1996
2399
  type: Component,
1997
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" }]
1998
2401
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
1999
2402
  type: Inject,
2000
2403
  args: [GANTT_UPPER_TOKEN]
2001
- }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }]; }, propDecorators: { groups: [{
2002
- type: Input
2003
- }], items: [{
2404
+ }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: GanttDragContainer }, { type: i0.NgZone }]; }, propDecorators: { flatData: [{
2004
2405
  type: Input
2005
2406
  }], lineClick: [{
2006
2407
  type: Output
@@ -2058,18 +2459,10 @@ class GanttDomService {
2058
2459
  .subscribe((event) => {
2059
2460
  this.syncScroll(event);
2060
2461
  }));
2061
- // fromEvent(this.mainContainer, 'scroll')
2062
- // .pipe(startWith(), takeUntil(this.unsubscribe$))
2063
- // .subscribe((event) => {
2064
- // // if (this.mainContainer.scrollLeft > 0) {
2065
- // // this.side.classList.add('gantt-side-has-shadow');
2066
- // // } else {
2067
- // // this.side.classList.remove('gantt-side-has-shadow');
2068
- // // }
2069
- // });
2070
2462
  }
2071
2463
  syncScroll(event) {
2072
2464
  const target = event.currentTarget;
2465
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2073
2466
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2074
2467
  this.sideContainer.scrollTop = target.scrollTop;
2075
2468
  this.mainContainer.scrollTop = target.scrollTop;
@@ -2095,8 +2488,11 @@ class GanttDomService {
2095
2488
  this.container = this.root.getElementsByClassName('gantt-container')[0];
2096
2489
  this.sideContainer = this.root.getElementsByClassName('gantt-side-container')[0];
2097
2490
  this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0];
2098
- this.mainItems = this.root.getElementsByClassName('gantt-main-items')[0];
2099
- 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];
2100
2496
  this.monitorScrollChange();
2101
2497
  this.disableBrowserWheelEvent();
2102
2498
  }
@@ -2133,6 +2529,7 @@ class GanttDomService {
2133
2529
  if (isNumber(left)) {
2134
2530
  const scrollLeft = left - this.mainContainer.clientWidth / 2;
2135
2531
  this.mainContainer.scrollLeft = scrollLeft > scrollThreshold ? scrollLeft : 0;
2532
+ this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft;
2136
2533
  this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft;
2137
2534
  }
2138
2535
  }
@@ -2161,100 +2558,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2161
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" }]
2162
2559
  }] });
2163
2560
 
2164
- class GanttPrintService {
2165
- constructor() { }
2166
- setInlineStyles(targetElem) {
2167
- const svgElements = Array.from(targetElem.getElementsByTagName('svg'));
2168
- for (const svgElement of svgElements) {
2169
- this.recursElementChildren(svgElement);
2170
- }
2561
+ class GanttCalendarHeaderComponent {
2562
+ get view() {
2563
+ return this.ganttUpper.view;
2171
2564
  }
2172
- recursElementChildren(node) {
2173
- const transformProperties = [
2174
- 'fill',
2175
- 'color',
2176
- 'font-size',
2177
- 'stroke',
2178
- 'font',
2179
- 'text-anchor',
2180
- 'stroke-dasharray',
2181
- 'shape-rendering',
2182
- 'stroke-width'
2183
- ];
2184
- if (!node.style) {
2185
- return;
2186
- }
2187
- const styles = getComputedStyle(node);
2188
- for (const transformProperty of transformProperties) {
2189
- node.style[transformProperty] = styles[transformProperty];
2190
- }
2191
- for (const child of Array.from(node.childNodes)) {
2192
- this.recursElementChildren(child);
2193
- }
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`;
2194
2573
  }
2195
- register(root) {
2196
- this.root = root.nativeElement;
2197
- 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
+ });
2198
2583
  }
2199
- async print(name = 'download', ignoreElementClass) {
2200
- const root = this.root;
2201
- const mainContainer = this.mainContainer;
2202
- // set print width
2203
- const printWidth = root.offsetWidth;
2204
- // set print height
2205
- const printHeight = root.offsetHeight - mainContainer.offsetHeight + mainContainer.scrollHeight;
2206
- const html2canvas = (await import(/* webpackChunkName: 'html2canvas' */ 'html2canvas')).default;
2207
- html2canvas(root, {
2208
- logging: false,
2209
- allowTaint: true,
2210
- useCORS: true,
2211
- width: printWidth,
2212
- height: printHeight,
2213
- ignoreElements: (element) => {
2214
- if (ignoreElementClass && element.classList.contains(ignoreElementClass)) {
2215
- return true;
2216
- }
2217
- if (element.classList.contains('gantt-calendar-today-overlay')) {
2218
- return true;
2219
- }
2220
- },
2221
- onclone: (cloneDocument) => {
2222
- const ganttClass = root.className;
2223
- const cloneGanttDom = cloneDocument.querySelector(`.${ganttClass.replace(/\s+/g, '.')}`);
2224
- const cloneGanttContainerDom = cloneDocument.querySelector('.gantt-container');
2225
- const cloneCalendarOverlay = cloneDocument.querySelector('.gantt-calendar-overlay-main');
2226
- const cloneLinksOverlay = cloneDocument.querySelector('.gantt-links-overlay-main');
2227
- // change targetDom width
2228
- cloneGanttDom.style.width = `${printWidth}px`;
2229
- cloneGanttDom.style.height = `${printHeight}px`;
2230
- cloneGanttDom.style.overflow = `unset`;
2231
- cloneGanttContainerDom.style.backgroundColor = '#fff';
2232
- cloneCalendarOverlay.setAttribute('height', `${printHeight}`);
2233
- cloneCalendarOverlay.setAttribute('style', `background: transparent`);
2234
- if (cloneLinksOverlay) {
2235
- cloneLinksOverlay.setAttribute('height', `${printHeight}`);
2236
- cloneLinksOverlay.setAttribute('style', `height: ${printHeight}px`);
2237
- }
2238
- // setInlineStyles for svg
2239
- 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();
2240
2594
  }
2241
- }).then((canvas) => {
2242
- const link = document.createElement('a');
2243
- const dataUrl = canvas.toDataURL('image/png');
2244
- link.download = `${name}.png`;
2245
- link.href = dataUrl;
2246
- link.click();
2247
- });
2595
+ }
2596
+ else {
2597
+ todayEle.style.display = 'none';
2598
+ }
2599
+ }
2600
+ trackBy(point, index) {
2601
+ return point.text || index;
2248
2602
  }
2249
2603
  }
2250
- GanttPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2251
- GanttPrintServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService });
2252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttPrintService, decorators: [{
2253
- type: Injectable
2254
- }], 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
+ }] } });
2255
2616
 
2256
2617
  const mainHeight = 5000;
2257
- class GanttCalendarComponent {
2618
+ class GanttCalendarGridComponent {
2258
2619
  get view() {
2259
2620
  return this.ganttUpper.view;
2260
2621
  }
@@ -2262,30 +2623,21 @@ class GanttCalendarComponent {
2262
2623
  this.ganttUpper = ganttUpper;
2263
2624
  this.ngZone = ngZone;
2264
2625
  this.elementRef = elementRef;
2626
+ this.unsubscribe$ = new Subject();
2265
2627
  this.headerHeight = headerHeight;
2266
2628
  this.mainHeight = mainHeight;
2267
- this.todayHeight = todayHeight;
2268
- this.todayWidth = todayWidth;
2269
2629
  this.todayBorderRadius = todayBorderRadius;
2270
2630
  this.viewTypes = GanttViewType;
2271
- this.className = true;
2272
- this.unsubscribe$ = new Subject();
2631
+ this.className = `gantt-calendar gantt-calendar-grid`;
2273
2632
  }
2274
2633
  setTodayPoint() {
2275
2634
  const x = this.view.getTodayXPoint();
2276
- const today = new GanttDate().getDate();
2277
2635
  const todayEle = this.elementRef.nativeElement.getElementsByClassName('gantt-calendar-today-overlay')[0];
2278
- const rect = this.elementRef.nativeElement.getElementsByClassName('today-rect')[0];
2279
2636
  const line = this.elementRef.nativeElement.getElementsByClassName('today-line')[0];
2280
2637
  if (isNumber(x)) {
2281
- if (rect) {
2282
- rect.style.left = `${x - todayWidth / 2}px`;
2283
- rect.style.top = `${headerHeight - todayHeight}px`;
2284
- rect.innerHTML = today.toString();
2285
- }
2286
2638
  if (line) {
2287
2639
  line.style.left = `${x}px`;
2288
- line.style.top = `${headerHeight}px`;
2640
+ line.style.top = `0px`;
2289
2641
  line.style.bottom = `${-mainHeight}px`;
2290
2642
  }
2291
2643
  }
@@ -2294,22 +2646,15 @@ class GanttCalendarComponent {
2294
2646
  }
2295
2647
  }
2296
2648
  ngOnInit() {
2297
- // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2298
- // the `onStable` will never emit any value.
2299
- const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
2300
- // Normally this isn't in the zone, but it can cause performance regressions for apps
2301
- // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
2302
- this.ngZone.runOutsideAngular(() => {
2303
- onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
2304
- merge(this.ganttUpper.viewChange, this.ganttUpper.view.start$)
2305
- .pipe(takeUntil(this.unsubscribe$))
2306
- .subscribe(() => {
2307
- this.setTodayPoint();
2308
- });
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();
2309
2654
  });
2310
2655
  });
2311
2656
  }
2312
- trackBy(index, point) {
2657
+ trackBy(point, index) {
2313
2658
  return point.text || index;
2314
2659
  }
2315
2660
  ngOnDestroy() {
@@ -2317,17 +2662,17 @@ class GanttCalendarComponent {
2317
2662
  this.unsubscribe$.complete();
2318
2663
  }
2319
2664
  }
2320
- 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 });
2321
- 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"] }] });
2322
- 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: [{
2323
2668
  type: Component,
2324
- 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" }]
2325
2670
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2326
2671
  type: Inject,
2327
2672
  args: [GANTT_UPPER_TOKEN]
2328
2673
  }] }, { type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { className: [{
2329
2674
  type: HostBinding,
2330
- args: ['class.gantt-calendar-overlay']
2675
+ args: ['class']
2331
2676
  }] } });
2332
2677
 
2333
2678
  class NgxGanttToolbarComponent {
@@ -2386,7 +2731,7 @@ class NgxGanttRootComponent {
2386
2731
  this.setupViewScroll();
2387
2732
  // 优化初始化时Scroll滚动体验问题,通过透明度解决,默认透明度为0,滚动结束后恢复
2388
2733
  this.elementRef.nativeElement.style.opacity = '1';
2389
- this.ganttUpper.viewChange.pipe(startWith(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2734
+ this.ganttUpper.viewChange.pipe(startWith$1(null), takeUntil(this.unsubscribe$)).subscribe(() => {
2390
2735
  this.scrollToToday();
2391
2736
  });
2392
2737
  });
@@ -2455,12 +2800,12 @@ class NgxGanttRootComponent {
2455
2800
  }
2456
2801
  }
2457
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 });
2458
- 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"] }] });
2459
2804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttRootComponent, decorators: [{
2460
2805
  type: Component,
2461
2806
  args: [{ selector: 'ngx-gantt-root', providers: [GanttDomService, GanttDragContainer], host: {
2462
2807
  class: 'gantt'
2463
- }, 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" }]
2464
2809
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: GanttDomService }, { type: GanttDragContainer }, { type: GanttUpper, decorators: [{
2465
2810
  type: Inject,
2466
2811
  args: [GANTT_UPPER_TOKEN]
@@ -2480,6 +2825,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
2480
2825
  }] } });
2481
2826
 
2482
2827
  const dragMinWidth = 10;
2828
+ const autoScrollStep = 10;
2483
2829
  const activeClass = 'gantt-bar-active';
2484
2830
  const dropActiveClass = 'gantt-bar-drop-active';
2485
2831
  const singleDropActiveClass = 'gantt-bar-single-drop-active';
@@ -2502,6 +2848,16 @@ class GanttBarDrag {
2502
2848
  this.root = root;
2503
2849
  this.dragRefs = [];
2504
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));
2505
2861
  }
2506
2862
  createMouseEvents() {
2507
2863
  const dropClass = this.ganttUpper.config.linkOptions?.dependencyTypes?.length === 1 &&
@@ -2537,33 +2893,38 @@ class GanttBarDrag {
2537
2893
  });
2538
2894
  }
2539
2895
  createBarDrag() {
2540
- const dragRef = this.dragDrop.createDrag(this.barElement);
2896
+ const dragRef = this.createDragRef(this.barElement);
2541
2897
  dragRef.lockAxis = 'x';
2542
2898
  dragRef.withBoundaryElement(this.dom.mainItems);
2543
2899
  dragRef.started.subscribe(() => {
2544
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
+ });
2545
2909
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2546
2910
  });
2547
2911
  dragRef.moved.subscribe((event) => {
2548
- const currentX = this.item.refs.x + event.distance.x;
2549
- const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
2550
- const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
2551
- const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
2552
- const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2553
- let start = currentDate;
2554
- let end = currentDate.addDays(diffDays);
2555
- if (currentX > currentStartX + dayWidth / 2) {
2556
- start = start.addDays(1);
2557
- end = end.addDays(1);
2912
+ this.barDragMove(dragRef, event.distance.x);
2913
+ if (!this.dragScrolling) {
2914
+ this.barDragMoveDistance = event.distance.x;
2558
2915
  }
2559
- this.openDragBackdrop(this.barElement, this.ganttUpper.view.getDateByXPoint(currentX), this.ganttUpper.view.getDateByXPoint(currentX + this.item.refs.width));
2560
- this.item.updateDate(start, end);
2561
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2562
2916
  });
2563
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
+ });
2564
2923
  this.clearDraggingStyles();
2565
2924
  this.closeDragBackdrop();
2566
2925
  event.source.reset();
2926
+ this.dragScrolling = false;
2927
+ this.barDragMoveDistance = 0;
2567
2928
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2568
2929
  });
2569
2930
  this.barDragRef = dragRef;
@@ -2574,36 +2935,26 @@ class GanttBarDrag {
2574
2935
  const handles = this.barElement.querySelectorAll('.drag-handles .handle');
2575
2936
  handles.forEach((handle, index) => {
2576
2937
  const isBefore = index === 0;
2577
- const dragRef = this.dragDrop.createDrag(handle);
2938
+ const dragRef = this.createDragRef(handle);
2578
2939
  dragRef.lockAxis = 'x';
2579
2940
  dragRef.withBoundaryElement(this.dom.mainItems);
2580
2941
  dragRef.started.subscribe(() => {
2581
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
+ });
2582
2951
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2583
2952
  });
2584
2953
  dragRef.moved.subscribe((event) => {
2585
- if (isBefore) {
2586
- const x = this.item.refs.x + event.distance.x;
2587
- const width = this.item.refs.width + event.distance.x * -1;
2588
- const start = this.ganttUpper.view.getDateByXPoint(x);
2589
- if (width > dragMinWidth) {
2590
- this.barElement.style.width = width + 'px';
2591
- this.barElement.style.left = x + 'px';
2592
- this.openDragBackdrop(this.barElement, start, this.item.end);
2593
- this.item.updateDate(start, this.item.end);
2594
- }
2595
- }
2596
- else {
2597
- const width = this.item.refs.width + event.distance.x;
2598
- const end = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + width);
2599
- if (width > dragMinWidth) {
2600
- this.barElement.style.width = width + 'px';
2601
- this.openDragBackdrop(this.barElement, this.item.start, end);
2602
- this.item.updateDate(this.item.start, end);
2603
- }
2954
+ this.barHandleDragMove(event.distance.x, isBefore);
2955
+ if (!this.dragScrolling) {
2956
+ this.barHandleDragMoveDistance = event.distance.x;
2604
2957
  }
2605
- this.dragContainer.dragMoved.emit({ item: this.item.origin });
2606
- event.source.reset();
2607
2958
  });
2608
2959
  dragRef.ended.subscribe((event) => {
2609
2960
  if (isBefore) {
@@ -2618,8 +2969,16 @@ class GanttBarDrag {
2618
2969
  this.item.updateDate(this.item.start, this.item.start.endOfDay());
2619
2970
  }
2620
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
+ });
2621
2977
  this.clearDraggingStyles();
2622
2978
  this.closeDragBackdrop();
2979
+ event.source.reset();
2980
+ this.dragScrolling = false;
2981
+ this.barHandleDragMoveDistance = 0;
2623
2982
  this.dragContainer.dragEnded.emit({ item: this.item.origin });
2624
2983
  });
2625
2984
  dragRefs.push(dragRef);
@@ -2680,8 +3039,10 @@ class GanttBarDrag {
2680
3039
  return dragRefs;
2681
3040
  }
2682
3041
  openDragBackdrop(dragElement, start, end) {
2683
- const dragBackdropElement = this.root.backdrop.nativeElement;
2684
- 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');
2685
3046
  const rootRect = this.dom.root.getBoundingClientRect();
2686
3047
  const dragRect = dragElement.getBoundingClientRect();
2687
3048
  const left = dragRect.left - rootRect.left - this.dom.side.clientWidth;
@@ -2696,8 +3057,8 @@ class GanttBarDrag {
2696
3057
  dragMaskElement.querySelector('.end').innerHTML = end.format('MM-dd');
2697
3058
  }
2698
3059
  closeDragBackdrop() {
2699
- const dragBackdropElement = this.root.backdrop.nativeElement;
2700
- 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');
2701
3062
  dragMaskElement.style.display = 'none';
2702
3063
  dragBackdropElement.style.display = 'none';
2703
3064
  }
@@ -2709,6 +3070,45 @@ class GanttBarDrag {
2709
3070
  this.barElement.style.pointerEvents = '';
2710
3071
  this.barElement.classList.remove('gantt-bar-draggable-drag');
2711
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
+ }
2712
3112
  calcLinkLinePositions(target, isBefore) {
2713
3113
  const rootRect = this.dom.root.getBoundingClientRect();
2714
3114
  const targetRect = target.getBoundingClientRect();
@@ -2740,7 +3140,6 @@ class GanttBarDrag {
2740
3140
  this.item = item;
2741
3141
  this.barElement = elementRef.nativeElement;
2742
3142
  this.ganttUpper = ganttUpper;
2743
- // if (!item.draggable || (this.dragDisabled && this.linkDragDisabled)) {
2744
3143
  if (this.dragDisabled && this.linkDragDisabled) {
2745
3144
  return;
2746
3145
  }
@@ -2750,6 +3149,13 @@ class GanttBarDrag {
2750
3149
  const dragRef = this.createBarDrag();
2751
3150
  const dragHandlesRefs = this.createBarHandleDrags();
2752
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]);
2753
3159
  }
2754
3160
  if (!this.linkDragDisabled) {
2755
3161
  const linkDragRefs = this.createLinkHandleDrags();
@@ -2757,6 +3163,9 @@ class GanttBarDrag {
2757
3163
  }
2758
3164
  }
2759
3165
  }
3166
+ updateItem(item) {
3167
+ this.item = item;
3168
+ }
2760
3169
  ngOnDestroy() {
2761
3170
  this.closeDragBackdrop();
2762
3171
  this.dragRefs.forEach((dragRef) => dragRef.dispose());
@@ -2764,11 +3173,11 @@ class GanttBarDrag {
2764
3173
  this.destroy$.complete();
2765
3174
  }
2766
3175
  }
2767
- 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 });
2768
3177
  GanttBarDrag.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag });
2769
3178
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttBarDrag, decorators: [{
2770
3179
  type: Injectable
2771
- }], 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: [{
2772
3181
  type: SkipSelf
2773
3182
  }] }]; } });
2774
3183
 
@@ -2785,16 +3194,25 @@ class GanttItemUpper {
2785
3194
  this.setPositions();
2786
3195
  });
2787
3196
  }
2788
- ngOnChanges() {
3197
+ ngOnChanges(changes) {
2789
3198
  if (!this.firstChange) {
2790
- this.setPositions();
3199
+ this.itemChange(changes.item.currentValue);
2791
3200
  }
2792
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
+ }
2793
3211
  setPositions() {
2794
3212
  const itemElement = this.elementRef.nativeElement;
2795
- itemElement.style.left = this.item.refs.x + 'px';
2796
- itemElement.style.top = this.item.refs.y + 'px';
2797
- 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';
2798
3216
  if (this.item.type === GanttItemType.bar) {
2799
3217
  itemElement.style.height = this.ganttUpper.styles.barHeight + 'px';
2800
3218
  }
@@ -2839,6 +3257,12 @@ class NgxGanttBarComponent extends GanttItemUpper {
2839
3257
  this.setContentBackground();
2840
3258
  });
2841
3259
  }
3260
+ ngOnChanges(changes) {
3261
+ super.ngOnChanges(changes);
3262
+ if (!this.firstChange) {
3263
+ this.drag.updateItem(this.item);
3264
+ }
3265
+ }
2842
3266
  ngAfterViewInit() {
2843
3267
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
2844
3268
  // the `onStable` will never emit any value.
@@ -2852,7 +3276,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2852
3276
  });
2853
3277
  this.setContentBackground();
2854
3278
  this.handles.changes
2855
- .pipe(startWith(this.handles), switchMap(() =>
3279
+ .pipe(startWith$1(this.handles), switchMap(() =>
2856
3280
  // Note: we need to explicitly subscribe outside of the Angular zone since `addEventListener`
2857
3281
  // is called when the `fromEvent` is subscribed.
2858
3282
  new Observable((subscriber) => this.ngZone.runOutsideAngular(() => merge(...this.handles.toArray().map((handle) => fromEvent(handle.nativeElement, 'mousedown'))).subscribe(subscriber)))), takeUntil(this.unsubscribe$))
@@ -2896,7 +3320,7 @@ class NgxGanttBarComponent extends GanttItemUpper {
2896
3320
  }
2897
3321
  }
2898
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 });
2899
- 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"] }] });
2900
3324
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttBarComponent, decorators: [{
2901
3325
  type: Component,
2902
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" }]
@@ -2981,16 +3405,16 @@ class GanttMainComponent {
2981
3405
  }
2982
3406
  }
2983
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 });
2984
- 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" }] });
2985
3409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: GanttMainComponent, decorators: [{
2986
3410
  type: Component,
2987
- 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" }]
2988
3412
  }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
2989
3413
  type: Inject,
2990
3414
  args: [GANTT_UPPER_TOKEN]
2991
- }] }]; }, propDecorators: { groups: [{
3415
+ }] }]; }, propDecorators: { renderData: [{
2992
3416
  type: Input
2993
- }], items: [{
3417
+ }], flatData: [{
2994
3418
  type: Input
2995
3419
  }], groupHeaderTemplate: [{
2996
3420
  type: Input
@@ -3010,18 +3434,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3010
3434
  }] } });
3011
3435
 
3012
3436
  class NgxGanttComponent extends GanttUpper {
3013
- constructor(elementRef, cdr, ngZone, config) {
3437
+ constructor(elementRef, cdr, ngZone, printService, config) {
3014
3438
  super(elementRef, cdr, ngZone, config);
3439
+ this.printService = printService;
3015
3440
  this.maxLevel = 2;
3016
3441
  this.linkDragStarted = new EventEmitter();
3017
3442
  this.linkDragEnded = new EventEmitter();
3018
3443
  this.lineClick = new EventEmitter();
3019
3444
  this.selectedChange = new EventEmitter();
3020
- this.ngUnsubscribe$ = new Subject();
3021
- this.sideTableWidth = sideWidth;
3445
+ this.flatData = [];
3446
+ this.renderData = [];
3447
+ this.computeAllRefs = false;
3022
3448
  }
3023
3449
  ngOnInit() {
3024
3450
  super.ngOnInit();
3451
+ this.buildVirtualFlatData();
3025
3452
  // Note: the zone may be nooped through `BootstrapOptions` when bootstrapping the root module. This means
3026
3453
  // the `onStable` will never emit any value.
3027
3454
  const onStable$ = this.ngZone.isStable ? from(Promise.resolve()) : this.ngZone.onStable.pipe(take(1));
@@ -3029,24 +3456,84 @@ class NgxGanttComponent extends GanttUpper {
3029
3456
  // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes.
3030
3457
  this.ngZone.runOutsideAngular(() => {
3031
3458
  onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
3032
- 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) => {
3033
3463
  this.linkDragStarted.emit(event);
3034
3464
  });
3035
- this.dragContainer.linkDragEnded.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event) => {
3465
+ this.dragContainer.linkDragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
3036
3466
  this.linkDragEnded.emit(event);
3037
3467
  });
3038
3468
  });
3039
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
+ }
3040
3487
  }
3041
3488
  ngAfterViewInit() {
3042
- this.columns.changes.pipe(startWith(true), takeUntil(this.ngUnsubscribe$)).subscribe(() => {
3043
- this.columns.forEach((column) => {
3044
- if (!column.columnWidth) {
3045
- 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);
3046
3506
  }
3047
3507
  });
3048
- 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
+ }
3049
3533
  });
3534
+ this.computeItemsRefs(...uniqBy(tempItemData, 'id'));
3535
+ this.flatData = [...this.flatData];
3536
+ this.renderData = [...this.renderData];
3050
3537
  }
3051
3538
  expandChildren(item) {
3052
3539
  if (!item.expanded) {
@@ -3056,6 +3543,7 @@ class NgxGanttComponent extends GanttUpper {
3056
3543
  this.childrenResolve(item.origin)
3057
3544
  .pipe(take(1), finalize(() => {
3058
3545
  item.loading = false;
3546
+ this.afterExpand();
3059
3547
  this.expandChange.emit(item);
3060
3548
  this.cdr.detectChanges();
3061
3549
  }))
@@ -3066,11 +3554,13 @@ class NgxGanttComponent extends GanttUpper {
3066
3554
  }
3067
3555
  else {
3068
3556
  this.computeItemsRefs(...item.children);
3557
+ this.afterExpand();
3069
3558
  this.expandChange.emit(item);
3070
3559
  }
3071
3560
  }
3072
3561
  else {
3073
3562
  item.setExpand(false);
3563
+ this.afterExpand();
3074
3564
  this.expandChange.emit(item);
3075
3565
  }
3076
3566
  }
@@ -3096,8 +3586,22 @@ class NgxGanttComponent extends GanttUpper {
3096
3586
  scrollToDate(date) {
3097
3587
  this.ganttRoot.scrollToDate(date);
3098
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
+ }
3099
3603
  }
3100
- 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 });
3101
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: [
3102
3606
  {
3103
3607
  provide: GANTT_UPPER_TOKEN,
@@ -3107,7 +3611,7 @@ NgxGanttComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
3107
3611
  provide: GANTT_ABSTRACT_TOKEN,
3108
3612
  useExisting: forwardRef(() => NgxGanttComponent)
3109
3613
  }
3110
- ], 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 });
3111
3615
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttComponent, decorators: [{
3112
3616
  type: Component,
3113
3617
  args: [{ selector: 'ngx-gantt', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
@@ -3119,8 +3623,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3119
3623
  provide: GANTT_ABSTRACT_TOKEN,
3120
3624
  useExisting: forwardRef(() => NgxGanttComponent)
3121
3625
  }
3122
- ], 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" }]
3123
- }], 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: [{
3124
3630
  type: Inject,
3125
3631
  args: [GANTT_GLOBAL_CONFIG]
3126
3632
  }] }]; }, propDecorators: { maxLevel: [{
@@ -3151,6 +3657,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3151
3657
  }], ganttRoot: [{
3152
3658
  type: ViewChild,
3153
3659
  args: ['ganttRoot']
3660
+ }], virtualScroll: [{
3661
+ type: ViewChild,
3662
+ args: [CdkVirtualScrollViewport]
3154
3663
  }] } });
3155
3664
 
3156
3665
  class NgxGanttModule {
@@ -3159,9 +3668,13 @@ NgxGanttModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
3159
3668
  NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, declarations: [NgxGanttComponent,
3160
3669
  NgxGanttTableComponent,
3161
3670
  NgxGanttTableColumnComponent,
3162
- GanttTableComponent,
3671
+ // GanttTableComponent,
3672
+ GanttTableHeaderComponent,
3673
+ GanttTableBodyComponent,
3163
3674
  GanttMainComponent,
3164
- GanttCalendarComponent,
3675
+ // GanttCalendarComponent,
3676
+ GanttCalendarHeaderComponent,
3677
+ GanttCalendarGridComponent,
3165
3678
  GanttLinksComponent,
3166
3679
  NgxGanttBarComponent,
3167
3680
  GanttIconComponent,
@@ -3172,7 +3685,7 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3172
3685
  NgxGanttToolbarComponent,
3173
3686
  IsGanttRangeItemPipe,
3174
3687
  IsGanttBarItemPipe,
3175
- IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule], exports: [NgxGanttComponent,
3688
+ IsGanttCustomItemPipe], imports: [CommonModule, DragDropModule, ScrollingModule], exports: [NgxGanttComponent,
3176
3689
  NgxGanttTableComponent,
3177
3690
  NgxGanttTableColumnComponent,
3178
3691
  NgxGanttRootComponent,
@@ -3181,15 +3694,16 @@ NgxGanttModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
3181
3694
  NgxGanttBaselineComponent,
3182
3695
  NgxGanttToolbarComponent] });
3183
3696
  NgxGanttModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, providers: [
3697
+ CdkVirtualScrollViewport,
3184
3698
  {
3185
3699
  provide: GANTT_GLOBAL_CONFIG,
3186
3700
  useValue: defaultConfig
3187
3701
  }
3188
- ], imports: [CommonModule, DragDropModule] });
3702
+ ], imports: [CommonModule, DragDropModule, ScrollingModule] });
3189
3703
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: NgxGanttModule, decorators: [{
3190
3704
  type: NgModule,
3191
3705
  args: [{
3192
- imports: [CommonModule, DragDropModule],
3706
+ imports: [CommonModule, DragDropModule, ScrollingModule],
3193
3707
  exports: [
3194
3708
  NgxGanttComponent,
3195
3709
  NgxGanttTableComponent,
@@ -3204,9 +3718,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3204
3718
  NgxGanttComponent,
3205
3719
  NgxGanttTableComponent,
3206
3720
  NgxGanttTableColumnComponent,
3207
- GanttTableComponent,
3721
+ // GanttTableComponent,
3722
+ GanttTableHeaderComponent,
3723
+ GanttTableBodyComponent,
3208
3724
  GanttMainComponent,
3209
- GanttCalendarComponent,
3725
+ // GanttCalendarComponent,
3726
+ GanttCalendarHeaderComponent,
3727
+ GanttCalendarGridComponent,
3210
3728
  GanttLinksComponent,
3211
3729
  NgxGanttBarComponent,
3212
3730
  GanttIconComponent,
@@ -3220,6 +3738,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3220
3738
  IsGanttCustomItemPipe
3221
3739
  ],
3222
3740
  providers: [
3741
+ CdkVirtualScrollViewport,
3223
3742
  {
3224
3743
  provide: GANTT_GLOBAL_CONFIG,
3225
3744
  useValue: defaultConfig
@@ -3236,5 +3755,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
3236
3755
  * Generated bundle index. Do not edit.
3237
3756
  */
3238
3757
 
3239
- 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 };
3240
3759
  //# sourceMappingURL=worktile-gantt.mjs.map