@progress/kendo-angular-gantt 0.2.1-dev.202112091019 → 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 (96) 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/add-task.component.js +94 -0
  5. package/dist/es/editing/dependencies-table.component.js +131 -0
  6. package/dist/es/editing/edit-dialog.component.js +37 -6
  7. package/dist/es/editing/edit.service.js +89 -7
  8. package/dist/es/editing/task-fields.component.js +43 -0
  9. package/dist/es/expanded-state/expandable.directive.js +4 -6
  10. package/dist/es/gantt.component.js +116 -45
  11. package/dist/es/gantt.module.js +13 -4
  12. package/dist/es/index.js +5 -1
  13. package/dist/es/localization/gantt-localization.service.js +26 -0
  14. package/dist/es/localization/messages.js +45 -1
  15. package/dist/es/models/dependency-type.enum.js +16 -0
  16. package/dist/es/models/events/{add-event.interface.js → task-add-event.interface.js} +0 -0
  17. package/dist/es/models/models.js +2 -0
  18. package/dist/es/models/{events/edit-event.interface.js → toolbar-settings.js} +0 -0
  19. package/dist/es/package-metadata.js +1 -1
  20. package/dist/es/timeline/timeline-base-view.service.js +12 -3
  21. package/dist/es/toolbar/toolbar.component.js +9 -1
  22. package/dist/es2015/dependencies/utils.js +6 -5
  23. package/dist/es2015/editing/add-task.component.d.ts +45 -0
  24. package/dist/es2015/editing/add-task.component.js +102 -0
  25. package/dist/es2015/editing/dependencies-table.component.d.ts +39 -0
  26. package/dist/es2015/editing/dependencies-table.component.js +160 -0
  27. package/dist/es2015/editing/edit-dialog.component.d.ts +10 -3
  28. package/dist/es2015/editing/edit-dialog.component.js +55 -33
  29. package/dist/es2015/editing/edit.service.d.ts +24 -3
  30. package/dist/es2015/editing/edit.service.js +78 -10
  31. package/dist/es2015/editing/task-fields.component.d.ts +22 -0
  32. package/dist/es2015/editing/task-fields.component.js +67 -0
  33. package/dist/es2015/expanded-state/expandable.directive.d.ts +1 -2
  34. package/dist/es2015/expanded-state/expandable.directive.js +2 -7
  35. package/dist/es2015/gantt.component.d.ts +29 -18
  36. package/dist/es2015/gantt.component.js +183 -43
  37. package/dist/es2015/gantt.module.js +13 -4
  38. package/dist/es2015/index.d.ts +5 -1
  39. package/dist/es2015/index.js +5 -1
  40. package/dist/es2015/index.metadata.json +1 -1
  41. package/dist/es2015/localization/{treelist-messages.directive.d.ts → gantt-localization.service.d.ts} +4 -3
  42. package/dist/es2015/localization/gantt-localization.service.js +25 -0
  43. package/dist/es2015/localization/messages.d.ts +46 -2
  44. package/dist/es2015/localization/messages.js +45 -1
  45. package/dist/es2015/models/dependency-type.enum.d.ts +1 -1
  46. package/dist/es2015/models/dependency-type.enum.js +16 -0
  47. package/dist/es2015/models/events/cell-close-event.interface.d.ts +1 -1
  48. package/dist/es2015/models/events/task-add-event.interface.d.ts +31 -0
  49. package/dist/{es/models/events/remove-event.interface.js → es2015/models/events/task-add-event.interface.js} +0 -0
  50. package/dist/es2015/models/events/task-edit-event.interface.d.ts +15 -2
  51. package/dist/es2015/models/models.d.ts +5 -3
  52. package/dist/es2015/models/models.js +2 -0
  53. package/dist/es2015/models/toolbar-settings.d.ts +29 -0
  54. package/dist/{es/models/toolbar-position.js → es2015/models/toolbar-settings.js} +0 -0
  55. package/dist/es2015/package-metadata.js +1 -1
  56. package/dist/es2015/timeline/timeline-base-view.service.d.ts +12 -0
  57. package/dist/es2015/timeline/timeline-base-view.service.js +12 -3
  58. package/dist/es2015/toolbar/toolbar-template.directive.d.ts +1 -1
  59. package/dist/es2015/toolbar/toolbar.component.d.ts +2 -0
  60. package/dist/es2015/toolbar/toolbar.component.js +10 -0
  61. package/dist/fesm2015/index.js +757 -115
  62. package/dist/fesm5/index.js +627 -88
  63. package/dist/npm/dependencies/utils.js +6 -5
  64. package/dist/npm/editing/add-task.component.js +96 -0
  65. package/dist/npm/editing/dependencies-table.component.js +133 -0
  66. package/dist/npm/editing/edit-dialog.component.js +36 -5
  67. package/dist/npm/editing/edit.service.js +88 -6
  68. package/dist/npm/editing/task-fields.component.js +45 -0
  69. package/dist/npm/expanded-state/expandable.directive.js +3 -5
  70. package/dist/npm/gantt.component.js +116 -45
  71. package/dist/npm/gantt.module.js +12 -3
  72. package/dist/npm/index.js +10 -2
  73. package/dist/npm/localization/gantt-localization.service.js +28 -0
  74. package/dist/npm/localization/messages.js +45 -1
  75. package/dist/npm/models/dependency-type.enum.js +16 -0
  76. package/dist/npm/models/events/{add-event.interface.js → task-add-event.interface.js} +0 -0
  77. package/dist/npm/models/models.js +4 -0
  78. package/dist/npm/models/{events/edit-event.interface.js → toolbar-settings.js} +0 -0
  79. package/dist/npm/package-metadata.js +1 -1
  80. package/dist/npm/timeline/timeline-base-view.service.js +17 -8
  81. package/dist/npm/toolbar/toolbar.component.js +9 -1
  82. package/dist/systemjs/kendo-angular-gantt.js +1 -1
  83. package/package.json +5 -3
  84. package/dist/es/localization/treelist-messages.directive.js +0 -31
  85. package/dist/es2015/localization/treelist-messages.directive.js +0 -29
  86. package/dist/es2015/models/events/add-event.interface.d.ts +0 -16
  87. package/dist/es2015/models/events/add-event.interface.js +0 -4
  88. package/dist/es2015/models/events/edit-event.interface.d.ts +0 -19
  89. package/dist/es2015/models/events/edit-event.interface.js +0 -4
  90. package/dist/es2015/models/events/remove-event.interface.d.ts +0 -16
  91. package/dist/es2015/models/events/remove-event.interface.js +0 -4
  92. package/dist/es2015/models/toolbar-position.d.ts +0 -9
  93. package/dist/es2015/models/toolbar-position.js +0 -4
  94. package/dist/npm/localization/treelist-messages.directive.js +0 -33
  95. package/dist/npm/models/events/remove-event.interface.js +0 -6
  96. package/dist/npm/models/toolbar-position.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: 1639044748,
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
  };
