@progress/kendo-angular-gantt 0.3.0-dev.202112141015 → 0.3.0-dev.202201111723

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 (60) hide show
  1. package/dist/cdn/js/kendo-angular-gantt.js +2 -2
  2. package/dist/cdn/main.js +10 -4
  3. package/dist/es/dependencies/utils.js +6 -5
  4. package/dist/es/editing/dependencies-table.component.js +131 -0
  5. package/dist/es/editing/edit-dialog.component.js +37 -6
  6. package/dist/es/editing/edit.service.js +88 -7
  7. package/dist/es/editing/task-fields.component.js +43 -0
  8. package/dist/es/gantt.component.js +49 -26
  9. package/dist/es/gantt.module.js +12 -3
  10. package/dist/es/index.js +3 -0
  11. package/dist/es/localization/gantt-localization.service.js +26 -0
  12. package/dist/es/models/dependency-type.enum.js +16 -0
  13. package/dist/es/models/models.js +1 -0
  14. package/dist/es/package-metadata.js +1 -1
  15. package/dist/es2015/dependencies/utils.js +6 -5
  16. package/dist/es2015/editing/dependencies-table.component.d.ts +39 -0
  17. package/dist/es2015/editing/dependencies-table.component.js +160 -0
  18. package/dist/es2015/editing/edit-dialog.component.d.ts +10 -3
  19. package/dist/es2015/editing/edit-dialog.component.js +55 -33
  20. package/dist/es2015/editing/edit.service.d.ts +21 -3
  21. package/dist/es2015/editing/edit.service.js +77 -10
  22. package/dist/es2015/editing/task-fields.component.d.ts +22 -0
  23. package/dist/es2015/editing/task-fields.component.js +67 -0
  24. package/dist/es2015/gantt.component.d.ts +4 -6
  25. package/dist/es2015/gantt.component.js +42 -23
  26. package/dist/es2015/gantt.module.js +12 -3
  27. package/dist/es2015/index.d.ts +3 -0
  28. package/dist/es2015/index.js +3 -0
  29. package/dist/es2015/index.metadata.json +1 -1
  30. package/dist/es2015/{models/events/remove-event.interface.d.ts → localization/gantt-localization.service.d.ts} +6 -7
  31. package/dist/es2015/localization/gantt-localization.service.js +25 -0
  32. package/dist/es2015/models/dependency-type.enum.d.ts +1 -1
  33. package/dist/es2015/models/dependency-type.enum.js +16 -0
  34. package/dist/es2015/models/events/task-edit-event.interface.d.ts +17 -4
  35. package/dist/es2015/models/models.d.ts +0 -2
  36. package/dist/es2015/models/models.js +1 -0
  37. package/dist/es2015/package-metadata.js +1 -1
  38. package/dist/fesm2015/index.js +429 -76
  39. package/dist/fesm5/index.js +377 -49
  40. package/dist/npm/dependencies/utils.js +6 -5
  41. package/dist/npm/editing/dependencies-table.component.js +133 -0
  42. package/dist/npm/editing/edit-dialog.component.js +36 -5
  43. package/dist/npm/editing/edit.service.js +87 -6
  44. package/dist/npm/editing/task-fields.component.js +45 -0
  45. package/dist/npm/gantt.component.js +49 -26
  46. package/dist/npm/gantt.module.js +11 -2
  47. package/dist/npm/index.js +6 -0
  48. package/dist/npm/localization/gantt-localization.service.js +28 -0
  49. package/dist/npm/models/dependency-type.enum.js +16 -0
  50. package/dist/npm/models/models.js +2 -0
  51. package/dist/npm/package-metadata.js +1 -1
  52. package/dist/systemjs/kendo-angular-gantt.js +1 -1
  53. package/package.json +3 -1
  54. package/dist/es/models/events/edit-event.interface.js +0 -4
  55. package/dist/es/models/events/remove-event.interface.js +0 -4
  56. package/dist/es2015/models/events/edit-event.interface.d.ts +0 -19
  57. package/dist/es2015/models/events/edit-event.interface.js +0 -4
  58. package/dist/es2015/models/events/remove-event.interface.js +0 -4
  59. package/dist/npm/models/events/edit-event.interface.js +0 -6
  60. package/dist/npm/models/events/remove-event.interface.js +0 -6
@@ -6,22 +6,24 @@ import { __decorate, __metadata, __param } from 'tslib';
6
6
  import { Input, EventEmitter, Injectable, Directive, Optional, TemplateRef, QueryList, ContentChildren, ContentChild, Component, forwardRef, SkipSelf, Host, Injector, NgZone, isDevMode, ViewChild, HostBinding, Output, Renderer2, ElementRef, ChangeDetectorRef, NgModule } from '@angular/core';
7
7
  import { ColumnBase, ColumnComponent, ColumnGroupComponent, SpanColumnComponent, TreeListComponent, DataBoundTreeComponent, ExpandableTreeComponent, FlatBindingDirective, HierarchyBindingDirective, ExpandableDirective, TreeListModule } from '@progress/kendo-angular-treelist';
8
8
  import { cloneDate, addWeeks, firstDayInWeek, addDays, getDate, lastDayOfMonth, firstDayOfMonth, addMonths, isEqual, MS_PER_HOUR, MS_PER_DAY } from '@progress/kendo-date-math';
9
- import { of, Subject, Subscription, fromEvent } from 'rxjs';
9
+ import { of, Subject, Subscription, fromEvent, forkJoin, EMPTY, isObservable } from 'rxjs';
10
10
  import { validatePackage } from '@progress/kendo-licensing';