@@ -766,8 +768,17 @@ const isClearButton = (contender, gantt) => {
766
768
  return isPresent(clearButtonContainer);
767
769
  };
768
770
 
771
+ /**
772
+ * @hidden
773
+ */
769
774
  const DAY_FORMAT = 'E d/MM';
775
+ /**
776
+ * @hidden
777
+ */
770
778
  const HOUR_FORMAT = 'HH:mm aa';
779
+ /**
780
+ * @hidden
781
+ */
771
782
  const MONTH_FORMAT = 'MMM';
772
783
  /**
773
784
  * @hidden
@@ -1313,34 +1324,99 @@ DependencyDomService = __decorate([
1313
1324
  * @hidden
1314
1325
  */
1315
1326
  let EditService = class EditService {
1316
- /**
1317
- * @hidden
1318
- */
1319
- constructor() {
1327
+ constructor(mapper) {
1328
+ this.mapper = mapper;
1320
1329
  this.showEditingDialog = new Subject();
1321
1330
  this.showConfirmationDialog = new Subject();
1322
1331
  this.editEvent = new Subject();
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);
1344
+ }
1345
+ get dependencies() {
1346
+ return [...this.predecessors, ...this.successors];
1323
1347
  }
1324
- createEditDialog(dataItem, formGroup) {
1348
+ createEditDialog(dataItem, taskFormGroup, dependencies) {
1325
1349
  this.dataItem = dataItem;
1326
- this.formGroup = formGroup;
1350
+ this.taskFormGroup = taskFormGroup;
1351
+ this.dependencies = dependencies;
1327
1352
  this.showEditingDialog.next(true);
1328
1353
  }
1329
1354
  closeEditDialog() {
1330
1355
  this.showEditingDialog.next(false);
1331
1356
  this.dataItem = undefined;
1332
- this.formGroup = undefined;
1357
+ this.taskFormGroup = undefined;
1358
+ this.dependencies = [];
1359
+ this.updatedItems = [];
1360
+ this.deletedItems = [];
1333
1361
  }
1334
1362
  triggerEditEvent(editResultType) {
1335
1363
  this.editEvent.next({
1336
- formGroup: this.formGroup,
1364
+ taskFormGroup: this.taskFormGroup,
1337
1365
  dataItem: this.dataItem,
1366
+ dependencies: {
1367
+ createdItems: this.getCreatedDependencies(),
1368
+ updatedItems: this.updatedItems,
1369
+ deletedItems: this.deletedItems
1370
+ },
1338
1371
  editResultType
1339
1372
  });
1340
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
+ }
1341
1416
  };
1342
1417
  EditService = __decorate([
1343
- Injectable()
1418
+ Injectable(),
1419
+ __metadata("design:paramtypes", [MappingService])
1344
1420
  ], EditService);
1345
1421
 
1346
1422
  /**
@@ -1642,6 +1718,24 @@ const mapPath = (item) => ({
1642
1718
  parent: item.parent.data ? mapPath(item.parent) : null
1643
1719
  });
1644
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
+
1645
1739
  var GanttComponent_1;
1646
1740
  const TREELIST_GROUP_COLUMNS_CLASS = 'k-gantt-treelist-nested-columns';
1647
1741
  const DEFAULT_VIEW = 'week';
@@ -1732,7 +1826,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1732
1826
  /**
1733
1827
  * Provides a callback that determines if the given task is selected ([see example]({% slug selection_gantt %}#toc-custom-selection))
1734
1828
  *
1735
- * > The [`selectable`]({% slug gantt_api_ganttcomponent %}#toc-selectable) prop has to be set to `true` in order for this callback to be executed.
1829
+ * > The [`selectable`]({% slug api_gantt_ganttcomponent %}#toc-selectable) prop has to be set to `true` in order for this callback to be executed.
1736
1830
  */
1737
1831
  this.isSelected = isSelected;
1738
1832
  /**
@@ -1746,29 +1840,10 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1746
1840
  /**
1747
1841
  * Enables or disables the Gantt selection mechanism ([see example]({% slug selection_gantt %}#toc-custom-selection)).
1748
1842
  *
1749
- * > When set to `true`, the [`isSelected`]({% slug gantt_api_ganttcomponent %}#toc-isselected) callback has to be provided.
1843
+ * > When set to `true`, the [`isSelected`]({% slug api_gantt_ganttcomponent %}#toc-isselected) callback has to be provided.
1750
1844
  * > When applied, the [`SelectableDirective`]({% slug api_gantt_selectabledirective %}) sets `selectable` to `true` internally.
1751
1845
  */
1752
1846
  this.selectable = false;
1753
- /**
1754
- * The position of the toolbar.
1755
- *
1756
- * The possible values are:
1757
- * - `top`—Positions the toolbar above the Gantt panes.
1758
- * - `bottom`—Positions the toolbar below the Gantt panes.
1759
- * - `both`—Displays two toolbar instances. Positions the first one above,
1760
- * and the second one - below the Gantt panes.
1761
- * - `none`—No toolbar is rendered.
1762
- */
1763
- this.toolbarPosition = 'top';
1764
- /**
1765
- * Gets or sets the callback function that retrieves the child items for a particular item.
1766
- */
1767
- this.fetchChildren = fetchChildren;
1768
- /**
1769
- * Gets or sets the callback function that indicates if a particular item has child items.
1770
- */
1771
- this.hasChildren = hasChildren;
1772
1847
  /**
1773
1848
  * Defines the dependencies that will be drawn between the rendered tasks.
1774
1849
  *
@@ -1870,6 +1945,10 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1870
1945
  * Fires when the user saves an edited task.
1871
1946
  */
1872
1947
  this.save = new EventEmitter();
1948
+ /**
1949
+ * Fires when the user adds a task.
1950
+ */
1951
+ this.taskAdd = new EventEmitter();
1873
1952
  /**
1874
1953
  * Fires when the sorting of the Gantt is changed.
1875
1954
  * You have to handle the event yourself and sort the data.
@@ -1947,6 +2026,13 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1947
2026
  this._rowClass = rowClassCallback;
1948
2027
  this._taskClass = taskClassCallback;
1949
2028
  this._activeView = DEFAULT_VIEW;
2029
+ this._toolbarSettings = {
2030
+ position: 'top',
2031
+ addTaskTool: 'none',
2032
+ viewSelectorTool: 'top'
2033
+ };
2034
+ this._fetchChildren = fetchChildren;
2035
+ this._hasChildren = hasChildren;
1950
2036
  this.rtl = false;
1951
2037
  this.optionChangesSubscriptions = new Subscription();
1952
2038
  this.editServiceSubscription = new Subscription();
@@ -1957,18 +2043,27 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
1957
2043
  this.optionChangesSubscriptions.add(this.optionChangesService.columnChanges.subscribe(() => {
1958
2044
  this.treeList.columns.notifyOnChanges();
1959
2045
  }));
2046
+ this.editService.getSelectedItem = this.getFirstSelectedItem.bind(this);
1960
2047
  this.editServiceSubscription.add(this.editService.showEditingDialog.subscribe(show => this.showEditingDialog = show));
1961
2048
  this.editServiceSubscription.add(this.editService.showConfirmationDialog.subscribe(() => this.taskDelete.emit()));
1962
2049
  this.editServiceSubscription.add(this.editService.editEvent.subscribe(args => {
1963
2050
  this[args.editResultType].emit({
1964
- formGroup: args.formGroup,
2051
+ taskFormGroup: args.taskFormGroup,
1965
2052
  item: getEditItem(args.dataItem, this.treeList.view.data, this.mapper),
2053
+ dependencies: args.dependencies,
1966
2054
  sender: this
1967
2055
  });
1968
2056
  this.showConfirmationDialog = this.showEditingDialog = false;
1969
- this.editService.dataItem = this.editService.formGroup = null;
2057
+ this.editService.dataItem = this.editService.taskFormGroup = null;
2058
+ this.updateView();
2059
+ }));
2060
+ this.editServiceSubscription.add(this.editService.addEvent.subscribe(args => {
2061
+ const selectedItem = this.getFirstSelectedItem();
2062
+ this.taskAdd.emit({
2063
+ actionType: args.actionType,
2064
+ selectedItem: selectedItem ? getEditItem(selectedItem, this.treeList.view.data, this.mapper) : null
2065
+ });
1970
2066
  this.updateView();
1971
- this.dependencyDomService.notifyChanges();
1972
2067
  }));
1973
2068
  this.localizationSubscription = this.localizationService.changes.subscribe(({ rtl }) => {
1974
2069
  this.rtl = rtl;
@@ -2043,6 +2138,49 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2043
2138
  get data() {
2044
2139
  return this._data;
2045
2140
  }
2141
+ /**
2142
+ * The toolbar configuration. Defines the position and content of the toolbar(s).
2143
+ * The available properties are `position`, `addTaskTool`, and `viewSelectorTool`.
2144
+ * All are optional and default to `top`.
2145
+ *
2146
+ * The possible values for each option are:
2147
+ * - `top`—Positions the toolbar above the Gantt panes. Renders the respective tool in the top toolbar.
2148
+ * - `bottom`—Positions the toolbar below the Gantt panes. Renders the respective tool in the bottom toolbar.
2149
+ * - `both`—Displays two toolbar instances. Positions the first one above,
2150
+ * and the second one - below the Gantt panes. Renders the respective tool in the both toolbars.
2151
+ * - `none`—No toolbar is rendered when used for setting `position`.
2152
+ * No add task or view selector tool is rendered when used for setting `addTaskTool` or `viewSelectorTool`.
2153
+ */
2154
+ set toolbarSettings(value) {
2155
+ this._toolbarSettings = {
2156
+ position: value.position || 'top',
2157
+ addTaskTool: value.addTaskTool || 'none',
2158
+ viewSelectorTool: value.viewSelectorTool || 'top'
2159
+ };
2160
+ }
2161
+ get toolbarSettings() {
2162
+ return this._toolbarSettings;
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
+ }
2046
2184
  /**
2047
2185
  * The options of the timeline splitter pane. By default the pane is `collapsible`,
2048
2186
  * `resizable`, not `collapsed`, and its `size` is `'50%'`.
@@ -2150,12 +2288,6 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2150
2288
  get viewTypes() {
2151
2289
  return this.views.map(view => view.type);
2152
2290
  }
2153
- /**
2154
- * @hidden
2155
- */
2156
- get editDialogFormGroup() {
2157
- return this.editService.formGroup;
2158
- }
2159
2291
  ngOnChanges(changes) {
2160
2292
  if (anyChanged(['data', 'activeView', 'workWeekStart', 'workWeekEnd', 'workDayStart', 'workDayEnd'], changes)) {
2161
2293
  this.loadTimelineData();
@@ -2227,19 +2359,27 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2227
2359
  }
2228
2360
  }
2229
2361
  /**
2230
- * Updates the data of the Gantt and forces row-related callbacks to be called anew.
2362
+ * Forces the TreeList to evaluate if some data items have changed and re-renders the rows information, if needed.
2363
+ * Recalculates and re-renders the Timeline period, if needed.
2364
+ * Redraws changed dependencies, if needed.
2365
+ * Executes all row-related callbacks anew.
2231
2366
  */
2232
2367
  updateView() {
2233
2368
  if (isPresent(this.treeList)) {
2234
2369
  this.treeList.updateView();
2235
2370
  }
2371
+ this.loadTimelineData();
2372
+ this.dependencyDomService.notifyChanges();
2236
2373
  }
2237
2374
  /**
2238
2375
  * Opens the task editing dialog.
2239
2376
  */
2240
2377
  editTask(dataItem, formGroup) {
2241
2378
  if (!this.showEditingDialog) {
2242
- 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);
2243
2383
  }
2244
2384
  }
2245
2385
  /**
@@ -2312,7 +2452,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2312
2452
  * @hidden
2313
2453
  */
2314
2454
  showToolbar(position) {
2315
- return this.toolbarPosition !== 'none' && ([position, 'both'].indexOf(this.toolbarPosition) > -1);
2455
+ return this.toolbarSettings.position !== 'none' && ([position, 'both'].indexOf(this.toolbarSettings.position) > -1);
2316
2456
  }
2317
2457
  /**
2318
2458
  * @hidden
@@ -2476,7 +2616,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2476
2616
  items: [dataItem],
2477
2617
  sender: this
2478
2618
  });
2479
- this.updateView();
2619
+ this.treeList.updateView();
2480
2620
  }
2481
2621
  updateTreeListGroupClass(columns = this.columns) {
2482
2622
  if (!isPresent(this.treeList)) {
@@ -2511,6 +2651,11 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
2511
2651
  const shouldToggleSelection = ctrlKey || metaKey;
2512
2652
  return (shouldToggleSelection && this.isSelected(dataItem)) ? 'remove' : 'select';
2513
2653
  }
2654
+ getFirstSelectedItem() {
2655
+ const isSelectedCallback = this.isSelected || isSelected;
2656
+ const loadedItems = this.renderedTreeListItems || [];
2657
+ return loadedItems.find(isSelectedCallback);
2658
+ }
2514
2659
  };
2515
2660
  __decorate([
2516
2661
  ViewChild(TreeListComponent, { static: true }),
@@ -2584,16 +2729,19 @@ __decorate([
2584
2729
  ], GanttComponent.prototype, "selectable", void 0);
2585
2730
  __decorate([
2586
2731
  Input(),
2587
- __metadata("design:type", String)
2588
- ], GanttComponent.prototype, "toolbarPosition", void 0);
2732
+ __metadata("design:type", Object),
2733
+ __metadata("design:paramtypes", [Object])
2734
+ ], GanttComponent.prototype, "toolbarSettings", null);
2589
2735
  __decorate([
2590
2736
  Input(),
2591
- __metadata("design:type", Function)
2592
- ], GanttComponent.prototype, "fetchChildren", void 0);
2737
+ __metadata("design:type", Function),
2738
+ __metadata("design:paramtypes", [Function])
2739
+ ], GanttComponent.prototype, "fetchChildren", null);
2593
2740
  __decorate([
2594
2741
  Input(),
2595
- __metadata("design:type", Function)
2596
- ], GanttComponent.prototype, "hasChildren", void 0);
2742
+ __metadata("design:type", Function),
2743
+ __metadata("design:paramtypes", [Function])
2744
+ ], GanttComponent.prototype, "hasChildren", null);
2597
2745
  __decorate([
2598
2746
  Input(),
2599
2747
  __metadata("design:type", Array)
@@ -2706,6 +2854,10 @@ __decorate([
2706
2854
  Output(),
2707
2855
  __metadata("design:type", EventEmitter)
2708
2856
  ], GanttComponent.prototype, "save", void 0);
2857
+ __decorate([
2858
+ Output(),
2859
+ __metadata("design:type", EventEmitter)
2860
+ ], GanttComponent.prototype, "taskAdd", void 0);
2709
2861
  __decorate([
2710
2862
  Output(),
2711
2863
  __metadata("design:type", EventEmitter)
@@ -2763,6 +2915,7 @@ GanttComponent = GanttComponent_1 = __decorate([
2763
2915
  selector: 'kendo-gantt',
2764
2916
  exportAs: 'kendoGantt',
2765
2917
  providers: [
2918
+ GanttLocalizationService,
2766
2919
  LocalizationService,
2767
2920
  {
2768
2921
  provide: DataBoundTreeComponent,
@@ -2784,6 +2937,27 @@ GanttComponent = GanttComponent_1 = __decorate([
2784
2937
  ],
2785
2938
  template: `
2786
2939
  <ng-container kendoGanttLocalizedMessages
2940
+ i18n-taskEditingGeneralTabTitle="kendo.gantt.taskEditingGeneralTabTitle|The title of the 'General' tab of the editing dialog TabStrip"
2941
+ taskEditingGeneralTabTitle="General"
2942
+
2943
+ i18n-taskEditingPredecessorsTabTitle="kendo.gantt.taskEditingPredecessorsTabTitle|The title of the 'Predecessors' dependencies tab of the editing dialog TabStrip"
2944
+ taskEditingPredecessorsTabTitle="Predecessors"
2945
+
2946
+ i18n-taskEditingSuccessorsTabTitle="kendo.gantt.taskEditingSuccessorsTabTitle|The title of the 'Successors' dependencies tab of the editing dialog TabStrip"
2947
+ taskEditingSuccessorsTabTitle="Successors"
2948
+
2949
+ i18n-taskEditingDependenciesAddButtonText="kendo.gantt.taskEditingDependenciesAddButtonText|The text of the 'Add' button in the dependencies tabs of the editing dialog TabStrip"
2950
+ taskEditingDependenciesAddButtonText="Add"
2951
+
2952
+ i18n-taskEditingDependenciesRemoveButtonText="kendo.gantt.taskEditingDependenciesRemoveButtonText|The text of the 'Remove' button in the dependencies tabs of the editing dialog TabStrip"
2953
+ taskEditingDependenciesRemoveButtonText="Remove"
2954
+
2955
+ i18n-taskEditingDependenciesGridNameColumnTitle="kendo.gantt.taskEditingDependenciesGridNameColumnTitle|The title of the 'Task Title' Grid column in the dependencies tabs of the editing dialog TabStrip"
2956
+ taskEditingDependenciesGridNameColumnTitle="Task Title"
2957
+
2958
+ i18n-taskEditingDependenciesGridTypeColumnTitle="kendo.gantt.taskEditingDependenciesGridTypeColumnTitle|The title of the 'Type' Grid column in the dependencies tabs of the editing dialog TabStrip"
2959
+ taskEditingDependenciesGridTypeColumnTitle="Type"
2960
+
2787
2961
  i18n-taskDeleteLabel="kendo.gantt.taskDeleteLabel|The label of the task delete icon"
2788
2962
  taskDeleteLabel="Delete"
2789
2963
 
@@ -2835,6 +3009,18 @@ GanttComponent = GanttComponent_1 = __decorate([
2835
3009
  i18n-yearViewText-disabled="kendo.gantt.yearViewText|The text of the year view in the ViewSelector component"
2836
3010
  yearViewText="Year"
2837
3011
 
3012
+ i18n-addTaskText="kendo.gantt.addTaskText|The text of the DropDownButton in the AddTask component"
3013
+ addTaskText="Add Task"
3014
+
3015
+ i18n-addChildText="kendo.gantt.addChildText|The text of the 'Add Child' option in the AddTask component"
3016
+ addChildText="Add Child"
3017
+
3018
+ i18n-addAboveText="kendo.gantt.addAboveText|The text of the 'Add Above' option in the AddTask component"
3019
+ addAboveText="Add Above"
3020
+
3021
+ i18n-addBelowText="kendo.gantt.addBelowText|The text of the 'Add Below' option in the AddTask component"
3022
+ addBelowText="Add Below"
3023
+
2838
3024
  i18n-noRecords="kendo.gantt.noRecords|The label visible in the TreeList when there are no records"
2839
3025
  noRecords="No records available."
2840
3026
 
@@ -2956,6 +3142,8 @@ GanttComponent = GanttComponent_1 = __decorate([
2956
3142
  columnsReset="Reset"></ng-container>
2957
3143
  <kendo-gantt-toolbar
2958
3144
  *ngIf="showToolbar('top')"
3145
+ [showAddTask]="toolbarSettings.addTaskTool === 'top' || toolbarSettings.addTaskTool === 'both'"
3146
+ [showViewSelector]="toolbarSettings.viewSelectorTool === 'top' || toolbarSettings.viewSelectorTool === 'both'"
2959
3147
  class="k-gantt-header k-toolbar k-gantt-toolbar"
2960
3148
  position="top"></kendo-gantt-toolbar>
2961
3149
  <div class="k-gantt-content">
@@ -3005,7 +3193,47 @@ GanttComponent = GanttComponent_1 = __decorate([
3005
3193
  }"
3006
3194
  [scope]="this"
3007
3195
  >
3008
- <kendo-treelist-messages [kendoGanttTreeListMessages]="localizationService"></kendo-treelist-messages>
3196
+ <kendo-treelist-messages
3197
+ [noRecords]="getText('noRecords')"
3198
+ [filter]="getText('filter')"
3199
+ [filterEqOperator]="getText('filterEqOperator')"
3200
+ [filterNotEqOperator]="getText('filterNotEqOperator')"
3201
+ [filterIsNullOperator]="getText('filterIsNullOperator')"
3202
+ [filterIsNotNullOperator]="getText('filterIsNotNullOperator')"
3203
+ [filterIsEmptyOperator]="getText('filterIsEmptyOperator')"
3204
+ [filterIsNotEmptyOperator]="getText('filterIsNotEmptyOperator')"
3205
+ [filterStartsWithOperator]="getText('filterStartsWithOperator')"
3206
+ [filterContainsOperator]="getText('filterContainsOperator')"
3207
+ [filterNotContainsOperator]="getText('filterNotContainsOperator')"
3208
+ [filterEndsWithOperator]="getText('filterEndsWithOperator')"
3209
+ [filterGteOperator]="getText('filterGteOperator')"
3210
+ [filterGtOperator]="getText('filterGtOperator')"
3211
+ [filterLteOperator]="getText('filterLteOperator')"
3212
+ [filterLtOperator]="getText('filterLtOperator')"
3213
+ [filterIsTrue]="getText('filterIsTrue')"
3214
+ [filterIsFalse]="getText('filterIsFalse')"
3215
+ [filterBooleanAll]="getText('filterBooleanAll')"
3216
+ [filterAfterOrEqualOperator]="getText('filterAfterOrEqualOperator')"
3217
+ [filterAfterOperator]="getText('filterAfterOperator')"
3218
+ [filterBeforeOperator]="getText('filterBeforeOperator')"
3219
+ [filterBeforeOrEqualOperator]="getText('filterBeforeOrEqualOperator')"
3220
+ [filterFilterButton]="getText('filterFilterButton')"
3221
+ [filterClearButton]="getText('filterClearButton')"
3222
+ [filterAndLogic]="getText('filterAndLogic')"
3223
+ [filterOrLogic]="getText('filterOrLogic')"
3224
+ [loading]="getText('loading')"
3225
+ [columnMenu]="getText('columnMenu')"
3226
+ [columns]="getText('columns')"
3227
+ [sortable]="getText('sortable')"
3228
+ [sortAscending]="getText('sortAscending')"
3229
+ [sortDescending]="getText('sortDescending')"
3230
+ [sortedAscending]="getText('sortedAscending')"
3231
+ [sortedDescending]="getText('sortedDescending')"
3232
+ [sortedDefault]="getText('sortedDefault')"
3233
+ [columnsApply]="getText('columnsApply')"
3234
+ [columnsReset]="getText('columnsReset')"
3235
+ >
3236
+ </kendo-treelist-messages>
3009
3237
  </kendo-treelist>
3010
3238
  </kendo-splitter-pane>
3011
3239
  <kendo-splitter-pane
@@ -3045,16 +3273,21 @@ GanttComponent = GanttComponent_1 = __decorate([
3045
3273
  </div>
3046
3274
  <kendo-gantt-toolbar
3047
3275
  *ngIf="showToolbar('bottom')"
3276
+ [showAddTask]="toolbarSettings.addTaskTool === 'bottom' || toolbarSettings.addTaskTool === 'both'"
3277
+ [showViewSelector]="toolbarSettings.viewSelectorTool === 'bottom' || toolbarSettings.viewSelectorTool === 'both'"
3048
3278
  class="k-gantt-footer k-toolbar k-gantt-toolbar"
3049
3279
  position="bottom"></kendo-gantt-toolbar>
3050
- <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>
3051
3284
  <kendo-dialog
3052
3285
  *ngIf="showConfirmationDialog"
3053
3286
  [width]="575"
3054
3287
  [height]="170"
3055
3288
  [title]="getText('confirmationDialogTitle')"
3056
3289
  (close)="showConfirmationDialog = false;">
3057
- <span>{{getText('confirmationDialogContent')}}</span>
3290
+ <span>{{ getText('confirmationDialogContent') }}</span>
3058
3291
  <kendo-dialog-actions layout="normal">
3059
3292
  <kendo-treelist-spacer></kendo-treelist-spacer>
3060
3293
  <button kendoButton [primary]="true" (click)="handleDeleteConfirmation()">{{ getText('deleteButtonText') }}</button>
@@ -3759,10 +3992,6 @@ GanttHierarchyBindingDirective = __decorate([
3759
3992
  * A directive which controls the expanded state of the items.
3760
3993
  */