11
11
  import { isDocumentAvailable, closestInScope, matchesClasses, anyChanged, hasObservers, EventsModule } from '@progress/kendo-angular-common';
12
12
  import { IntlService } from '@progress/kendo-angular-intl';
13
13
  import { orderBy } from '@progress/kendo-data-query';
14
14
  import { getter } from '@progress/kendo-common';
15
- import { map, distinctUntilChanged, take, filter, switchMap } from 'rxjs/operators';
15
+ import { map, distinctUntilChanged, take, expand, reduce, filter, switchMap } from 'rxjs/operators';
16
16
  import { LocalizationService, ComponentMessages, L10N_PREFIX } from '@progress/kendo-angular-l10n';
17
17
  import { CommonModule } from '@angular/common';
18
- import { SplitterModule } from '@progress/kendo-angular-layout';
18
+ import { SplitterModule, TabStripModule } from '@progress/kendo-angular-layout';
19
19
  import { ButtonsModule } from '@progress/kendo-angular-buttons';
20
20
  import { DialogModule } from '@progress/kendo-angular-dialog';
21
- import { FormGroup, ReactiveFormsModule } from '@angular/forms';
21
+ import { FormArray, FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
22
22
  import { LabelModule } from '@progress/kendo-angular-label';
23
23
  import { InputsModule } from '@progress/kendo-angular-inputs';
24
24
  import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
25
+ import { GridModule } from '@progress/kendo-angular-grid';
26
+ import { DropDownsModule } from '@progress/kendo-angular-dropdowns';
25
27
 
26
28
  /**
27
29
  * @hidden
@@ -30,7 +32,7 @@ const packageMetadata = {
30
32
  name: '@progress/kendo-angular-gantt',
31
33
  productName: 'Kendo UI for Angular',
32
34
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
33
- publishDate: 1639476447,
35
+ publishDate: 1641921322,
34
36
  version: '',
35
37
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
36
38
  };
@@ -1322,35 +1324,99 @@ DependencyDomService = __decorate([
1322
1324
  * @hidden
1323
1325
  */
1324
1326
  let EditService = class EditService {
1325
- /**
1326
- * @hidden
1327
- */
1328
- constructor() {
1327
+ constructor(mapper) {
1328
+ this.mapper = mapper;
1329
1329
  this.showEditingDialog = new Subject();
1330
1330
  this.showConfirmationDialog = new Subject();
1331
1331
  this.editEvent = new Subject();
1332
1332
  this.addEvent = new Subject();
1333
+ this.updatedItems = [];
1334
+ this.deletedItems = [];
1335
+ this.itemIndex = (item, data) => {
1336
+ return data.findIndex(dataItem => this.mapper.extractFromTask(dataItem, 'id') === this.mapper.extractFromTask(item, 'id'));
1337
+ };
1338
+ }
1339
+ set dependencies(items) {
1340
+ // Can this whole thing be moved to edit-dialog? Dependencies might not be needed here
1341
+ const dataItemId = this.mapper.extractFromTask(this.dataItem, 'id');
1342
+ this.predecessors = items.filter(item => this.mapper.extractFromDependency(item, 'toId') === dataItemId);
1343
+ this.successors = items.filter(item => this.mapper.extractFromDependency(item, 'fromId') === dataItemId);
1333
1344
  }
1334
- createEditDialog(dataItem, formGroup) {
1345
+ get dependencies() {
1346
+ return [...this.predecessors, ...this.successors];
1347
+ }
1348
+ createEditDialog(dataItem, taskFormGroup, dependencies) {
1335
1349
  this.dataItem = dataItem;
1336
- this.formGroup = formGroup;
1350
+ this.taskFormGroup = taskFormGroup;
1351
+ this.dependencies = dependencies;
1337
1352
  this.showEditingDialog.next(true);
1338
1353
  }
1339
1354
  closeEditDialog() {
1340
1355
  this.showEditingDialog.next(false);
1341
1356
  this.dataItem = undefined;
1342
- this.formGroup = undefined;
1357
+ this.taskFormGroup = undefined;
1358
+ this.dependencies = [];
1359
+ this.updatedItems = [];
1360
+ this.deletedItems = [];
1343
1361
  }
1344
1362
  triggerEditEvent(editResultType) {
1345
1363
  this.editEvent.next({
1346
- formGroup: this.formGroup,
1364
+ taskFormGroup: this.taskFormGroup,
1347
1365
  dataItem: this.dataItem,
1366
+ dependencies: {
1367
+ createdItems: this.getCreatedDependencies(),
1368
+ updatedItems: this.updatedItems,
1369
+ deletedItems: this.deletedItems
1370
+ },
1348
1371
  editResultType
1349
1372
  });
1350
1373
  }
1374
+ updateDependencies(item) {
1375
+ if (!this.isNew(item)) {
1376
+ // update
1377
+ const index = this.itemIndex(item, this.updatedItems);
1378
+ if (index !== -1) {
1379
+ this.updatedItems.splice(index, 1, item);
1380
+ }
1381
+ else {
1382
+ this.updatedItems.push(item);
1383
+ }
1384
+ }
1385
+ }
1386
+ getCreatedDependencies() {
1387
+ return this.dependencies.filter(item => this.mapper.extractFromDependency(item, 'id') === null);
1388
+ }
1389
+ deleteDependency(item) {
1390
+ const updatedIndex = this.itemIndex(item, this.updatedItems);
1391
+ if (updatedIndex !== -1) {
1392
+ this.updatedItems.splice(updatedIndex, 1);
1393
+ }
1394
+ if (!this.isNew(item)) {
1395
+ this.deletedItems.push(item);
1396
+ }
1397
+ }
1398
+ loadTasks(initialValues, isInitializer = true) {
1399
+ return forkJoin(initialValues.map(v => this.getElementById(v))).pipe(map((value) => value.reduce((acc, item) => acc = acc.concat(normalizeGanttData(item)), [])), expand(values => {
1400
+ if (values.some(el => this.hasChildren(el))) {
1401
+ return this.loadTasks(values, false);
1402
+ }
1403
+ return EMPTY;
1404
+ }), reduce((acc, values) => acc.concat(values), isInitializer ? [...initialValues] : []));
1405
+ }
1406
+ getElementById(item) {
1407
+ const children = this.fetchChildren(item);
1408
+ if (isObservable(children)) {
1409
+ return children;
1410
+ }
1411
+ return of(children);
1412
+ }
1413
+ isNew(item) {
1414
+ return !isPresent(this.mapper.extractFromDependency(item, 'id'));
1415
+ }
1351
1416
  };
1352
1417
  EditService = __decorate([
1353
- Injectable()
1418
+ Injectable(),
1419
+ __metadata("design:paramtypes", [MappingService])
1354
1420
  ], EditService);
1355
1421
 
1356
1422
  /**
@@ -1652,6 +1718,24 @@ const mapPath = (item) => ({
1652
1718
  parent: item.parent.data ? mapPath(item.parent) : null
1653
1719
  });
1654
1720
 
1721
+ /**
1722
+ * @hidden
1723
+ *
1724
+ * Needed to keep the Gantt's LocalizationService reference and be able to use it component's inside the TabStrip
1725
+ */
1726
+ let GanttLocalizationService = class GanttLocalizationService {
1727
+ constructor(localizationService) {
1728
+ this.localizationService = localizationService;
1729
+ }
1730
+ get(token) {
1731
+ return this.localizationService.get(token);
1732
+ }
1733
+ };
1734
+ GanttLocalizationService = __decorate([
1735
+ Injectable(),
1736
+ __metadata("design:paramtypes", [LocalizationService])
1737
+ ], GanttLocalizationService);
1738
+
1655
1739
  var GanttComponent_1;
1656
1740
  const TREELIST_GROUP_COLUMNS_CLASS = 'k-gantt-treelist-nested-columns';
1657
1741
  const DEFAULT_VIEW = 'week';
@@ -1760,14 +1844,6 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1760
1844
  * > When applied, the [`SelectableDirective`]({% slug api_gantt_selectabledirective %}) sets `selectable` to `true` internally.
1761
1845
  */
1762
1846
  this.selectable = false;
1763
- /**
1764
- * Gets or sets the callback function that retrieves the child items for a particular item.
1765
- */
1766
- this.fetchChildren = fetchChildren;
1767
- /**
1768
- * Gets or sets the callback function that indicates if a particular item has child items.
1769
- */
1770
- this.hasChildren = hasChildren;
1771
1847
  /**
1772
1848
  * Defines the dependencies that will be drawn between the rendered tasks.
1773
1849
  *
@@ -1955,6 +2031,8 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1955
2031
  addTaskTool: 'none',
1956
2032
  viewSelectorTool: 'top'
1957
2033
  };
2034
+ this._fetchChildren = fetchChildren;
2035
+ this._hasChildren = hasChildren;
1958
2036
  this.rtl = false;
1959
2037
  this.optionChangesSubscriptions = new Subscription();
1960
2038
  this.editServiceSubscription = new Subscription();
@@ -1970,12 +2048,13 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1970
2048
  this.editServiceSubscription.add(this.editService.showConfirmationDialog.subscribe(() => this.taskDelete.emit()));
1971
2049
  this.editServiceSubscription.add(this.editService.editEvent.subscribe(args => {
1972
2050
  this[args.editResultType].emit({
1973
- formGroup: args.formGroup,
2051
+ taskFormGroup: args.taskFormGroup,
1974
2052
  item: getEditItem(args.dataItem, this.treeList.view.data, this.mapper),
2053
+ dependencies: args.dependencies,
1975
2054
  sender: this
1976
2055
  });
1977
2056
  this.showConfirmationDialog = this.showEditingDialog = false;
1978
- this.editService.dataItem = this.editService.formGroup = null;
2057
+ this.editService.dataItem = this.editService.taskFormGroup = null;
1979
2058
  this.updateView();
1980
2059
  }));
1981
2060
  this.editServiceSubscription.add(this.editService.addEvent.subscribe(args => {
@@ -2082,6 +2161,26 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2082
2161
  get toolbarSettings() {
2083
2162
  return this._toolbarSettings;
2084
2163
  }
2164
+ /**
2165
+ * Gets or sets the callback function that retrieves the child items for a particular item.
2166
+ */
2167
+ set fetchChildren(fn) {
2168
+ this._fetchChildren = fn;
2169
+ this.editService.fetchChildren = fn;
2170
+ }
2171
+ get fetchChildren() {
2172
+ return this._fetchChildren;
2173
+ }
2174
+ /**
2175
+ * Gets or sets the callback function that indicates if a particular item has child items.
2176
+ */
2177
+ set hasChildren(fn) {
2178
+ this._hasChildren = fn;
2179
+ this.editService.hasChildren = fn;
2180
+ }
2181
+ get hasChildren() {
2182
+ return this._hasChildren;
2183
+ }
2085
2184
  /**
2086
2185
  * The options of the timeline splitter pane. By default the pane is `collapsible`,
2087
2186
  * `resizable`, not `collapsed`, and its `size` is `'50%'`.
@@ -2189,12 +2288,6 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2189
2288
  get viewTypes() {
2190
2289
  return this.views.map(view => view.type);
2191
2290
  }
2192
- /**
2193
- * @hidden
2194
- */
2195
- get editDialogFormGroup() {
2196
- return this.editService.formGroup;
2197
- }
2198
2291
  ngOnChanges(changes) {
2199
2292
  if (anyChanged(['data', 'activeView', 'workWeekStart', 'workWeekEnd', 'workDayStart', 'workDayEnd'], changes)) {
2200
2293
  this.loadTimelineData();
@@ -2283,7 +2376,10 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2283
2376
  */
2284
2377
  editTask(dataItem, formGroup) {
2285
2378
  if (!this.showEditingDialog) {
2286
- this.editService.createEditDialog(dataItem, formGroup);
2379
+ const taskId = this.mapper.extractFromTask(dataItem, 'id');
2380
+ const dependencies = this.dependencies.filter(item => this.mapper.extractFromDependency(item, 'toId') === taskId
2381
+ || this.mapper.extractFromDependency(item, 'fromId') === taskId);
2382
+ this.editService.createEditDialog(dataItem, formGroup, dependencies);
2287
2383
  }
2288
2384
  }
2289
2385
  /**
@@ -2638,12 +2734,14 @@ __decorate([
2638
2734
  ], GanttComponent.prototype, "toolbarSettings", null);
2639
2735
  __decorate([
2640
2736
  Input(),
2641
- __metadata("design:type", Function)
2642
- ], GanttComponent.prototype, "fetchChildren", void 0);
2737
+ __metadata("design:type", Function),
2738
+ __metadata("design:paramtypes", [Function])
2739
+ ], GanttComponent.prototype, "fetchChildren", null);
2643
2740
  __decorate([
2644
2741
  Input(),
2645
- __metadata("design:type", Function)
2646
- ], GanttComponent.prototype, "hasChildren", void 0);
2742
+ __metadata("design:type", Function),
2743
+ __metadata("design:paramtypes", [Function])
2744
+ ], GanttComponent.prototype, "hasChildren", null);
2647
2745
  __decorate([
2648
2746
  Input(),
2649
2747
  __metadata("design:type", Array)
@@ -2817,6 +2915,7 @@ GanttComponent = GanttComponent_1 = __decorate([
2817
2915
  selector: 'kendo-gantt',
2818
2916
  exportAs: 'kendoGantt',
2819
2917
  providers: [
2918
+ GanttLocalizationService,
2820
2919
  LocalizationService,
2821
2920
  {
2822
2921
  provide: DataBoundTreeComponent,
@@ -3178,14 +3277,17 @@ GanttComponent = GanttComponent_1 = __decorate([
3178
3277
  [showViewSelector]="toolbarSettings.viewSelectorTool === 'bottom' || toolbarSettings.viewSelectorTool === 'both'"
3179
3278
  class="k-gantt-footer k-toolbar k-gantt-toolbar"
3180
3279
  position="bottom"></kendo-gantt-toolbar>
3181
- <kendo-gantt-edit-dialog *ngIf="showEditingDialog" [formGroup]="editDialogFormGroup"></kendo-gantt-edit-dialog>
3280
+ <kendo-gantt-edit-dialog
3281
+ *ngIf="showEditingDialog"
3282
+ [data]="data">
3283
+ </kendo-gantt-edit-dialog>
3182
3284
  <kendo-dialog
3183
3285
  *ngIf="showConfirmationDialog"
3184
3286
  [width]="575"
3185
3287
  [height]="170"
3186
3288
  [title]="getText('confirmationDialogTitle')"
3187
3289
  (close)="showConfirmationDialog = false;">
3188
- <span>{{getText('confirmationDialogContent')}}</span>
3290
+ <span>{{ getText('confirmationDialogContent') }}</span>
3189
3291
  <kendo-dialog-actions layout="normal">
3190
3292
  <kendo-treelist-spacer></kendo-treelist-spacer>
3191
3293
  <button kendoButton [primary]="true" (click)="handleDeleteConfirmation()">{{ getText('deleteButtonText') }}</button>
@@ -4152,6 +4254,23 @@ ViewSelectorComponent = __decorate([
4152
4254
  __metadata("design:paramtypes", [LocalizationService])
4153
4255
  ], ViewSelectorComponent);
4154
4256
 
4257
+ /**
4258
+ * The dependency type when two tasks are connected.
4259
+ *
4260
+ * The supported values are:
4261
+ * * `FF`&mdash;from 'finish' to 'finish'
4262
+ * * `FS`&mdash;from 'finish' to 'start'
4263
+ * * `SS`&mdash;from 'start' to 'start'
4264
+ * * `SF`&mdash;from 'start' to 'finish'
4265
+ */
4266
+ var DependencyType;
4267
+ (function (DependencyType) {
4268
+ DependencyType[DependencyType["FF"] = 0] = "FF";
4269
+ DependencyType[DependencyType["FS"] = 1] = "FS";
4270
+ DependencyType[DependencyType["SF"] = 2] = "SF";
4271
+ DependencyType[DependencyType["SS"] = 3] = "SS"; // task B can't start before task A starts
4272
+ })(DependencyType || (DependencyType = {}));
4273
+
4155
4274
  /**
4156
4275
  * @hidden
4157
4276
  *
@@ -4195,9 +4314,9 @@ const dependencyCoordinates = (from, to, rowHeight, type, minDistanceBeforeTurn,
4195
4314
  | |
4196
4315
  [[[]]]- -[[[]]]
4197
4316
  */
4198
- if (type === 0 /* FF */ || type === 3 /* SS */) {
4317
+ if (type === DependencyType.FF || type === DependencyType.SS) {
4199
4318
  // polyline start from first task
4200
- const dir = type === 3 /* SS */ ? 'left' : 'right';
4319
+ const dir = type === DependencyType.SS ? 'left' : 'right';
4201
4320
  top = from.top;
4202
4321
  left = from[dir];
4203
4322
  points.push({ top, left });
@@ -4223,9 +4342,9 @@ const dependencyCoordinates = (from, to, rowHeight, type, minDistanceBeforeTurn,
4223
4342
  |
4224
4343
  -[[[]]]
4225
4344
  */
4226
- const startDir = type === 2 /* SF */ ? 'left' : 'right';
4227
- const endDir = type === 2 /* SF */ ? 'right' : 'left';
4228
- const additionalTurn = type === 2 /* SF */
4345
+ const startDir = type === DependencyType.SF ? 'left' : 'right';
4346
+ const endDir = type === DependencyType.SF ? 'right' : 'left';
4347
+ const additionalTurn = type === DependencyType.SF
4229
4348
  ? from[startDir] - minDistanceBeforeTurn * 2 < to[endDir]
4230
4349
  : from[startDir] + minDistanceBeforeTurn * 2 > to[endDir];
4231
4350
  // polyline start from first task
@@ -4459,14 +4578,35 @@ TimelineMonthViewComponent = TimelineMonthViewComponent_1 = __decorate([
4459
4578
  * @hidden
4460
4579
  */
4461
4580
  let EditDialogComponent = class EditDialogComponent {
4462
- constructor(mapper, editService, localizationService) {
4581
+ constructor(mapper, editService, cdr, localizationService) {
4463
4582
  this.mapper = mapper;
4464
4583
  this.editService = editService;
4584
+ this.cdr = cdr;
4465
4585
  this.localizationService = localizationService;
4466
4586
  }
4587
+ ngOnInit() {
4588
+ this.editService.loadTasks(this.data).subscribe(value => {
4589
+ this.loadedTasks = value;
4590
+ });
4591
+ }
4592
+ get predecessors() {
4593
+ return this.editService.predecessors;
4594
+ }
4595
+ set predecessors(items) {
4596
+ this.editService.predecessors = items;
4597
+ }
4598
+ get successors() {
4599
+ return this.editService.successors;
4600
+ }
4601
+ set successors(items) {
4602
+ this.editService.successors = items;
4603
+ }
4467
4604
  getText(token) {
4468
4605
  return this.localizationService.get(token);
4469
4606
  }
4607
+ getDependencyType(typeId) {
4608
+ return DependencyType[typeId];
4609
+ }
4470
4610
  handleEditingResult(editResultType) {
4471
4611
  this.editService.triggerEditEvent(editResultType);
4472
4612
  }
@@ -4476,8 +4616,8 @@ let EditDialogComponent = class EditDialogComponent {
4476
4616
  };
4477
4617
  __decorate([
4478
4618
  Input(),
4479
- __metadata("design:type", FormGroup)
4480
- ], EditDialogComponent.prototype, "formGroup", void 0);
4619
+ __metadata("design:type", Array)
4620
+ ], EditDialogComponent.prototype, "data", void 0);
4481
4621
  EditDialogComponent = __decorate([
4482
4622
  Component({
4483
4623
  selector: 'kendo-gantt-edit-dialog',
@@ -4489,34 +4629,34 @@ EditDialogComponent = __decorate([
4489
4629
  (close)="handleEditingResult('cancel')">
4490
4630
  <kendo-dialog-messages
4491
4631
  [closeTitle]="getText('taskEditingDialogCloseTitle')"></kendo-dialog-messages>
4492
- <form class="k-form" [formGroup]="formGroup">
4493
- <kendo-formfield *ngIf="formGroup.contains(mapper.taskFields.title)">
4494
- <kendo-label [for]="mapper.taskFields.title" [text]="getText('titleFieldInputLabel')"></kendo-label>
4495
- <input class="k-textbox" [formControlName]="mapper.taskFields.title" />
4496
- </kendo-formfield>
4497
- <div class="k-hstack">
4498
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.start)">
4499
- <kendo-label [for]="mapper.taskFields.start" [text]="getText('startFieldInputLabel')"></kendo-label>
4500
- <kendo-datetimepicker [formControlName]="mapper.taskFields.start"></kendo-datetimepicker>
4501
- </kendo-formfield>
4502
- <kendo-treelist-spacer></kendo-treelist-spacer>
4503
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.end)">
4504
- <kendo-label [for]="mapper.taskFields.end" [text]="getText('endFieldInputLabel')"></kendo-label>
4505
- <kendo-datetimepicker [formControlName]="mapper.taskFields.end"></kendo-datetimepicker>
4506
- </kendo-formfield>
4507
- </div>
4508
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.completionRatio)">
4509
- <kendo-label [for]="mapper.taskFields.completionRatio" [text]="getText('completionRatioFieldInputLabel')"></kendo-label>
4510
- <kendo-numerictextbox
4511
- [formControlName]="mapper.taskFields.completionRatio"
4512
- [min]="0"
4513
- [max]="1"
4514
- [decimals]="2"
4515
- format="p2"
4516
- [step]="0.01"
4517
- ></kendo-numerictextbox>
4518
- </kendo-formfield>
4519
- </form>
4632
+
4633
+ <kendo-tabstrip [keepTabContent]="true">
4634
+ <kendo-tabstrip-tab [title]="getText('taskEditingGeneralTabTitle')" [selected]="true">
4635
+ <ng-template kendoTabContent>
4636
+ <kendo-gantt-task-fields></kendo-gantt-task-fields>
4637
+ </ng-template>
4638
+ </kendo-tabstrip-tab>
4639
+ <kendo-tabstrip-tab [title]="getText('taskEditingPredecessorsTabTitle')">
4640
+ <ng-template kendoTabContent>
4641
+ <kendo-gantt-dependencies-table
4642
+ [tasks]="loadedTasks"
4643
+ [(dependencies)]="predecessors"
4644
+ dependencyType="predecessor"
4645
+ >
4646
+ </kendo-gantt-dependencies-table>
4647
+ </ng-template>
4648
+ </kendo-tabstrip-tab>
4649
+ <kendo-tabstrip-tab [title]="getText('taskEditingSuccessorsTabTitle')">
4650
+ <ng-template kendoTabContent>
4651
+ <kendo-gantt-dependencies-table
4652
+ [tasks]="loadedTasks"
4653
+ [(dependencies)]="successors"
4654
+ dependencyType="successor">
4655
+ </kendo-gantt-dependencies-table>
4656
+ </ng-template>
4657
+ </kendo-tabstrip-tab>
4658
+ </kendo-tabstrip>
4659
+
4520
4660
  <kendo-dialog-actions layout="normal">
4521
4661
  <button kendoButton (click)="onTaskDelete()">{{ getText('deleteButtonText') }}</button>
4522
4662
  <kendo-treelist-spacer></kendo-treelist-spacer>
@@ -4528,6 +4668,7 @@ EditDialogComponent = __decorate([
4528
4668
  }),
4529
4669
  __metadata("design:paramtypes", [MappingService,
4530
4670
  EditService,
4671
+ ChangeDetectorRef,
4531
4672
  LocalizationService])
4532
4673
  ], EditDialogComponent);
4533
4674
 
@@ -4954,6 +5095,213 @@ GanttAddTaskComponent = __decorate([
4954
5095
  NgZone])
4955
5096
  ], GanttAddTaskComponent);
4956
5097
 
5098
+ /**
5099
+ * @hidden
5100
+ */
5101
+ let DependenciesTableComponent = class DependenciesTableComponent {
5102
+ constructor(mapper, editService, localizationService) {
5103
+ this.mapper = mapper;
5104
+ this.editService = editService;
5105
+ this.localizationService = localizationService;
5106
+ this.dependenciesChange = new EventEmitter();
5107
+ this.selectedKeys = [];
5108
+ this.formGroups = new FormArray([]);
5109
+ this.dependencyTypes = this.getDependencyTypes();
5110
+ }
5111
+ get taskId() {
5112
+ return this.editService.dataItem.id;
5113
+ }
5114
+ // The target dependency id field
5115
+ // e.g. if Predecessors, we have the `fromId` which is the currently edited task,
5116
+ // while the `toId` is missing (needs to be selected by the user)
5117
+ get dependencyIdField() {
5118
+ return this.dependencyType === 'predecessor' ? 'fromId' : 'toId';
5119
+ }
5120
+ ngOnInit() {
5121
+ // generate the FormGroups per each Grid row
5122
+ if (this.formGroups.controls.length === 0) {
5123
+ const fields = this.mapper.dependencyFields;
5124
+ this.dependencies.forEach(item => {
5125
+ const formGroup = new FormGroup({
5126
+ [fields.id]: new FormControl(this.mapper.extractFromDependency(item, 'id')),
5127
+ [fields.fromId]: new FormControl(this.mapper.extractFromDependency(item, 'fromId'), Validators.required),
5128
+ [fields.toId]: new FormControl(this.mapper.extractFromDependency(item, 'toId'), Validators.required),
5129
+ [fields.type]: new FormControl(this.mapper.extractFromDependency(item, 'type'), Validators.required)
5130
+ });
5131
+ this.formGroups.push(formGroup);
5132
+ });
5133
+ }
5134
+ this.formGroups.valueChanges.subscribe(val => {
5135
+ this.formGroups.controls.forEach(control => {
5136
+ if (control.dirty) {
5137
+ this.editService.updateDependencies(control.value);
5138
+ }
5139
+ });
5140
+ this.dependenciesChange.emit(val);
5141
+ });
5142
+ }
5143
+ getFormControl(dataItemIndex, field) {
5144
+ // return the FormControl for the respective column editor
5145
+ return this.formGroups.controls
5146
+ .find((_control, index) => index === dataItemIndex)
5147
+ .get(this.mapper.dependencyFields[field]);
5148
+ }
5149
+ getText(token) {
5150
+ return this.localizationService.get(token);
5151
+ }
5152
+ getDependencyTypes() {
5153
+ const types = Object.keys(DependencyType)
5154
+ .filter(value => typeof DependencyType[value] === 'number')
5155
+ .map(type => {
5156
+ return {
5157
+ type,
5158
+ id: DependencyType[type]
5159
+ };
5160
+ });
5161
+ return types;
5162
+ }
5163
+ addHandler() {
5164
+ const fields = this.mapper.dependencyFields;
5165
+ const formGroup = new FormGroup({
5166
+ [fields.id]: new FormControl(),
5167
+ [fields.fromId]: new FormControl(this.dependencyIdField === 'toId' ? this.taskId : null, Validators.required),
5168
+ [fields.toId]: new FormControl(this.dependencyIdField === 'fromId' ? this.taskId : null, Validators.required),
5169
+ [fields.type]: new FormControl(null, Validators.required)
5170
+ });
5171
+ this.formGroups.push(formGroup);
5172
+ }
5173
+ removeHandler() {
5174
+ const [selectedIndex] = this.selectedKeys;
5175
+ const item = this.formGroups.at(selectedIndex).value;
5176
+ this.editService.deleteDependency(item);
5177
+ this.formGroups.removeAt(selectedIndex);
5178
+ }
5179
+ };
5180
+ __decorate([
5181
+ Input(),
5182
+ __metadata("design:type", Array)
5183
+ ], DependenciesTableComponent.prototype, "tasks", void 0);
5184
+ __decorate([
5185
+ Input(),
5186
+ __metadata("design:type", Array)
5187
+ ], DependenciesTableComponent.prototype, "dependencies", void 0);
5188
+ __decorate([
5189
+ Input(),
5190
+ __metadata("design:type", String)
5191
+ ], DependenciesTableComponent.prototype, "dependencyType", void 0);
5192
+ __decorate([
5193
+ Output(),
5194
+ __metadata("design:type", EventEmitter)
5195
+ ], DependenciesTableComponent.prototype, "dependenciesChange", void 0);
5196
+ DependenciesTableComponent = __decorate([
5197
+ Component({
5198
+ selector: 'kendo-gantt-dependencies-table',
5199
+ template: `
5200
+ <kendo-grid
5201
+ [data]="dependencies"
5202
+ [selectable]="{ mode: 'single' }"
5203
+ [(selectedKeys)]="selectedKeys"
5204
+ kendoGridSelectBy
5205
+ [height]="295"
5206
+ >
5207
+ <ng-template kendoGridToolbarTemplate>
5208
+ <button kendoButton (click)="addHandler()">
5209
+ {{ getText('taskEditingDependenciesAddButtonText') }}
5210
+ </button>
5211
+ <button kendoButton (click)="removeHandler()" [disabled]="selectedKeys.length === 0">
5212
+ {{ getText('taskEditingDependenciesRemoveButtonText') }}
5213
+ </button>
5214
+ </ng-template>
5215
+ <kendo-grid-column [title]="getText('taskEditingDependenciesGridNameColumnTitle')" [field]="dependencyIdField">
5216
+ <ng-template kendoGridCellTemplate let-dataItem="dataItem" let-column="column" let-rowIndex="rowIndex">
5217
+ <kendo-dropdownlist
5218
+ [data]="tasks"
5219
+ textField="title"
5220
+ valueField="id"
5221
+ [valuePrimitive]="true"
5222
+ [formControl]="getFormControl(rowIndex, column.field)"
5223
+ >
5224
+ </kendo-dropdownlist>
5225
+ </ng-template>
5226
+ </kendo-grid-column>
5227
+ <kendo-grid-column [title]="getText('taskEditingDependenciesGridTypeColumnTitle')" field="type">
5228
+ <ng-template kendoGridCellTemplate let-dataItem="dataItem" let-column="column" let-rowIndex="rowIndex">
5229
+ <kendo-dropdownlist
5230
+ [data]="dependencyTypes"
5231
+ textField="type"
5232
+ valueField="id"
5233
+ [valuePrimitive]="true"
5234
+ [formControl]="getFormControl(rowIndex, column.field)"
5235
+ >
5236
+ </kendo-dropdownlist>
5237
+ </ng-template>
5238
+ </kendo-grid-column>
5239
+ </kendo-grid>
5240
+ `
5241
+ }),
5242
+ __metadata("design:paramtypes", [MappingService,
5243
+ EditService,
5244
+ GanttLocalizationService])
5245
+ ], DependenciesTableComponent);
5246
+
5247
+ /**
5248
+ * @hidden
5249
+ */
5250
+ let TaskFieldsComponent = class TaskFieldsComponent {
5251
+ constructor(mapper, editService, localizationService) {
5252
+ this.mapper = mapper;
5253
+ this.editService = editService;
5254
+ this.localizationService = localizationService;
5255
+ }
5256
+ /**
5257
+ * @hidden
5258
+ */
5259
+ get formGroup() {
5260
+ return this.editService.taskFormGroup;
5261
+ }
5262
+ getText(token) {
5263
+ return this.localizationService.get(token);
5264
+ }
5265
+ };
5266
+ TaskFieldsComponent = __decorate([
5267
+ Component({
5268
+ selector: 'kendo-gantt-task-fields',
5269
+ template: `
5270
+ <form class="k-form" [formGroup]="formGroup">
5271
+ <kendo-formfield *ngIf="formGroup.contains(mapper.taskFields.title)">
5272
+ <kendo-label [for]="mapper.taskFields.title" [text]="getText('titleFieldInputLabel')"></kendo-label>
5273
+ <input class="k-textbox" [formControlName]="mapper.taskFields.title" />
5274
+ </kendo-formfield>
5275
+ <div class="k-hstack">
5276
+ <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.start)">
5277
+ <kendo-label [for]="mapper.taskFields.start" [text]="getText('startFieldInputLabel')"></kendo-label>
5278
+ <kendo-datetimepicker [formControlName]="mapper.taskFields.start"></kendo-datetimepicker>
5279
+ </kendo-formfield>
5280
+ <kendo-treelist-spacer></kendo-treelist-spacer>
5281
+ <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.end)">
5282
+ <kendo-label [for]="mapper.taskFields.end" [text]="getText('endFieldInputLabel')"></kendo-label>
5283
+ <kendo-datetimepicker [formControlName]="mapper.taskFields.end"></kendo-datetimepicker>
5284
+ </kendo-formfield>
5285
+ </div>
5286
+ <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.completionRatio)">
5287
+ <kendo-label [for]="mapper.taskFields.completionRatio" [text]="getText('completionRatioFieldInputLabel')"></kendo-label>
5288
+ <kendo-numerictextbox
5289
+ [formControlName]="mapper.taskFields.completionRatio"
5290
+ [min]="0"
5291
+ [max]="1"
5292
+ [decimals]="2"
5293
+ format="p2"
5294
+ [step]="0.01"
5295
+ ></kendo-numerictextbox>
5296
+ </kendo-formfield>
5297
+ </form>
5298
+ `
5299
+ }),
5300
+ __metadata("design:paramtypes", [MappingService,
5301
+ EditService,
5302
+ GanttLocalizationService])
5303
+ ], TaskFieldsComponent);
5304
+
4957
5305
  const IMPORTED_MODULES = [
4958
5306
  CommonModule,
4959
5307
  ReactiveFormsModule,
@@ -4965,7 +5313,10 @@ const IMPORTED_MODULES = [
4965
5313
  TreeListModule,
4966
5314
  ButtonsModule,
4967
5315
  DialogModule,
4968
- EventsModule
5316
+ EventsModule,
5317
+ TabStripModule,
5318
+ GridModule,
5319
+ DropDownsModule
4969
5320
  ];
4970
5321
  const DECLARATIONS = [
4971
5322
  GanttComponent,
@@ -5002,7 +5353,9 @@ const DECLARATIONS = [
5002
5353
  EditDialogComponent,
5003
5354
  CustomMessagesComponent,
5004
5355
  LocalizedMessagesDirective,
5005
- GanttAddTaskComponent
5356
+ GanttAddTaskComponent,
5357
+ DependenciesTableComponent,
5358
+ TaskFieldsComponent
5006
5359
  ];
5007
5360
  /**
5008
5361
  * Represents the [NgModule]({{ site.data.urls.angular['ngmoduleapi'] }})
@@ -5090,4 +5443,4 @@ class CellCloseEvent extends PreventableEvent {
5090
5443
  * Generated bundle index. Do not edit.
5091
5444
  */
5092
5445
 
5093
- export { MappingService, OptionChangesService, DependencyDomService, GanttDependencyDirective, GanttAddTaskComponent, EditDialogComponent, EditService, CustomMessagesComponent, LocalizedMessagesDirective, Messages, PreventableEvent, GanttHeaderTableBodyComponent, GanttMilestoneTaskComponent, GanttSummaryTaskComponent, GanttTaskBase, GanttTaskComponent, GanttTasksTableBodyComponent, ScrollSyncService, GanttTimelineComponent, TimelineBaseViewService, TimelineDayViewComponent, TimelineDayViewService, TimelineMonthViewComponent, TimelineMonthViewService, TimelineViewService, TimelineWeekViewComponent, TimelineWeekViewService, ViewBase, ToolbarComponent, ViewSelectorComponent, GanttComponent, GanttModule, GanttHierarchyBindingDirective, GanttFlatBindingDirective, GanttExpandableDirective, GanttTaskTemplateDirective, GanttTaskContentTemplateDirective, GanttSummaryTaskTemplateDirective, ToolbarTemplateDirective, SelectableDirective, CellCloseEvent, GanttColumnBase, GanttColumnComponent, GanttColumnGroupComponent, GanttSpanColumnComponent, CellTemplateDirective, HeaderTemplateDirective, FooterTemplateDirective, ColumnMenuTemplateDirective, FilterCellTemplateDirective, FilterMenuTemplateDirective, EditTemplateDirective };
5446
+ export { MappingService, OptionChangesService, DependencyDomService, GanttDependencyDirective, GanttAddTaskComponent, DependenciesTableComponent, EditDialogComponent, EditService, TaskFieldsComponent, CustomMessagesComponent, GanttLocalizationService, LocalizedMessagesDirective, Messages, PreventableEvent, GanttHeaderTableBodyComponent, GanttMilestoneTaskComponent, GanttSummaryTaskComponent, GanttTaskBase, GanttTaskComponent, GanttTasksTableBodyComponent, ScrollSyncService, GanttTimelineComponent, TimelineBaseViewService, TimelineDayViewComponent, TimelineDayViewService, TimelineMonthViewComponent, TimelineMonthViewService, TimelineViewService, TimelineWeekViewComponent, TimelineWeekViewService, ViewBase, ToolbarComponent, ViewSelectorComponent, GanttComponent, GanttModule, GanttHierarchyBindingDirective, GanttFlatBindingDirective, GanttExpandableDirective, GanttTaskTemplateDirective, GanttTaskContentTemplateDirective, GanttSummaryTaskTemplateDirective, ToolbarTemplateDirective, SelectableDirective, DependencyType, CellCloseEvent, GanttColumnBase, GanttColumnComponent, GanttColumnGroupComponent, GanttSpanColumnComponent, CellTemplateDirective, HeaderTemplateDirective, FooterTemplateDirective, ColumnMenuTemplateDirective, FilterCellTemplateDirective, FilterMenuTemplateDirective, EditTemplateDirective };