3761
3994
  let GanttExpandableDirective = class GanttExpandableDirective extends ExpandableDirective {
3762
- // fixes an injection error in some builds/ng-versions (e.g. StackBlitz)
3763
- constructor(gantt) {
3764
- super(gantt);
3765
- }
3766
3995
  };
3767
3996
  __decorate([
3768
3997
  Input(),
@@ -3772,8 +4001,7 @@ GanttExpandableDirective = __decorate([
3772
4001
  Directive({
3773
4002
  exportAs: 'kendoGanttExpandable',
3774
4003
  selector: '[kendoGanttExpandable]'
3775
- }),
3776
- __metadata("design:paramtypes", [ExpandableTreeComponent])
4004
+ })
3777
4005
  ], GanttExpandableDirective);
3778
4006
 
3779
4007
  /**
@@ -3919,6 +4147,14 @@ let ToolbarComponent = class ToolbarComponent {
3919
4147
  this.scrollSyncService.resetTimelineScrollLeft();
3920
4148
  }
3921
4149
  };
4150
+ __decorate([
4151
+ Input(),
4152
+ __metadata("design:type", Boolean)
4153
+ ], ToolbarComponent.prototype, "showAddTask", void 0);
4154
+ __decorate([
4155
+ Input(),
4156
+ __metadata("design:type", Boolean)
4157
+ ], ToolbarComponent.prototype, "showViewSelector", void 0);
3922
4158
  __decorate([
3923
4159
  Input(),
3924
4160
  __metadata("design:type", String),
@@ -3929,8 +4165,10 @@ ToolbarComponent = __decorate([
3929
4165
  selector: 'kendo-gantt-toolbar',
3930
4166
  template: `
3931
4167
  <ng-container *ngIf="!renderTemplate">
4168
+ <kendo-gantt-add-task *ngIf="showAddTask"></kendo-gantt-add-task>
3932
4169
  <span class="k-spacer k-toolbar-spacer"></span>
3933
4170
  <kendo-gantt-view-selector
4171
+ *ngIf="showViewSelector"
3934
4172
  [views]="gantt.viewTypes"
3935
4173
  [activeView]="gantt.activeView"
3936
4174
  (activeViewChange)="onViewChange($event)"></kendo-gantt-view-selector>
@@ -4016,6 +4254,23 @@ ViewSelectorComponent = __decorate([
4016
4254
  __metadata("design:paramtypes", [LocalizationService])
4017
4255
  ], ViewSelectorComponent);
4018
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
+
4019
4274
  /**
4020
4275
  * @hidden
4021
4276
  *
@@ -4059,9 +4314,9 @@ const dependencyCoordinates = (from, to, rowHeight, type, minDistanceBeforeTurn,
4059
4314
  | |
4060
4315
  [[[]]]- -[[[]]]
4061
4316
  */
4062
- if (type === 0 /* FF */ || type === 3 /* SS */) {
4317
+ if (type === DependencyType.FF || type === DependencyType.SS) {
4063
4318
  // polyline start from first task
4064
- const dir = type === 3 /* SS */ ? 'left' : 'right';
4319
+ const dir = type === DependencyType.SS ? 'left' : 'right';
4065
4320
  top = from.top;
4066
4321
  left = from[dir];
4067
4322
  points.push({ top, left });
@@ -4087,9 +4342,9 @@ const dependencyCoordinates = (from, to, rowHeight, type, minDistanceBeforeTurn,
4087
4342
  |
4088
4343
  -[[[]]]
4089
4344
  */
4090
- const startDir = type === 2 /* SF */ ? 'left' : 'right';
4091
- const endDir = type === 2 /* SF */ ? 'right' : 'left';
4092
- 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
4093
4348
  ? from[startDir] - minDistanceBeforeTurn * 2 < to[endDir]
4094
4349
  : from[startDir] + minDistanceBeforeTurn * 2 > to[endDir];
4095
4350
  // polyline start from first task
@@ -4323,14 +4578,35 @@ TimelineMonthViewComponent = TimelineMonthViewComponent_1 = __decorate([
4323
4578
  * @hidden
4324
4579
  */
4325
4580
  let EditDialogComponent = class EditDialogComponent {
4326
- constructor(mapper, editService, localizationService) {
4581
+ constructor(mapper, editService, cdr, localizationService) {
4327
4582
  this.mapper = mapper;
4328
4583
  this.editService = editService;
4584
+ this.cdr = cdr;
4329
4585
  this.localizationService = localizationService;
4330
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
+ }
4331
4604
  getText(token) {
4332
4605
  return this.localizationService.get(token);
4333
4606
  }
4607
+ getDependencyType(typeId) {
4608
+ return DependencyType[typeId];
4609
+ }
4334
4610
  handleEditingResult(editResultType) {
4335
4611
  this.editService.triggerEditEvent(editResultType);
4336
4612
  }
@@ -4340,8 +4616,8 @@ let EditDialogComponent = class EditDialogComponent {
4340
4616
  };
4341
4617
  __decorate([
4342
4618
  Input(),
4343
- __metadata("design:type", FormGroup)
4344
- ], EditDialogComponent.prototype, "formGroup", void 0);
4619
+ __metadata("design:type", Array)
4620
+ ], EditDialogComponent.prototype, "data", void 0);
4345
4621
  EditDialogComponent = __decorate([
4346
4622
  Component({
4347
4623
  selector: 'kendo-gantt-edit-dialog',
@@ -4353,34 +4629,34 @@ EditDialogComponent = __decorate([
4353
4629
  (close)="handleEditingResult('cancel')">
4354
4630
  <kendo-dialog-messages
4355
4631
  [closeTitle]="getText('taskEditingDialogCloseTitle')"></kendo-dialog-messages>
4356
- <form class="k-form" [formGroup]="formGroup">
4357
- <kendo-formfield *ngIf="formGroup.contains(mapper.taskFields.title)">
4358
- <kendo-label [for]="mapper.taskFields.title" [text]="getText('titleFieldInputLabel')"></kendo-label>
4359
- <input class="k-textbox" [formControlName]="mapper.taskFields.title" />
4360
- </kendo-formfield>
4361
- <div class="k-hstack">
4362
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.start)">
4363
- <kendo-label [for]="mapper.taskFields.start" [text]="getText('startFieldInputLabel')"></kendo-label>
4364
- <kendo-datetimepicker [formControlName]="mapper.taskFields.start"></kendo-datetimepicker>
4365
- </kendo-formfield>
4366
- <kendo-treelist-spacer></kendo-treelist-spacer>
4367
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.end)">
4368
- <kendo-label [for]="mapper.taskFields.end" [text]="getText('endFieldInputLabel')"></kendo-label>
4369
- <kendo-datetimepicker [formControlName]="mapper.taskFields.end"></kendo-datetimepicker>
4370
- </kendo-formfield>
4371
- </div>
4372
- <kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.completionRatio)">
4373
- <kendo-label [for]="mapper.taskFields.completionRatio" [text]="getText('completionRatioFieldInputLabel')"></kendo-label>
4374
- <kendo-numerictextbox
4375
- [formControlName]="mapper.taskFields.completionRatio"
4376
- [min]="0"
4377
- [max]="1"
4378
- [decimals]="2"
4379
- format="p2"
4380
- [step]="0.01"
4381
- ></kendo-numerictextbox>
4382
- </kendo-formfield>
4383
- </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
+
4384
4660
  <kendo-dialog-actions layout="normal">
4385
4661
  <button kendoButton (click)="onTaskDelete()">{{ getText('deleteButtonText') }}</button>
4386
4662
  <kendo-treelist-spacer></kendo-treelist-spacer>
@@ -4392,6 +4668,7 @@ EditDialogComponent = __decorate([
4392
4668
  }),
4393
4669
  __metadata("design:paramtypes", [MappingService,
4394
4670
  EditService,
4671
+ ChangeDetectorRef,
4395
4672
  LocalizationService])
4396
4673
  ], EditDialogComponent);
4397
4674
 
@@ -4400,6 +4677,38 @@ EditDialogComponent = __decorate([
4400
4677
  */
4401
4678
  class Messages extends ComponentMessages {
4402
4679
  }
4680
+ __decorate([
4681
+ Input(),
4682
+ __metadata("design:type", String)
4683
+ ], Messages.prototype, "taskEditingGeneralTabTitle", void 0);
4684
+ __decorate([
4685
+ Input(),
4686
+ __metadata("design:type", String)
4687
+ ], Messages.prototype, "taskEditingPredecessorsTabTitle", void 0);
4688
+ __decorate([
4689
+ Input(),
4690
+ __metadata("design:type", String)
4691
+ ], Messages.prototype, "taskEditingSuccessorsTabTitle", void 0);
4692
+ __decorate([
4693
+ Input(),
4694
+ __metadata("design:type", String)
4695
+ ], Messages.prototype, "taskEditingDependenciesAddButtonText", void 0);
4696
+ __decorate([
4697
+ Input(),
4698
+ __metadata("design:type", String)
4699
+ ], Messages.prototype, "taskEditingDependenciesRemoveButtonText", void 0);
4700
+ __decorate([
4701
+ Input(),
4702
+ __metadata("design:type", String)
4703
+ ], Messages.prototype, "taskEditingDependenciesGridNameColumnTitle", void 0);
4704
+ __decorate([
4705
+ Input(),
4706
+ __metadata("design:type", String)
4707
+ ], Messages.prototype, "taskEditingDependenciesGridTypeColumnTitle", void 0);
4708
+ __decorate([
4709
+ Input(),
4710
+ __metadata("design:type", String)
4711
+ ], Messages.prototype, "deleteButtonText", void 0);
4403
4712
  __decorate([
4404
4713
  Input(),
4405
4714
  __metadata("design:type", String)
@@ -4423,7 +4732,19 @@ __decorate([
4423
4732
  __decorate([
4424
4733
  Input(),
4425
4734
  __metadata("design:type", String)
4426
- ], Messages.prototype, "deleteButtonText", void 0);
4735
+ ], Messages.prototype, "addTaskText", void 0);
4736
+ __decorate([
4737
+ Input(),
4738
+ __metadata("design:type", String)
4739
+ ], Messages.prototype, "addChildText", void 0);
4740
+ __decorate([
4741
+ Input(),
4742
+ __metadata("design:type", String)
4743
+ ], Messages.prototype, "addAboveText", void 0);
4744
+ __decorate([
4745
+ Input(),
4746
+ __metadata("design:type", String)
4747
+ ], Messages.prototype, "addBelowText", void 0);
4427
4748
  __decorate([
4428
4749
  Input(),
4429
4750
  __metadata("design:type", String)
@@ -4680,27 +5001,306 @@ LocalizedMessagesDirective = LocalizedMessagesDirective_1 = __decorate([
4680
5001
  __metadata("design:paramtypes", [LocalizationService])
4681
5002
  ], LocalizedMessagesDirective);
4682
5003
 
5004
+ /**
5005
+ * The UI for adding new items to the Gantt.
5006
+ * Use it within a toolbar template to provide a custom icon or list of options.
5007
+ */
5008
+ let GanttAddTaskComponent = class GanttAddTaskComponent {
5009
+ constructor(localizationService, editService, ngZone) {
5010
+ this.localizationService = localizationService;
5011
+ this.editService = editService;
5012
+ this.ngZone = ngZone;
5013
+ /**
5014
+ * Sets the data of the DropDownButton.
5015
+ * > The data has to be provided in an array-like list.
5016
+ */
5017
+ this.data = [{
5018
+ text: this.getText('addChildText'),
5019
+ type: 'addChild'
5020
+ }, {
5021
+ text: this.getText('addAboveText'),
5022
+ type: 'addAbove'
5023
+ }, {
5024
+ text: this.getText('addBelowText'),
5025
+ type: 'addBelow'
5026
+ }];
5027
+ /**
5028
+ * Defines the name of an existing icon in a Kendo UI theme.
5029
+ * @default 'plus'
5030
+ */
5031
+ this.icon = 'plus';
5032
+ }
5033
+ /**
5034
+ * @hidden
5035
+ */
5036
+ getText(message) {
5037
+ return this.localizationService.get(message);
5038
+ }
5039
+ /**
5040
+ * @hidden
5041
+ */
5042
+ handleOpen(e) {
5043
+ if (!this.editService.getSelectedItem()) {
5044
+ e.preventDefault();
5045
+ }
5046
+ }
5047
+ /**
5048
+ * @hidden
5049
+ */
5050
+ handleMouseClick() {
5051
+ if (!this.editService.getSelectedItem()) {
5052
+ this.ngZone.run(() => {
5053
+ this.editService.addEvent.next({
5054
+ selectedItem: null,
5055
+ actionType: 'addTask'
5056
+ });
5057
+ });
5058
+ }
5059
+ }
5060
+ /**
5061
+ * @hidden
5062
+ */
5063
+ handleItemClick(e) {
5064
+ this.editService.addEvent.next({
5065
+ actionType: e.type,
5066
+ selectedItem: null
5067
+ });
5068
+ }
5069
+ };
5070
+ __decorate([
5071
+ Input(),
5072
+ __metadata("design:type", Array)
5073
+ ], GanttAddTaskComponent.prototype, "data", void 0);
5074
+ __decorate([
5075
+ Input(),
5076
+ __metadata("design:type", String)
5077
+ ], GanttAddTaskComponent.prototype, "icon", void 0);
5078
+ GanttAddTaskComponent = __decorate([
5079
+ Component({
5080
+ selector: 'kendo-gantt-add-task',
5081
+ template: `
5082
+ <kendo-dropdownbutton
5083
+ [data]="data"
5084
+ [icon]="icon"
5085
+ [kendoEventsOutsideAngular]="{ click: handleMouseClick }"
5086
+ [scope]="this"
5087
+ (itemClick)="handleItemClick($event)"
5088
+ (open)="handleOpen($event)">
5089
+ {{ getText('addTaskText') }}
5090
+ </kendo-dropdownbutton>
5091
+ `
5092
+ }),
5093
+ __metadata("design:paramtypes", [LocalizationService,
5094
+ EditService,
5095
+ NgZone])
5096
+ ], GanttAddTaskComponent);
5097
+
4683
5098
  /**
4684
5099
  * @hidden
4685
5100
  */
4686
- let GanttTreeListMessagesDirective = class GanttTreeListMessagesDirective {
4687
- constructor(localizationService) {
5101
+ let DependenciesTableComponent = class DependenciesTableComponent {
5102
+ constructor(mapper, editService, localizationService) {
5103
+ this.mapper = mapper;
5104
+ this.editService = editService;
4688
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
+ });
4689
5142
  }
4690
- ngAfterViewInit() {
4691
- const treeListServiceDictionary = this.localizationService.dictionary;
4692
- Object.keys(treeListServiceDictionary)
4693
- .forEach(token => treeListServiceDictionary[token] = this.kendoGanttTreeListMessages.get(token.replace('kendo.treelist.', '')));
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);
4694
5178
  }
4695
5179
  };
4696
5180
  __decorate([
4697
5181
  Input(),
4698
- __metadata("design:type", LocalizationService)
4699
- ], GanttTreeListMessagesDirective.prototype, "kendoGanttTreeListMessages", void 0);
4700
- GanttTreeListMessagesDirective = __decorate([
4701
- Directive({ selector: '[kendoGanttTreeListMessages]' }),
4702
- __metadata("design:paramtypes", [LocalizationService])
4703
- ], GanttTreeListMessagesDirective);
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);
4704
5304
 
4705
5305
  const IMPORTED_MODULES = [
4706
5306
  CommonModule,
@@ -4713,7 +5313,10 @@ const IMPORTED_MODULES = [
4713
5313
  TreeListModule,
4714
5314
  ButtonsModule,
4715
5315
  DialogModule,
4716
- EventsModule
5316
+ EventsModule,
5317
+ TabStripModule,
5318
+ GridModule,
5319
+ DropDownsModule
4717
5320
  ];
4718
5321
  const DECLARATIONS = [
4719
5322
  GanttComponent,
@@ -4750,7 +5353,9 @@ const DECLARATIONS = [
4750
5353
  EditDialogComponent,
4751
5354
  CustomMessagesComponent,
4752
5355
  LocalizedMessagesDirective,
4753
- GanttTreeListMessagesDirective
5356
+ GanttAddTaskComponent,
5357
+ DependenciesTableComponent,
5358
+ TaskFieldsComponent
4754
5359
  ];
4755
5360
  /**
4756
5361
  * Represents the [NgModule]({{ site.data.urls.angular['ngmoduleapi'] }})
@@ -4797,8 +5402,45 @@ GanttModule = __decorate([
4797
5402
  })
4798
5403
  ], GanttModule);
4799
5404
 
5405
+ /**
5406
+ * @hidden
5407
+ */
5408
+ class PreventableEvent {
5409
+ constructor() {
5410
+ this.prevented = false;
5411
+ }
5412
+ /**
5413
+ * Prevents the default action for a specified event.
5414
+ * In this way, the source component suppresses
5415
+ * the built-in behavior that follows the event.
5416
+ */
5417
+ preventDefault() {
5418
+ this.prevented = true;
5419
+ }
5420
+ /**
5421
+ * Returns `true` if the event was prevented
5422
+ * by any of its subscribers.
5423
+ *
5424
+ * @returns `true` if the default action was prevented.
5425
+ * Otherwise, returns `false`.
5426
+ */
5427
+ isDefaultPrevented() {
5428
+ return this.prevented;
5429
+ }
5430
+ }
5431
+
5432
+ /**
5433
+ * Called every time a user leaves an edited cell.
5434
+ */
5435
+ class CellCloseEvent extends PreventableEvent {
5436
+ constructor(options) {
5437
+ super();
5438
+ Object.assign(this, options);
5439
+ }
5440
+ }
5441
+
4800
5442
  /**
4801
5443
  * Generated bundle index. Do not edit.
4802
5444
  */
4803
5445
 
4804
- export { MappingService, OptionChangesService, DependencyDomService, GanttDependencyDirective, EditDialogComponent, EditService, CustomMessagesComponent, LocalizedMessagesDirective, Messages, GanttTreeListMessagesDirective, 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, 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 };