@progress/kendo-angular-scheduler 2.2.0-dev.202111081454 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/cdn/js/kendo-angular-scheduler.js +2 -2
  2. package/dist/cdn/main.js +1 -1
  3. package/dist/es/editing/date-time-picker.component.js +2 -1
  4. package/dist/es/editing/edit-dialog.component.js +1 -1
  5. package/dist/es/editing/recurrence/end-rule-radio-button.directive.js +5 -0
  6. package/dist/es/editing/recurrence/recurrence-monthly-yearly-editor.component.js +1 -1
  7. package/dist/es/editing/recurrence/repeat-on-radio-button.directive.js +5 -0
  8. package/dist/es/events/slot-drag-end-event.js +17 -0
  9. package/dist/es/events/slot-drag-event.js +18 -0
  10. package/dist/es/events/slot-drag-start-event.js +24 -0
  11. package/dist/es/events.js +3 -0
  12. package/dist/es/index.js +1 -0
  13. package/dist/es/package-metadata.js +1 -1
  14. package/dist/es/scheduler.component.js +73 -1
  15. package/dist/es/scheduler.module.js +5 -1
  16. package/dist/es/toolbar/view-selector.component.js +1 -1
  17. package/dist/es/types/slot-selection.js +23 -0
  18. package/dist/es/types.js +1 -0
  19. package/dist/es/views/common/base-view.js +103 -8
  20. package/dist/es/views/common/slot-selectable.directive.js +117 -0
  21. package/dist/es/views/common/view-footer.component.js +1 -1
  22. package/dist/es/views/common/views-shared.module.js +2 -1
  23. package/dist/es/views/day-time/day-time-view.component.js +1 -1
  24. package/dist/es/views/day-time/day-time.module.js +2 -1
  25. package/dist/es/views/month/month-view-renderer.component.js +9 -5
  26. package/dist/es/views/multi-day/multi-day-view-renderer.component.js +3 -3
  27. package/dist/es/views/timeline/timeline-multi-day-view.component.js +1 -1
  28. package/dist/es/views/utils.js +49 -0
  29. package/dist/es/views/view-state.service.js +18 -0
  30. package/dist/es2015/editing/date-time-picker.component.js +7 -1
  31. package/dist/es2015/editing/edit-dialog.component.js +7 -7
  32. package/dist/es2015/editing/recurrence/end-rule-radio-button.directive.d.ts +1 -0
  33. package/dist/es2015/editing/recurrence/end-rule-radio-button.directive.js +5 -0
  34. package/dist/es2015/editing/recurrence/recurrence-monthly-yearly-editor.component.js +14 -5
  35. package/dist/es2015/editing/recurrence/repeat-on-radio-button.directive.d.ts +1 -0
  36. package/dist/es2015/editing/recurrence/repeat-on-radio-button.directive.js +5 -0
  37. package/dist/es2015/events/slot-drag-end-event.d.ts +10 -0
  38. package/dist/es2015/events/slot-drag-end-event.js +10 -0
  39. package/dist/es2015/events/slot-drag-event.d.ts +39 -0
  40. package/dist/es2015/events/slot-drag-event.js +16 -0
  41. package/dist/es2015/events/slot-drag-start-event.d.ts +41 -0
  42. package/dist/es2015/events/slot-drag-start-event.js +19 -0
  43. package/dist/es2015/events.d.ts +3 -0
  44. package/dist/es2015/events.js +3 -0
  45. package/dist/es2015/index.d.ts +2 -0
  46. package/dist/es2015/index.js +1 -0
  47. package/dist/es2015/index.metadata.json +1 -1
  48. package/dist/es2015/package-metadata.js +1 -1
  49. package/dist/es2015/scheduler.component.d.ts +27 -0
  50. package/dist/es2015/scheduler.component.js +73 -1
  51. package/dist/es2015/scheduler.module.js +5 -1
  52. package/dist/es2015/toolbar/view-selector.component.js +2 -1
  53. package/dist/es2015/types/datepicker-options.interface.d.ts +5 -5
  54. package/dist/es2015/types/slot-selection.d.ts +71 -0
  55. package/dist/es2015/types/slot-selection.js +19 -0
  56. package/dist/es2015/types.d.ts +2 -0
  57. package/dist/es2015/types.js +1 -0
  58. package/dist/es2015/views/common/base-view.d.ts +26 -5
  59. package/dist/es2015/views/common/base-view.js +103 -8
  60. package/dist/es2015/views/common/slot-selectable.directive.d.ts +45 -0
  61. package/dist/es2015/views/common/slot-selectable.directive.js +112 -0
  62. package/dist/es2015/views/common/view-footer.component.js +1 -1
  63. package/dist/es2015/views/common/views-shared.module.js +2 -1
  64. package/dist/es2015/views/day-time/day-time-view.component.js +1 -1
  65. package/dist/es2015/views/day-time/day-time.module.js +2 -1
  66. package/dist/es2015/views/month/month-view-renderer.component.d.ts +3 -2
  67. package/dist/es2015/views/month/month-view-renderer.component.js +17 -7
  68. package/dist/es2015/views/multi-day/multi-day-view-renderer.component.d.ts +1 -1
  69. package/dist/es2015/views/multi-day/multi-day-view-renderer.component.js +22 -4
  70. package/dist/es2015/views/timeline/timeline-multi-day-view.component.js +8 -1
  71. package/dist/es2015/views/utils.d.ts +29 -0
  72. package/dist/es2015/views/utils.js +49 -0
  73. package/dist/es2015/views/view-state.service.d.ts +24 -1
  74. package/dist/es2015/views/view-state.service.js +18 -0
  75. package/dist/fesm2015/index.js +1674 -1230
  76. package/dist/fesm5/index.js +1803 -1388
  77. package/dist/npm/editing/date-time-picker.component.js +2 -1
  78. package/dist/npm/editing/edit-dialog.component.js +1 -1
  79. package/dist/npm/editing/recurrence/end-rule-radio-button.directive.js +5 -0
  80. package/dist/npm/editing/recurrence/recurrence-monthly-yearly-editor.component.js +1 -1
  81. package/dist/npm/editing/recurrence/repeat-on-radio-button.directive.js +5 -0
  82. package/dist/npm/events/slot-drag-end-event.js +19 -0
  83. package/dist/npm/events/slot-drag-event.js +20 -0
  84. package/dist/npm/events/slot-drag-start-event.js +26 -0
  85. package/dist/npm/events.js +6 -0
  86. package/dist/npm/index.js +2 -0
  87. package/dist/npm/package-metadata.js +1 -1
  88. package/dist/npm/scheduler.component.js +73 -1
  89. package/dist/npm/scheduler.module.js +4 -0
  90. package/dist/npm/toolbar/view-selector.component.js +1 -1
  91. package/dist/npm/types/slot-selection.js +25 -0
  92. package/dist/npm/types.js +2 -0
  93. package/dist/npm/views/common/base-view.js +102 -7
  94. package/dist/npm/views/common/slot-selectable.directive.js +119 -0
  95. package/dist/npm/views/common/view-footer.component.js +1 -1
  96. package/dist/npm/views/common/views-shared.module.js +2 -1
  97. package/dist/npm/views/day-time/day-time-view.component.js +1 -1
  98. package/dist/npm/views/day-time/day-time.module.js +2 -1
  99. package/dist/npm/views/month/month-view-renderer.component.js +8 -4
  100. package/dist/npm/views/multi-day/multi-day-view-renderer.component.js +3 -3
  101. package/dist/npm/views/timeline/timeline-multi-day-view.component.js +1 -1
  102. package/dist/npm/views/utils.js +53 -0
  103. package/dist/npm/views/view-state.service.js +18 -0
  104. package/dist/systemjs/kendo-angular-scheduler.js +1 -1
  105. package/package.json +25 -23
@@ -6,14 +6,14 @@ import { __decorate, __param, __metadata } from 'tslib';
6
6
  import { Directive, Optional, TemplateRef, Injectable, EventEmitter, NgZone, Input, Renderer2, ElementRef, ChangeDetectorRef, Inject, isDevMode, HostBinding, Component, Output, ContentChild, ContentChildren, QueryList, ViewChild, ViewContainerRef, ChangeDetectionStrategy, ViewEncapsulation, forwardRef, NgModule, LOCALE_ID, Pipe, ViewChildren, HostListener } from '@angular/core';
7
7
  import { LocalizationService, L10N_PREFIX, RTL, MessageService, ComponentMessages } from '@progress/kendo-angular-l10n';
8
8
  import { hasObservers, isDocumentAvailable, isChanged, anyChanged, ResizeSensorComponent, EventsModule, guid, Keys, ResizeSensorModule } from '@progress/kendo-angular-common';
9
- import { getDate, Day, ZonedDate, isEqualDate, toLocalDate, MS_PER_DAY, addDays, firstDayOfMonth, addMonths, firstDayInWeek, timezoneNames } from '@progress/kendo-date-math';
9
+ import { isEqualDate, getDate, Day, ZonedDate, toLocalDate, MS_PER_DAY, addDays, firstDayOfMonth, addMonths, firstDayInWeek, timezoneNames } from '@progress/kendo-date-math';
10
10
  import { validatePackage } from '@progress/kendo-licensing';
11
11
  import { PreventableEvent, CalendarComponent, CalendarModule, DatePickerComponent, DateInputsModule } from '@progress/kendo-angular-dateinputs';
12
12
  import { Subject, BehaviorSubject, fromEvent, Subscription, Observable, combineLatest, merge } from 'rxjs';
13
- import { buffer, filter, map, auditTime, debounceTime, take, switchMap, tap } from 'rxjs/operators';
13
+ import { buffer, filter, map, auditTime, debounceTime, take, switchMap, tap, distinctUntilChanged } from 'rxjs/operators';
14
14
  import { FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
15
15
  import { DialogCloseResult, DialogService, DialogModule } from '@progress/kendo-angular-dialog';
16
- import { IntlService, formatDate, IntlModule, CldrIntlService, parseDate } from '@progress/kendo-angular-intl';
16
+ import { formatDate, IntlService, IntlModule, CldrIntlService, parseDate } from '@progress/kendo-angular-intl';
17
17
  import { CommonModule } from '@angular/common';
18
18
  import { parseRule, expand, serializeRule } from '@progress/kendo-recurrence';
19
19
  import { ButtonsModule, Button } from '@progress/kendo-angular-buttons';
@@ -21,7 +21,7 @@ import { PopupService, PopupModule } from '@progress/kendo-angular-popup';
21
21
  import { orderBy, groupBy } from '@progress/kendo-data-query';
22
22
  import Draggable from '@telerik/kendo-draggable';
23
23
  import { MultiSelectComponent, DropDownListComponent, ComboBoxComponent, DropDownsModule } from '@progress/kendo-angular-dropdowns';
24
- import { NumericTextBoxModule, TextBoxModule } from '@progress/kendo-angular-inputs';
24
+ import { CheckBoxModule, TextAreaModule, NumericTextBoxModule, TextBoxModule } from '@progress/kendo-angular-inputs';
25
25
  import { drawDOM, exportPDF } from '@progress/kendo-drawing';
26
26
  import { saveAs } from '@progress/kendo-file-saver';
27
27
 
@@ -32,7 +32,7 @@ const packageMetadata = {
32
32
  name: '@progress/kendo-angular-scheduler',
33
33
  productName: 'Kendo UI for Angular',
34
34
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
35
- publishDate: 1636383004,
35
+ publishDate: 1642598504,
36
36
  version: '',
37
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'
38
38
  };
@@ -316,6 +316,40 @@ class AddEvent extends PreventableEvent$1 {
316
316
  }
317
317
  }
318
318
 
319
+ /**
320
+ * Arguments for the `slotDragStart` event.
321
+ * The event is preventable and if prevented, subsequent `slotDrag`, `slotDragEnd`, and `slotSelectionChange` will not be fired.
322
+ */
323
+ class SlotDragStartEvent extends PreventableEvent$1 {
324
+ /**
325
+ * @hidden
326
+ */
327
+ constructor(sender, args) {
328
+ super();
329
+ this.sender = sender;
330
+ Object.assign(this, args);
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Arguments for the `slotDrag` event.
336
+ */
337
+ class SlotDragEvent {
338
+ /**
339
+ * @hidden
340
+ */
341
+ constructor(sender, args) {
342
+ this.sender = sender;
343
+ Object.assign(this, args);
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Arguments for the `slotDragEnd` event.
349
+ */
350
+ class SlotDragEndEvent extends SlotDragEvent {
351
+ }
352
+
319
353
  /**
320
354
  * Represents the toolbar template of the Scheduler. To define a toolbar
321
355
  * template, nest an `<ng-template kendoSchedulerToolbarTemplate>` tag
@@ -387,6 +421,22 @@ ToolbarService = __decorate([
387
421
  class SchedulerView {
388
422
  }
389
423
 
424
+ /**
425
+ * The arguments for the [`isSlotSelected`]({% slug api_scheduler_schedulercomponent %}#toc-isslotselected) callback.
426
+ */
427
+ class IsSlotSelectedArgs {
428
+ }
429
+ /**
430
+ * @hidden
431
+ */
432
+ var slotDragEventName;
433
+ (function (slotDragEventName) {
434
+ slotDragEventName["initDragSelect"] = "initDragSelect";
435
+ slotDragEventName["dragSelect"] = "dragSelect";
436
+ slotDragEventName["refreshSlotSelection"] = "refreshSlotSelection";
437
+ slotDragEventName["dragSelectRelease"] = "dragSelectRelease";
438
+ })(slotDragEventName || (slotDragEventName = {}));
439
+
390
440
  /**
391
441
  * Represents the template which renders the date header in the **Agenda** view.
392
442
  * To define the date template, nest an `<ng-template>` tag with the `kendoSchedulerAgendaDateTemplate`
@@ -803,12 +853,18 @@ let ViewStateService = class ViewStateService {
803
853
  this.viewEventSource = new Subject();
804
854
  this.layoutEndSource = new Subject();
805
855
  this.optionsChangeSource = new Subject();
856
+ this.slotSelectionStartSource = new Subject();
857
+ this.slotSelectionStartDragSource = new Subject();
858
+ this.slotSelectionStartEndSource = new Subject();
806
859
  this.dateRange = this.dateRangeSource.asObservable();
807
860
  this.nextDate = this.nextDateSource.asObservable();
808
861
  this.navigate = this.navigateSource.asObservable();
809
862
  this.viewEvent = this.viewEventSource.asObservable();
810
863
  this.layoutEnd = this.layoutEndSource.asObservable();
811
864
  this.optionsChange = this.optionsChangeSource.asObservable();
865
+ this.slotSelectionStart = this.slotSelectionStartSource.asObservable();
866
+ this.slotSelectionDrag = this.slotSelectionStartDragSource.asObservable();
867
+ this.slotSelectionEnd = this.slotSelectionStartEndSource.asObservable();
812
868
  }
813
869
  /**
814
870
  * Publishes the date that will be displayed by the Scheduler
@@ -852,6 +908,18 @@ let ViewStateService = class ViewStateService {
852
908
  args: args
853
909
  });
854
910
  }
911
+ /** @hidden */
912
+ notifySlotSelectionStart(selection) {
913
+ this.slotSelectionStartSource.next(selection);
914
+ }
915
+ /** @hidden */
916
+ notifySlotSelectionDrag(selection) {
917
+ this.slotSelectionStartDragSource.next(selection);
918
+ }
919
+ /** @hidden */
920
+ notifySlotSelectionEnd(selection) {
921
+ this.slotSelectionStartEndSource.next(selection);
922
+ }
855
923
  };
856
924
  ViewStateService = __decorate([
857
925
  Injectable(),
@@ -1747,845 +1815,1208 @@ function rtlScrollPosition(element, position) {
1747
1815
  return result;
1748
1816
  }
1749
1817
 
1750
- const todayDate = () => getDate(new Date());
1751
- const DAYS_IN_WEEK = 7;
1818
+ /** @hidden */
1819
+ const intersects = (startTime, endTime, periodStart, periodEnd) => (startTime < periodStart && endTime > periodEnd) ||
1820
+ (periodStart <= startTime && startTime < periodEnd) ||
1821
+ (periodStart < endTime && endTime <= periodEnd && startTime < endTime);
1822
+ /** @hidden */
1823
+ const dateInRange = (date, start, end) => start.getTime() <= date.getTime() && date.getTime() <= end.getTime();
1824
+ /** @hidden */
1825
+ const roundAllDayEnd = ({ start, end }) => {
1826
+ const startDate = start.stripTime();
1827
+ const endDate = end.stripTime();
1828
+ return endDate.getTime() !== end.getTime() || startDate.getTime() === endDate.getTime() ? endDate.addDays(1) : endDate;
1829
+ };
1830
+ /** @hidden */
1831
+ function toInvariantTime(date) {
1832
+ var staticDate = new Date(1980, 0, 1, 0, 0, 0);
1833
+ if (date) {
1834
+ staticDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
1835
+ }
1836
+ return staticDate;
1837
+ }
1752
1838
  /**
1753
- * Represents the [Kendo UI Scheduler component for Angular]({% slug overview_scheduler %}).
1754
- *
1755
- * @example
1756
- * ```ts-preview
1757
- * _@Component({
1758
- * selector: 'my-app',
1759
- * template: `
1760
- * <kendo-scheduler style="height: 600px">
1761
- * <kendo-scheduler-day-view>
1762
- * </kendo-scheduler-day-view>
1763
- * <kendo-scheduler-week-view>
1764
- * </kendo-scheduler-week-view>
1765
- * </kendo-scheduler>
1766
- * `
1767
- * })
1768
- * class AppComponent {}
1769
- * ```
1839
+ * @hidden
1840
+ * TODO Move to date-math
1770
1841
  */
1771
- let SchedulerComponent = class SchedulerComponent {
1772
- constructor(wrapper, viewContext, viewState, editService, dialogsService, intlService, changeDetector, zone, pdfService, localization, domEvents, renderer, focusService) {
1773
- this.wrapper = wrapper;
1774
- this.viewContext = viewContext;
1775
- this.viewState = viewState;
1776
- this.editService = editService;
1777
- this.dialogsService = dialogsService;
1778
- this.intlService = intlService;
1779
- this.changeDetector = changeDetector;
1780
- this.zone = zone;
1781
- this.pdfService = pdfService;
1782
- this.localization = localization;
1783
- this.domEvents = domEvents;
1784
- this.renderer = renderer;
1785
- this.focusService = focusService;
1786
- this.hostClasses = true;
1787
- this.rtl = false;
1788
- /**
1789
- * Specifies if the Scheduler is editable.
1790
- */
1791
- this.editable = false;
1792
- /**
1793
- * The height of the events in the **Month** and **Timeline** views, and the height of the **All day** events in the **Day** and **Week** views.
1794
- */
1795
- this.eventHeight = 25;
1796
- /**
1797
- * Specifies the columns width. Applicable for the **Timeline** views.
1798
- */
1799
- this.columnWidth = 100;
1800
- /**
1801
- * The start time of the view. The Scheduler displays events which start after the start time.
1802
- * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
1803
- */
1804
- this.startTime = '00:00';
1805
- /**
1806
- * The end time of the view. The Scheduler displays events which end before the end time.
1807
- * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
1808
- */
1809
- this.endTime = '00:00';
1810
- /**
1811
- * The start time of the view when `showWorkHours` is set to `true`.
1812
- * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
1813
- */
1814
- this.workDayStart = '08:00';
1815
- /**
1816
- * The end time of the view when `showWorkHours` is set to `true`.
1817
- * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
1818
- */
1819
- this.workDayEnd = '17:00';
1820
- /**
1821
- * The duration (in minutes) of the time slots. Applicable for the day, week and timeline views.
1822
- */
1823
- this.slotDuration = 60;
1824
- /**
1825
- * The number of divisions of the time slots. Applicable for the **Day**, **Week**, and **Timeline** views.
1826
- */
1827
- this.slotDivisions = 2;
1828
- /**
1829
- * A numeric value between 0 and 1 that specifies what percentage of the slot will be filled by the events.
1830
- * Applicable for the **Day** and **Week** views.
1831
- * Defaults to `0.9` (90% fill).
1832
- */
1833
- this.slotFill = 0.9;
1834
- /**
1835
- * The time to which the view will initially be scrolled.
1836
- * Accepts string values in the `HH:mm` format or a JavaScript `Date`. Applicable for the **Day**, **Week**, and **Timeline** views.
1837
- */
1838
- this.scrollTime = this.workDayStart;
1839
- /**
1840
- * Specifies the Scheduler current time marker settings.
1841
- */
1842
- this.currentTimeMarker = true;
1843
- /**
1844
- * @hidden
1845
- */
1846
- this.selectedViewIndexChange = new EventEmitter();
1847
- /**
1848
- * Fires when the Scheduler is about to execute a navigation action
1849
- * (a view, date, or focus change).
1850
- */
1851
- this.navigate = new EventEmitter();
1852
- /**
1853
- * Fires when the date range that is displayed in the Scheduler changes.
1854
- */
1855
- this.dateChange = new EventEmitter();
1856
- /**
1857
- * Fires when a Scheduler view slot is clicked.
1858
- */
1859
- this.slotClick = new EventEmitter();
1860
- /**
1861
- * Fires when a Scheduler view slot is double-clicked.
1862
- */
1863
- this.slotDblClick = new EventEmitter();
1864
- /**
1865
- * Fires when the user creates a new event using the `'c'` key.
1866
- * ([see example]({% slug keyboard_navigation_scheduler %})).
1867
- */
1868
- this.create = new EventEmitter();
1869
- /**
1870
- * Fires when a Scheduler event is clicked.
1871
- */
1872
- this.eventClick = new EventEmitter();
1873
- /**
1874
- * Fires when a Scheduler event is double-clicked.
1875
- */
1876
- this.eventDblClick = new EventEmitter();
1877
- /**
1878
- * Fires when a key is pressed on a focused Scheduler event.
1879
- */
1880
- this.eventKeydown = new EventEmitter();
1881
- /**
1882
- * Fires when the user cancels the editing by clicking the **Cancel** command button.
1883
- */
1884
- this.cancel = new EventEmitter();
1885
- /**
1886
- * Fires when the user clicks the **Save** command button to save the changes of the edited event.
1887
- */
1888
- this.save = new EventEmitter();
1889
- /**
1890
- * Fires when the user clicks the **Remove** icon of a Scheduler event.
1891
- */
1892
- this.remove = new EventEmitter();
1893
- /**
1894
- * Fires when the user starts resizing a Scheduler event.
1895
- */
1896
- this.resizeStart = new EventEmitter();
1897
- /**
1898
- * Fires when the user is resizing a Scheduler event.
1899
- */
1900
- this.resize = new EventEmitter();
1901
- /**
1902
- * Fires when the user stops resizing a Scheduler event.
1903
- */
1904
- this.resizeEnd = new EventEmitter();
1905
- /**
1906
- * Fires when the user starts dragging a Scheduler event.
1907
- */
1908
- this.dragStart = new EventEmitter();
1909
- /**
1910
- * Fires when the user is dragging a Scheduler event.
1911
- */
1912
- this.drag = new EventEmitter();
1913
- /**
1914
- * Fires when the user stops dragging a Scheduler event.
1915
- */
1916
- this.dragEnd = new EventEmitter();
1917
- /**
1918
- * Fires when the user clicks the **PDF export** command button.
1919
- */
1920
- this.pdfExport = new EventEmitter();
1921
- /**
1922
- * @hidden
1923
- */
1924
- this.dragEndConfirmed = new EventEmitter();
1925
- /**
1926
- * @hidden
1927
- */
1928
- this.resizeEndConfirmed = new EventEmitter();
1929
- /**
1930
- * @hidden
1931
- */
1932
- this.removeConfirmed = new EventEmitter();
1933
- this.viewIndex = 0;
1934
- this._timezone = '';
1935
- this._modelFields = defaultModelFields;
1936
- validatePackage(packageMetadata);
1937
- this.dateRangeStream = viewState.dateRange;
1938
- this.selectedDateStream = viewContext.selectedDate;
1939
- }
1940
- get dir() {
1941
- return this.direction;
1942
- }
1943
- /**
1944
- * The index of the currently selected view.
1945
- *
1946
- * By default, the selected view index is `0` and
1947
- * indicates that the first declared view is visible.
1948
- */
1949
- set selectedViewIndex(index) {
1950
- this.viewIndex = index;
1951
- this.onViewIndexChange();
1952
- }
1953
- get selectedViewIndex() {
1954
- return this.viewIndex;
1842
+ const addUTCDays = (date, offset) => {
1843
+ const newDate = new Date(date.getTime());
1844
+ newDate.setUTCDate(newDate.getUTCDate() + offset);
1845
+ return newDate;
1846
+ };
1847
+ // TODO: name? move to date-math
1848
+ /** @hidden */
1849
+ function toUTCTime(localDate, localTime) {
1850
+ return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localTime.getHours(), localTime.getMinutes(), localTime.getSeconds(), localTime.getMilliseconds()));
1851
+ }
1852
+ // TODO: move to date-math
1853
+ /** @hidden */
1854
+ function toUTCDate(localDate) {
1855
+ return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()));
1856
+ }
1857
+ // TODO: move to date-math
1858
+ /** @hidden */
1859
+ function getUTCDate(utcDate) {
1860
+ return new Date(Date.UTC(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate()));
1861
+ }
1862
+ // TODO: move to date-math
1863
+ /** @hidden */
1864
+ function toUTCDateTime(localDate) {
1865
+ return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localDate.getHours(), localDate.getMinutes(), localDate.getSeconds(), localDate.getMilliseconds()));
1866
+ }
1867
+ /** @hidden */
1868
+ function dateWithTime(target, time) {
1869
+ return new Date(target.getFullYear(), target.getMonth(), target.getDate(), time.getHours(), time.getMinutes());
1870
+ }
1871
+ /**
1872
+ * @hidden
1873
+ * Flips the start and end values of a slot selection based on whether
1874
+ * the last dragged-over slot is before or after the slot where the selection began.
1875
+ */
1876
+ function normaliseRangeStartAndEnd(selectionOrigin, currentSlot) {
1877
+ let start;
1878
+ let end;
1879
+ if (currentSlot.end <= selectionOrigin.end) {
1880
+ end = selectionOrigin.end;
1881
+ start = currentSlot.start;
1955
1882
  }
1956
- /**
1957
- * The first day of the week. Applicable to **Week**, **Month** and **TimelineWeek** views.
1958
- * Defaults to the locale settings.
1959
- */
1960
- set weekStart(value) {
1961
- this._weekStart = value;
1883
+ else {
1884
+ start = selectionOrigin.start;
1885
+ end = currentSlot.end;
1962
1886
  }
1963
- get weekStart() {
1964
- if (isPresent(this._weekStart)) {
1965
- return this._weekStart;
1887
+ return { start, end };
1888
+ }
1889
+ function getDataIdx(value, resource) {
1890
+ const data = resource.data;
1891
+ for (let dataIdx = 0; dataIdx < data.length; dataIdx++) {
1892
+ if (getField(data[dataIdx], resource.valueField) === value) {
1893
+ return dataIdx;
1966
1894
  }
1967
- return this.intlService.firstDay();
1968
- }
1969
- /**
1970
- * Specifies the id of the timezone that will be displayed in the Scheduler.
1971
- * For example, `Europe/Sofia`.
1972
- * Defaults to `Etc/UTC`.
1973
- */
1974
- set timezone(value) {
1975
- this._timezone = value;
1976
- this.events = this.events || [];
1977
- }
1978
- get timezone() {
1979
- return this._timezone;
1980
1895
  }
1981
- /**
1982
- * An array of event instances which will be shown by the Scheduler.
1983
- */
1984
- set events(value) {
1985
- this._events = value;
1986
- this.processEvents(value);
1896
+ return -1;
1897
+ }
1898
+ function resourceItem(value, resource) {
1899
+ const index = getDataIdx(value, resource);
1900
+ return index >= 0 ? resource.data[index] : {};
1901
+ }
1902
+ function resourceItems(values, resource) {
1903
+ return values.map(value => resourceItem(value, resource));
1904
+ }
1905
+ function cloneResources(arr) {
1906
+ const result = [];
1907
+ for (let idx = 0; idx < arr.length; idx++) {
1908
+ const clone$$1 = Object.assign({}, arr[idx]);
1909
+ clone$$1.resources = clone$$1.resources.slice(0);
1910
+ result.push(clone$$1);
1987
1911
  }
1988
- get events() {
1989
- return this._events;
1912
+ return result;
1913
+ }
1914
+ /** @hidden */
1915
+ function resourceItemByValue(event, resource) {
1916
+ const value = getField(event, resource.field);
1917
+ if (Array.isArray(value)) {
1918
+ return resourceItems(value, resource);
1990
1919
  }
1991
- /**
1992
- * The currently selected date of the Scheduler.
1993
- * Determines the period which is displayed.
1994
- */
1995
- set selectedDate(value) {
1996
- if (!value) {
1997
- return;
1920
+ return resourceItem(value, resource);
1921
+ }
1922
+ function addNotGroupedResources(event, resources, allResources) {
1923
+ for (let resourceIdx = 0; resourceIdx < resources.length; resourceIdx++) {
1924
+ const current = resources[resourceIdx];
1925
+ for (let idx = 0; idx < allResources.length; idx++) {
1926
+ const item = allResources[idx];
1927
+ if (!current.resources[idx] && item.data) {
1928
+ current.resources[idx] = resourceItemByValue(event, item);
1929
+ }
1998
1930
  }
1999
- this._selectedDate = value;
2000
- this.viewContext.notifySelectedDate(value);
2001
- }
2002
- get selectedDate() {
2003
- return this._selectedDate;
2004
- }
2005
- /**
2006
- * The names of the model fields from which the Scheduler will read its data
2007
- * ([see example]({% slug databinding_scheduler %}#toc-binding-to-models)).
2008
- */
2009
- set modelFields(value) {
2010
- this._modelFields = Object.assign({}, defaultModelFields, value);
2011
1931
  }
2012
- get modelFields() {
2013
- return this._modelFields;
2014
- }
2015
- ngOnInit() {
2016
- if (!this.selectedDate) {
2017
- this.selectedDate = todayDate();
1932
+ }
1933
+ /** @hidden */
1934
+ function eventResources(event, { taskResources, hasGroups, spans, allResources = [] }) {
1935
+ let resources = [];
1936
+ for (let resourceIdx = 0; resourceIdx < taskResources.length; resourceIdx++) {
1937
+ const resource = taskResources[resourceIdx];
1938
+ if (!resource.data) {
1939
+ resources = [{ leafIdx: 0, resources: [] }];
1940
+ continue;
2018
1941
  }
2019
- }
2020
- ngAfterContentInit() {
2021
- if (isDevMode() && this.views.length === 0) {
2022
- throw new Error('No views declared for <kendo-scheduler>. Please, declare at least one view.');
1942
+ const resourceIndex = allResources.indexOf(resource);
1943
+ let values = getField(event, resource.field);
1944
+ if (!Array.isArray(values)) {
1945
+ values = [values];
2023
1946
  }
2024
- this.subs = this.views.changes.subscribe(() => this.resetViewIndex());
2025
- this.subs.add(this.intlService.changes.subscribe(this.intlChange.bind(this)));
2026
- this.subs.add(this.viewState.nextDate.subscribe(nextDate => {
2027
- this.selectedDate = nextDate;
2028
- }));
2029
- this.subs.add(this.viewState.dateRange.subscribe(dateRange => {
2030
- const isEmpty = dateRange.start.getTime() === 0;
2031
- if (!isEmpty) {
2032
- const args = new DateChangeEvent(this, this.selectedDate, dateRange);
2033
- this.dateChange.emit(args);
2034
- }
2035
- }));
2036
- this.subs.add(this.viewState.navigate.subscribe(({ viewName, date }) => {
2037
- const views = this.views.toArray();
2038
- const view = views.find(v => v.name === viewName);
2039
- const args = new NavigateEvent(this, {
2040
- type: 'show-date',
2041
- view: view || {
2042
- name: viewName,
2043
- title: viewName
2044
- },
2045
- date: date
2046
- });
2047
- this.navigate.next(args);
2048
- if (view && !args.isDefaultPrevented()) {
2049
- const index = views.indexOf(view);
2050
- this.selectedView = view;
2051
- this.setViewIndex(index);
2052
- this.selectedDate = date;
1947
+ const expandedResources = [];
1948
+ for (let valueIdx = 0; valueIdx < values.length; valueIdx++) {
1949
+ const dataIdx = getDataIdx(values[valueIdx], resource);
1950
+ if (dataIdx < 0) {
1951
+ return [{ leafIdx: hasGroups ? -1 : 0, resources: [] }];
2053
1952
  }
2054
- }));
2055
- this.subs.add(this.viewState.viewEvent.subscribe(({ name, args }) => {
2056
- const emitter = this[name];
2057
- const confirmedEmitter = this[`${name}Confirmed`];
2058
- if (hasObservers(emitter) || (confirmedEmitter && hasObservers(confirmedEmitter))) {
2059
- this.zone.run(() => {
2060
- const eventInstance = new VIEW_EVENT_MAP[name](this, args);
2061
- emitter.emit(eventInstance);
2062
- args.prevented = eventInstance.prevented;
2063
- if (confirmedEmitter && !args.prevented) {
2064
- confirmedEmitter.emit(eventInstance);
2065
- }
1953
+ const item = resource.data[dataIdx];
1954
+ // has groups - need all copies of the multiple resource
1955
+ // no groups - just the first
1956
+ if (resourceIdx === 0 && (hasGroups || valueIdx === 0)) {
1957
+ const resourceItems = [];
1958
+ resourceItems[resourceIndex] = resource.multiple && !hasGroups ? [item] : item;
1959
+ resources.push({
1960
+ leafIdx: hasGroups ? dataIdx * spans[resourceIdx] : 0,
1961
+ color: getField(item, resource.colorField),
1962
+ resources: resourceItems
2066
1963
  });
2067
1964
  }
2068
- }));
2069
- this.subs.add(this.viewState.layoutEnd.subscribe(() => {
2070
- if (this.resizeSensor) {
2071
- this.resizeSensor.acceptSize();
1965
+ else if (hasGroups) { // don't create multiple resource groups if no groups for multiple resources
1966
+ let currentResources = resources;
1967
+ if (values.length > 1) {
1968
+ currentResources = cloneResources(resources);
1969
+ expandedResources.push.apply(expandedResources, currentResources);
1970
+ }
1971
+ for (let currentIdx = 0; currentIdx < currentResources.length; currentIdx++) {
1972
+ currentResources[currentIdx].leafIdx += dataIdx * spans[resourceIdx];
1973
+ currentResources[currentIdx].resources[resourceIndex] = item;
1974
+ }
2072
1975
  }
2073
- }));
2074
- this.onViewIndexChange();
2075
- this.notifyOptionsChange = this.notifyOptionsChange.bind(this);
2076
- this.subs.add(this.allDayEventTemplate.changes.subscribe(this.notifyOptionsChange));
2077
- this.subs.add(this.eventTemplate.changes.subscribe(this.notifyOptionsChange));
2078
- this.subs.add(this.timeSlotTemplate.changes.subscribe(this.notifyOptionsChange));
2079
- this.subs.add(this.timeSlotTemplate.changes.subscribe(this.notifyOptionsChange));
2080
- this.subs.add(this.minorTimeHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2081
- this.subs.add(this.majorTimeHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2082
- this.subs.add(this.monthDaySlotTemplate.changes.subscribe(this.notifyOptionsChange));
2083
- this.subs.add(this.dateHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2084
- this.subs.add(this.allDaySlotTemplate.changes.subscribe(this.notifyOptionsChange));
2085
- this.subs.add(this.groupHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2086
- this.subs.add(this.agendaDateTemplate.changes.subscribe(this.notifyOptionsChange));
2087
- this.subs.add(this.agendaTimeTemplate.changes.subscribe(this.notifyOptionsChange));
2088
- this.subs.add(this.views.changes.subscribe(() => {
2089
- this.changeDetector.markForCheck();
2090
- }));
2091
- //this.editService.timezone = this.timezone;
2092
- this.attachEditHandlers();
2093
- this.dialogsService.container = this.confirmationDialogContainerRef;
2094
- this.notifyOptionsChange();
2095
- this.subs.add(this.pdfService.exportClick.subscribe(() => {
2096
- const args = new PDFExportEvent();
2097
- this.pdfExport.emit(args);
2098
- if (!args.isDefaultPrevented()) {
2099
- this.saveAsPDF();
1976
+ else if (valueIdx > 0) {
1977
+ for (let idx = 0; idx < resources.length; idx++) {
1978
+ resources[idx].resources[resourceIndex].push(item);
1979
+ }
2100
1980
  }
2101
- }));
2102
- this.subs.add(this.pdfService.done.subscribe(() => {
2103
- this.loadingComponent.toggle(false);
2104
- }));
2105
- this.subs.add(this.localization.changes.subscribe(({ rtl }) => {
2106
- this.rtl = rtl;
2107
- this.direction = this.rtl ? 'rtl' : 'ltr';
2108
- }));
2109
- this.subs.add(this.viewState.optionsChange.subscribe(() => {
2110
- this.changeDetector.markForCheck();
2111
- }));
2112
- this.attachElementEventHandlers();
2113
- }
2114
- ngOnChanges(changes) {
2115
- if (isChanged('resources', changes) && !isChanged('events', changes) && this.viewItems) {
2116
- this.viewItems.forEach(item => {
2117
- copyResources(item.event, this.resources);
2118
- });
2119
1981
  }
2120
- if (anyChanged([
2121
- 'group', 'resources', 'min', 'max', 'showWorkHours', 'startTime', 'scrollTime', 'endTime', 'eventHeight',
2122
- 'workDayStart', 'workDayEnd', 'workWeekStart', 'workWeekEnd', 'weekStart', 'slotDuration', 'slotDivisions',
2123
- 'editable', 'timezone', 'slotClass', 'slotFill', 'columnWidth', 'eventClass', 'eventStyles'
2124
- ], changes)) {
2125
- this.notifyOptionsChange(changes);
1982
+ if (expandedResources.length) {
1983
+ resources = expandedResources;
2126
1984
  }
2127
1985
  }
2128
- ngOnDestroy() {
2129
- if (this.subs) {
2130
- this.subs.unsubscribe();
2131
- }
2132
- if (this.detachElementEventHandlers) {
2133
- this.detachElementEventHandlers();
2134
- }
1986
+ addNotGroupedResources(event, resources, allResources);
1987
+ return resources;
1988
+ }
1989
+ /** @hidden */
1990
+ function assignTasksResources(tasks, options) {
1991
+ for (let idx = 0; idx < tasks.length; idx++) {
1992
+ const task = tasks[idx];
1993
+ task.resources = eventResources(task.event, options);
2135
1994
  }
2136
- /**
2137
- * @hidden
2138
- */
2139
- onResize(_event) {
2140
- this.viewContext.notifyResize();
1995
+ }
1996
+ /**
1997
+ * @hidden
1998
+ */
1999
+ function areValidResources(resources) {
2000
+ return Array.isArray(resources) && resources.length > 0 && resources[0] !== undefined;
2001
+ }
2002
+ /**
2003
+ * @hidden
2004
+ */
2005
+ function resourcesMatch(res1, res2, strict) {
2006
+ if (res1.length !== res2.length) {
2007
+ return false;
2141
2008
  }
2142
- /**
2143
- * @hidden
2144
- */
2145
- onNavigationAction(action) {
2146
- const args = new NavigateEvent(this, action);
2147
- this.navigate.next(args);
2148
- if (args.isDefaultPrevented()) {
2149
- return true;
2150
- }
2151
- if (action.type === 'view-change') {
2152
- const views = this.views.toArray();
2153
- const index = views.indexOf(action.view);
2154
- this.selectedView = action.view;
2155
- this.setViewIndex(index);
2156
- }
2157
- else if (action.type === 'select-date') {
2158
- if (this.isInRange(action.date)) {
2159
- this.selectedDate = action.date;
2160
- }
2161
- }
2162
- else if (action.type === 'today') {
2163
- const date = new Date();
2164
- if (this.isInRange(date)) {
2165
- this.selectedDate = date;
2166
- }
2167
- }
2168
- else {
2169
- this.viewContext.notifyAction(action);
2170
- }
2009
+ if (!strict && !areValidResources(res1) || !areValidResources(res2)) {
2010
+ return true;
2171
2011
  }
2172
- /**
2173
- * Creates a popup editor for the new event.
2174
- *
2175
- * @param group - The [`FormGroup`](https://angular.io/docs/ts/latest/api/forms/index/FormGroup-class.html) that describes
2176
- * the edit form. If called with a data item, the parameter will build the `FormGroup` from the data item fields.
2177
- */
2178
- addEvent(group) {
2179
- const isFormGroup = group instanceof FormGroup;
2180
- if (!isFormGroup) {
2181
- const createControl = (source) => (acc, key) => {
2182
- acc[key] = new FormControl(source[key]);
2183
- return acc;
2184
- };
2185
- const fields = Object.keys(group).reduce(createControl(group), {});
2186
- group = new FormGroup(fields);
2012
+ return res1.every(r1 => res2.some(r2 => r2.value === r1.value));
2013
+ }
2014
+ /**
2015
+ * @hidden
2016
+ */
2017
+ function isSameRange(range1, range2) {
2018
+ return (range1.start.getTime() === range2.start.getTime() &&
2019
+ range1.end.getTime() === range2.end.getTime() &&
2020
+ range1.isAllDay === range2.isAllDay &&
2021
+ resourcesMatch(range1.resources, range2.resources, true));
2022
+ }
2023
+ /** @hidden */
2024
+ function findRowIndex(events, data) {
2025
+ if (data.rowIndex !== undefined) {
2026
+ return data.rowIndex;
2027
+ }
2028
+ for (let idx = 0; idx < events.length; idx++) {
2029
+ if (!events[idx]) {
2030
+ return idx;
2187
2031
  }
2188
- this.editService.addEvent(group);
2189
2032
  }
2190
- /**
2191
- * Switches the specified event in edit mode.
2192
- *
2193
- * @param dataItem - The event that will be switched to edit mode.
2194
- * @param options - An object which contains the form `group` that will be bound in the edit dialog and the current edit `mode`.
2195
- *
2196
- */
2197
- editEvent(dataItem, options = {}) {
2198
- const { group, mode } = options;
2199
- this.editService.editEvent(dataItem, group, mode);
2033
+ return events.length;
2034
+ }
2035
+ /** @hidden */
2036
+ function isRecurrence(task) {
2037
+ return Boolean(task.event && task.event.recurrenceRule);
2038
+ }
2039
+ /** @hidden */
2040
+ function isRecurrenceException(task) {
2041
+ return task.event && isPresent(task.event.recurrenceId) && !task.event.recurrenceRule;
2042
+ }
2043
+ /** @hidden */
2044
+ const rectContains = (rect, left, top) => rect.left <= left && left <= rect.left + rect.width && rect.top <= top && top <= rect.top + rect.height;
2045
+ /** @hidden */
2046
+ const rectContainsX = (rect, left) => rect.left <= left && left <= rect.left + rect.width;
2047
+ /** @hidden */
2048
+ const toPx = value => `${value}px`;
2049
+ /** @hidden */
2050
+ const elementOffset = (element) => {
2051
+ if (!element) {
2052
+ return null;
2200
2053
  }
2201
- /**
2202
- * Closes the event editor, if open.
2203
- */
2204
- closeEvent() {
2205
- this.editService.close();
2054
+ const box = element.getBoundingClientRect();
2055
+ const documentElement = document.documentElement;
2056
+ return {
2057
+ top: box.top + (window.pageYOffset || documentElement.scrollTop) - (documentElement.clientTop || 0),
2058
+ left: box.left + (window.pageXOffset || documentElement.scrollLeft) - (documentElement.clientLeft || 0),
2059
+ width: box.width,
2060
+ height: box.height
2061
+ };
2062
+ };
2063
+ /** @hidden */
2064
+ const pointDistance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
2065
+ /** @hidden */
2066
+ const ignoreContentChild = child => child.nodeName === 'KENDO-RESIZE-SENSOR' || hasClasses(child, 'k-loading-mask');
2067
+ /** @hidden */
2068
+ const setCoordinates = (element, coordinates) => {
2069
+ for (let field in coordinates) {
2070
+ if (coordinates.hasOwnProperty(field)) {
2071
+ element.style[field] = toPx(coordinates[field]);
2072
+ }
2206
2073
  }
2207
- /**
2208
- * Returns a flag which indicates if an event is currently edited.
2209
- *
2210
- * @return {boolean} - A flag which indicates if an event is currently edited.
2211
- */
2212
- isEditing() {
2213
- return this.editService.isEditing();
2074
+ };
2075
+ /** @hidden */
2076
+ const convertNgClassBindings = (bindingValues) => {
2077
+ const result = [];
2078
+ if (isString(bindingValues)) {
2079
+ result.push(bindingValues);
2214
2080
  }
2215
- /**
2216
- * Opens the built-in confirmation dialog for defining the edit mode
2217
- * that will be used when the user edits or removes a recurring event.
2218
- *
2219
- * @param operation - The type of operation that will be confirmed. Has to be either **Edit** or **Remove**.
2220
- *
2221
- * @return {Observable<EditMode>}
2222
- */
2223
- openRecurringConfirmationDialog(operation) {
2224
- return this.dialogsService.openRecurringConfirmationDialog(operation);
2081
+ else if (isArray(bindingValues)) {
2082
+ result.push.apply(result, bindingValues);
2225
2083
  }
2226
- /**
2227
- * Opens the built-in removal confirmation dialog.
2228
- *
2229
- * @return {Observable<boolean>}
2230
- */
2231
- openRemoveConfirmationDialog() {
2232
- return this.dialogsService.openRemoveConfirmationDialog();
2084
+ else if (isObject(bindingValues)) {
2085
+ for (let field in bindingValues) {
2086
+ if (bindingValues.hasOwnProperty(field) && bindingValues[field]) {
2087
+ result.push(field);
2088
+ }
2089
+ }
2233
2090
  }
2234
- /**
2235
- * Saves the current view as PDF.
2236
- */
2237
- saveAsPDF() {
2238
- this.loadingComponent.toggle(true);
2239
- this.zone.runOutsideAngular(() => {
2240
- // wait a tick in order for the loading element style to be updated by the browser.
2241
- // if the export is synchronous, the browser will not update the element before the export is finished.
2242
- setTimeout(() => {
2243
- this.pdfService.save();
2244
- }, 0);
2245
- });
2091
+ return result;
2092
+ };
2093
+ /**
2094
+ * @hidden
2095
+ */
2096
+ function formatEventTime(start, end, isAllDay, localeId) {
2097
+ const startTimeFormat = { skeleton: 'yMMMMEEEEdhm' };
2098
+ const startDateFormat = { skeleton: 'yMMMMEEEEd' };
2099
+ const endFormat = isEqualDate(start, end) ? 't' : startTimeFormat;
2100
+ return isAllDay ?
2101
+ `${formatDate(start, startDateFormat, localeId)}` :
2102
+ `${formatDate(start, startTimeFormat, localeId)}–${formatDate(end, endFormat, localeId)}`;
2103
+ }
2104
+ /**
2105
+ * @hidden
2106
+ */
2107
+ function formValueOrDefault(group, field, defaultValue) {
2108
+ const control = group.get(field);
2109
+ if (!control) {
2110
+ return defaultValue;
2246
2111
  }
2247
- /**
2248
- * Scrolls the view to the specified time.
2249
- */
2250
- scrollToTime(time) {
2251
- this.viewContext.notifyAction({
2252
- type: 'scroll-time',
2253
- time: time
2254
- });
2112
+ return control.value || defaultValue;
2113
+ }
2114
+ /**
2115
+ * @hidden
2116
+ */
2117
+ const isWorkWeekDay = (day, start, end) => {
2118
+ if (end < start) {
2119
+ return day <= end || start <= day;
2255
2120
  }
2256
- /**
2257
- * Returns the current view slot that matches the passed document position.
2258
- *
2259
- * @param x - The x document position.
2260
- * @param y - The y document position.
2261
- *
2262
- * @return {SchedulerSlot} - The slot.
2263
- *
2264
- * {% embed_file drag-and-drop/app.component.ts %}
2265
- * {% embed_file drag-and-drop/draggable.directive.ts %}
2266
- * {% embed_file drag-and-drop/app.module.ts %}
2267
- * {% embed_file shared/main.ts %}
2268
- */
2269
- slotByPosition(x, y) {
2270
- return this.viewContext.executeMethod('slotByPosition', { x, y });
2121
+ return start <= day && day <= end;
2122
+ };
2123
+ /**
2124
+ * @hidden
2125
+ */
2126
+ const alwaysFalse = () => false;
2127
+
2128
+ const todayDate = () => getDate(new Date());
2129
+ const DAYS_IN_WEEK = 7;
2130
+ /**
2131
+ * Represents the [Kendo UI Scheduler component for Angular]({% slug overview_scheduler %}).
2132
+ *
2133
+ * @example
2134
+ * ```ts-preview
2135
+ * _@Component({
2136
+ * selector: 'my-app',
2137
+ * template: `
2138
+ * <kendo-scheduler style="height: 600px">
2139
+ * <kendo-scheduler-day-view>
2140
+ * </kendo-scheduler-day-view>
2141
+ * <kendo-scheduler-week-view>
2142
+ * </kendo-scheduler-week-view>
2143
+ * </kendo-scheduler>
2144
+ * `
2145
+ * })
2146
+ * class AppComponent {}
2147
+ * ```
2148
+ */
2149
+ let SchedulerComponent = class SchedulerComponent {
2150
+ constructor(wrapper, viewContext, viewState, editService, dialogsService, intlService, changeDetector, zone, pdfService, localization, domEvents, renderer, focusService) {
2151
+ this.wrapper = wrapper;
2152
+ this.viewContext = viewContext;
2153
+ this.viewState = viewState;
2154
+ this.editService = editService;
2155
+ this.dialogsService = dialogsService;
2156
+ this.intlService = intlService;
2157
+ this.changeDetector = changeDetector;
2158
+ this.zone = zone;
2159
+ this.pdfService = pdfService;
2160
+ this.localization = localization;
2161
+ this.domEvents = domEvents;
2162
+ this.renderer = renderer;
2163
+ this.focusService = focusService;
2164
+ this.hostClasses = true;
2165
+ this.rtl = false;
2166
+ /**
2167
+ * Specifies if the Scheduler is editable.
2168
+ */
2169
+ this.editable = false;
2170
+ /**
2171
+ * Specifies if the Scheduler's day or time slots are selectable ([see example]({% slug slotselection_scheduler %}#toc-custom-callback)).
2172
+ *
2173
+ * When this input is set to `true`, the Scheduler component will emit [`slotDragStart`]({% slug api_scheduler_schedulercomponent %}#toc-slotdragstart), [`slotDrag`]({% slug api_scheduler_schedulercomponent %}#toc-slotdrag), and [`slotDragEnd`]({% slug api_scheduler_schedulercomponent %}#toc-slotdragend) events upon user interaction.
2174
+ */
2175
+ this.selectable = false;
2176
+ /**
2177
+ * The height of the events in the **Month** and **Timeline** views, and the height of the **All day** events in the **Day** and **Week** views.
2178
+ */
2179
+ this.eventHeight = 25;
2180
+ /**
2181
+ * Specifies the columns width. Applicable for the **Timeline** views.
2182
+ */
2183
+ this.columnWidth = 100;
2184
+ /**
2185
+ * The start time of the view. The Scheduler displays events which start after the start time.
2186
+ * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
2187
+ */
2188
+ this.startTime = '00:00';
2189
+ /**
2190
+ * The end time of the view. The Scheduler displays events which end before the end time.
2191
+ * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
2192
+ */
2193
+ this.endTime = '00:00';
2194
+ /**
2195
+ * The start time of the view when `showWorkHours` is set to `true`.
2196
+ * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
2197
+ */
2198
+ this.workDayStart = '08:00';
2199
+ /**
2200
+ * The end time of the view when `showWorkHours` is set to `true`.
2201
+ * Accepts string values in the `HH:mm` format. Applicable for the **Day**, **Week**, and **Timeline** views.
2202
+ */
2203
+ this.workDayEnd = '17:00';
2204
+ /**
2205
+ * The duration (in minutes) of the time slots. Applicable for the day, week and timeline views.
2206
+ */
2207
+ this.slotDuration = 60;
2208
+ /**
2209
+ * The number of divisions of the time slots. Applicable for the **Day**, **Week**, and **Timeline** views.
2210
+ */
2211
+ this.slotDivisions = 2;
2212
+ /**
2213
+ * A numeric value between 0 and 1 that specifies what percentage of the slot will be filled by the events.
2214
+ * Applicable for the **Day** and **Week** views.
2215
+ * Defaults to `0.9` (90% fill).
2216
+ */
2217
+ this.slotFill = 0.9;
2218
+ /**
2219
+ * The time to which the view will initially be scrolled.
2220
+ * Accepts string values in the `HH:mm` format or a JavaScript `Date`. Applicable for the **Day**, **Week**, and **Timeline** views.
2221
+ */
2222
+ this.scrollTime = this.workDayStart;
2223
+ /**
2224
+ * Specifies the Scheduler current time marker settings.
2225
+ */
2226
+ this.currentTimeMarker = true;
2227
+ /**
2228
+ * A callback that executes for each slot of the Scheduler view.
2229
+ * If it returns `true`, the `k-state-selected` CSS class will be added to the cell, making it visibly selected.
2230
+ */
2231
+ this.isSlotSelected = alwaysFalse;
2232
+ /**
2233
+ * @hidden
2234
+ */
2235
+ this.selectedViewIndexChange = new EventEmitter();
2236
+ /**
2237
+ * Fires when the Scheduler is about to execute a navigation action
2238
+ * (a view, date, or focus change).
2239
+ */
2240
+ this.navigate = new EventEmitter();
2241
+ /**
2242
+ * Fires when the date range that is displayed in the Scheduler changes.
2243
+ */
2244
+ this.dateChange = new EventEmitter();
2245
+ /**
2246
+ * Fires when a Scheduler view slot is clicked.
2247
+ */
2248
+ this.slotClick = new EventEmitter();
2249
+ /**
2250
+ * Fires when a Scheduler view slot is double-clicked.
2251
+ */
2252
+ this.slotDblClick = new EventEmitter();
2253
+ /**
2254
+ * Fires when the user creates a new event using the `'c'` key.
2255
+ * ([see example]({% slug keyboard_navigation_scheduler %})).
2256
+ */
2257
+ this.create = new EventEmitter();
2258
+ /**
2259
+ * Fires when a Scheduler event is clicked.
2260
+ */
2261
+ this.eventClick = new EventEmitter();
2262
+ /**
2263
+ * Fires when a Scheduler event is double-clicked.
2264
+ */
2265
+ this.eventDblClick = new EventEmitter();
2266
+ /**
2267
+ * Fires when a key is pressed on a focused Scheduler event.
2268
+ */
2269
+ this.eventKeydown = new EventEmitter();
2270
+ /**
2271
+ * Fires when the user cancels the editing by clicking the **Cancel** command button.
2272
+ */
2273
+ this.cancel = new EventEmitter();
2274
+ /**
2275
+ * Fires when the user clicks the **Save** command button to save the changes of the edited event.
2276
+ */
2277
+ this.save = new EventEmitter();
2278
+ /**
2279
+ * Fires when the user clicks the **Remove** icon of a Scheduler event.
2280
+ */
2281
+ this.remove = new EventEmitter();
2282
+ /**
2283
+ * Fires when the user starts resizing a Scheduler event.
2284
+ */
2285
+ this.resizeStart = new EventEmitter();
2286
+ /**
2287
+ * Fires when the user is resizing a Scheduler event.
2288
+ */
2289
+ this.resize = new EventEmitter();
2290
+ /**
2291
+ * Fires when the user stops resizing a Scheduler event.
2292
+ */
2293
+ this.resizeEnd = new EventEmitter();
2294
+ /**
2295
+ * Fires when the user starts dragging a Scheduler event.
2296
+ */
2297
+ this.dragStart = new EventEmitter();
2298
+ /**
2299
+ * Fires when the user is dragging a Scheduler event.
2300
+ */
2301
+ this.drag = new EventEmitter();
2302
+ /**
2303
+ * Fires when the user stops dragging a Scheduler event.
2304
+ */
2305
+ this.dragEnd = new EventEmitter();
2306
+ /**
2307
+ * Fires when the user starts drag-selecting a Scheduler slot range.
2308
+ */
2309
+ this.slotDragStart = new EventEmitter();
2310
+ /**
2311
+ * Fires when the user is drag-selecting a Scheduler slot range.
2312
+ */
2313
+ this.slotDrag = new EventEmitter();
2314
+ /**
2315
+ * Fires when the user stops drag-selecting a Scheduler slot range.
2316
+ */
2317
+ this.slotDragEnd = new EventEmitter();
2318
+ /**
2319
+ * Fires when the user clicks the **PDF export** command button.
2320
+ */
2321
+ this.pdfExport = new EventEmitter();
2322
+ /**
2323
+ * @hidden
2324
+ */
2325
+ this.dragEndConfirmed = new EventEmitter();
2326
+ /**
2327
+ * @hidden
2328
+ */
2329
+ this.resizeEndConfirmed = new EventEmitter();
2330
+ /**
2331
+ * @hidden
2332
+ */
2333
+ this.removeConfirmed = new EventEmitter();
2334
+ this.viewIndex = 0;
2335
+ this._timezone = '';
2336
+ this._modelFields = defaultModelFields;
2337
+ validatePackage(packageMetadata);
2338
+ this.dateRangeStream = viewState.dateRange;
2339
+ this.selectedDateStream = viewContext.selectedDate;
2340
+ }
2341
+ get dir() {
2342
+ return this.direction;
2271
2343
  }
2272
2344
  /**
2273
- * Returns the event associated with the specified DOM element, if any.
2345
+ * The index of the currently selected view.
2274
2346
  *
2275
- * @param element - The DOM element document position.
2276
- * @return the event instance, if found.
2347
+ * By default, the selected view index is `0` and
2348
+ * indicates that the first declared view is visible.
2277
2349
  */
2278
- eventFromElement(element) {
2279
- return this.viewContext.executeMethod('eventFromElement', { element });
2350
+ set selectedViewIndex(index) {
2351
+ this.viewIndex = index;
2352
+ this.onViewIndexChange();
2353
+ }
2354
+ get selectedViewIndex() {
2355
+ return this.viewIndex;
2280
2356
  }
2281
2357
  /**
2282
- * Gets the currently active event, if any.
2283
- * The active event is the event that can currently receive focus.
2358
+ * The first day of the week. Applicable to **Week**, **Month** and **TimelineWeek** views.
2359
+ * Defaults to the locale settings.
2284
2360
  */
2285
- get activeEvent() {
2286
- const activeElement = this.focusService.activeElement;
2287
- if (activeElement) {
2288
- return this.eventFromElement(activeElement.nativeElement);
2361
+ set weekStart(value) {
2362
+ this._weekStart = value;
2363
+ }
2364
+ get weekStart() {
2365
+ if (isPresent(this._weekStart)) {
2366
+ return this._weekStart;
2289
2367
  }
2368
+ return this.intlService.firstDay();
2290
2369
  }
2291
2370
  /**
2292
- * Focuses the next event or an event at a specified relative position.
2293
- * The `options` parameter can be used to set a positive or negative offset
2294
- * that is relative to the currently focused event.
2295
- * A `nowrap` flag toggles the wrapping to the first or to the last item.
2296
- *
2297
- * @example
2298
- * ```ts-no-run
2299
- * scheduler.focusNext(); // Focuses the next event.
2300
- * scheduler.focusNext({ offset: 1 }); // Focuses the next event.
2301
- * scheduler.focusNext({ offset: -1 }); // Focuses the previous event.
2302
- * scheduler.focusNext({ nowrap: true }); // If the focus is on the last event, does not move the focus to the first event.
2303
- * ```
2304
- *
2305
- * @param position The relative position of the event to focus.
2306
- * @returns `true` if the focused event changed. Otherwise, returns `false`.
2371
+ * Specifies the id of the timezone that will be displayed in the Scheduler.
2372
+ * For example, `Europe/Sofia`.
2373
+ * Defaults to `Etc/UTC`.
2307
2374
  */
2308
- focusNext(position) {
2309
- return this.focusService.focusNext(position);
2375
+ set timezone(value) {
2376
+ this._timezone = value;
2377
+ this.events = this.events || [];
2378
+ }
2379
+ get timezone() {
2380
+ return this._timezone;
2310
2381
  }
2311
2382
  /**
2312
- * Focuses the previous event or an event at a specified relative position.
2313
- * The `options` parameter can be used to set a positive or negative offset
2314
- * that is relative to the currently focused event.
2315
- * A `nowrap` flag toggles the wrapping to the first or to the last item.
2316
- *
2317
- * @example
2318
- * ```ts-no-run
2319
- * scheduler.focusPrev(); // Focuses the previous event
2320
- * scheduler.focusPrev({ nowrap: true }); // Does not move the focus to the last event, if focus is on the first one.
2321
- * ```
2322
- *
2323
- * @param position The relative position of the event to focus.
2324
- * @returns `true` if the focused event changed. Otherwise, returns `false`.
2383
+ * An array of event instances which will be shown by the Scheduler.
2325
2384
  */
2326
- focusPrev(position) {
2327
- const prevPosition = Object.assign({ offset: -1 }, position);
2328
- return this.focusService.focusNext(prevPosition);
2385
+ set events(value) {
2386
+ this._events = value;
2387
+ this.processEvents(value);
2388
+ }
2389
+ get events() {
2390
+ return this._events;
2329
2391
  }
2330
2392
  /**
2331
- * Focuses the last focused event or the Scheduler element, if no events are available.
2393
+ * The currently selected date of the Scheduler.
2394
+ * Determines the period which is displayed.
2332
2395
  */
2333
- focus() {
2334
- return this.focusService.focus();
2396
+ set selectedDate(value) {
2397
+ if (!value) {
2398
+ return;
2399
+ }
2400
+ this._selectedDate = value;
2401
+ this.viewContext.notifySelectedDate(value);
2335
2402
  }
2336
- isInRange(date) {
2337
- return (!this.min || this.min <= date) && (!this.max || date <= this.max);
2403
+ get selectedDate() {
2404
+ return this._selectedDate;
2338
2405
  }
2339
- notifyOptionsChange(changes) {
2340
- const workweek = this.workWeek;
2341
- this.viewContext.notifyOptionsChange({
2342
- group: this.group,
2343
- resources: this.resources,
2344
- allDayEventTemplate: this.allDayEventTemplate ? this.allDayEventTemplate.first : null,
2345
- eventTemplate: this.eventTemplate ? this.eventTemplate.first : null,
2346
- timeSlotTemplate: this.timeSlotTemplate ? this.timeSlotTemplate.first : null,
2347
- minorTimeHeaderTemplate: this.minorTimeHeaderTemplate ? this.minorTimeHeaderTemplate.first : null,
2348
- majorTimeHeaderTemplate: this.majorTimeHeaderTemplate ? this.majorTimeHeaderTemplate.first : null,
2349
- monthDaySlotTemplate: this.monthDaySlotTemplate ? this.monthDaySlotTemplate.first : null,
2350
- dateHeaderTemplate: this.dateHeaderTemplate ? this.dateHeaderTemplate.first : null,
2351
- allDaySlotTemplate: this.allDaySlotTemplate ? this.allDaySlotTemplate.first : null,
2352
- groupHeaderTemplate: this.groupHeaderTemplate ? this.groupHeaderTemplate.first : null,
2353
- agendaDateTemplate: this.agendaDateTemplate ? this.agendaDateTemplate.first : null,
2354
- agendaTimeTemplate: this.agendaTimeTemplate ? this.agendaTimeTemplate.first : null,
2355
- min: this.min,
2356
- max: this.max,
2357
- showWorkHours: this.showWorkHours,
2358
- startTime: this.startTime,
2359
- scrollTime: this.scrollTime,
2360
- endTime: this.endTime,
2361
- workDayStart: this.workDayStart,
2362
- workDayEnd: this.workDayEnd,
2363
- workWeekStart: workweek.start,
2364
- workWeekEnd: workweek.end,
2365
- weekStart: this.weekStart,
2366
- slotDuration: this.slotDuration,
2367
- slotDivisions: this.slotDivisions,
2368
- eventHeight: this.eventHeight,
2369
- editable: this.editable,
2370
- timezone: this.timezone,
2371
- currentTimeMarker: this.currentTimeMarker,
2372
- slotClass: this.slotClass,
2373
- slotFill: this.slotFill,
2374
- columnWidth: this.columnWidth,
2375
- eventClass: this.eventClass,
2376
- eventStyles: this.eventStyles,
2377
- changes: changes
2378
- });
2406
+ /**
2407
+ * The names of the model fields from which the Scheduler will read its data
2408
+ * ([see example]({% slug databinding_scheduler %}#toc-binding-to-models)).
2409
+ */
2410
+ set modelFields(value) {
2411
+ this._modelFields = Object.assign({}, defaultModelFields, value);
2379
2412
  }
2380
- get workWeek() {
2381
- let { start, end } = this.intlService.weekendRange();
2382
- const workWeekStart = isPresent(this.workWeekStart) ? this.workWeekStart : (end + 1) % DAYS_IN_WEEK;
2383
- const weekEnd = start > 0 ? start - 1 : Day.Saturday;
2384
- const workWeekEnd = isPresent(this.workWeekEnd) ? this.workWeekEnd : weekEnd;
2385
- return { start: workWeekStart, end: workWeekEnd };
2413
+ get modelFields() {
2414
+ return this._modelFields;
2386
2415
  }
2387
- resetViewIndex() {
2388
- const index = this.selectedViewIndex;
2389
- const newIndex = Math.max(0, Math.min(index, this.views.length - 1));
2390
- this.setViewIndex(newIndex);
2416
+ ngOnInit() {
2417
+ if (!this.selectedDate) {
2418
+ this.selectedDate = todayDate();
2419
+ }
2420
+ }
2421
+ ngAfterContentInit() {
2422
+ if (isDevMode() && this.views.length === 0) {
2423
+ throw new Error('No views declared for <kendo-scheduler>. Please, declare at least one view.');
2424
+ }
2425
+ this.subs = this.views.changes.subscribe(() => this.resetViewIndex());
2426
+ this.subs.add(this.intlService.changes.subscribe(this.intlChange.bind(this)));
2427
+ this.subs.add(this.viewState.nextDate.subscribe(nextDate => {
2428
+ this.selectedDate = nextDate;
2429
+ }));
2430
+ this.subs.add(this.viewState.dateRange.subscribe(dateRange => {
2431
+ const isEmpty = dateRange.start.getTime() === 0;
2432
+ if (!isEmpty) {
2433
+ const args = new DateChangeEvent(this, this.selectedDate, dateRange);
2434
+ this.dateChange.emit(args);
2435
+ }
2436
+ }));
2437
+ this.subs.add(this.viewState.navigate.subscribe(({ viewName, date }) => {
2438
+ const views = this.views.toArray();
2439
+ const view = views.find(v => v.name === viewName);
2440
+ const args = new NavigateEvent(this, {
2441
+ type: 'show-date',
2442
+ view: view || {
2443
+ name: viewName,
2444
+ title: viewName
2445
+ },
2446
+ date: date
2447
+ });
2448
+ this.navigate.next(args);
2449
+ if (view && !args.isDefaultPrevented()) {
2450
+ const index = views.indexOf(view);
2451
+ this.selectedView = view;
2452
+ this.setViewIndex(index);
2453
+ this.selectedDate = date;
2454
+ }
2455
+ }));
2456
+ this.subs.add(this.viewState.viewEvent.subscribe(({ name, args }) => {
2457
+ const emitter = this[name];
2458
+ const confirmedEmitter = this[`${name}Confirmed`];
2459
+ if (hasObservers(emitter) || (confirmedEmitter && hasObservers(confirmedEmitter))) {
2460
+ this.zone.run(() => {
2461
+ const eventInstance = new VIEW_EVENT_MAP[name](this, args);
2462
+ emitter.emit(eventInstance);
2463
+ args.prevented = eventInstance.prevented;
2464
+ if (confirmedEmitter && !args.prevented) {
2465
+ confirmedEmitter.emit(eventInstance);
2466
+ }
2467
+ });
2468
+ }
2469
+ }));
2470
+ this.subs.add(this.viewState.layoutEnd.subscribe(() => {
2471
+ if (this.resizeSensor) {
2472
+ this.resizeSensor.acceptSize();
2473
+ }
2474
+ }));
2475
+ this.subs.add(this.viewState.slotSelectionStart
2476
+ .subscribe((e) => {
2477
+ if (hasObservers(this.slotDragStart)) {
2478
+ this.zone.run(() => {
2479
+ this.slotDragStart.emit(Object.assign(e, { sender: this }));
2480
+ });
2481
+ }
2482
+ }));
2483
+ this.subs.add(this.viewState.slotSelectionDrag
2484
+ .subscribe((value) => {
2485
+ if (hasObservers(this.slotDrag)) {
2486
+ this.zone.run(() => {
2487
+ this.slotDrag.emit(new SlotDragEvent(this, value));
2488
+ });
2489
+ }
2490
+ }));
2491
+ this.subs.add(this.viewState.slotSelectionEnd
2492
+ .subscribe((value) => {
2493
+ if (hasObservers(this.slotDragEnd)) {
2494
+ this.zone.run(() => {
2495
+ this.slotDragEnd.emit(new SlotDragEndEvent(this, value));
2496
+ });
2497
+ }
2498
+ }));
2391
2499
  this.onViewIndexChange();
2500
+ this.notifyOptionsChange = this.notifyOptionsChange.bind(this);
2501
+ this.subs.add(this.allDayEventTemplate.changes.subscribe(this.notifyOptionsChange));
2502
+ this.subs.add(this.eventTemplate.changes.subscribe(this.notifyOptionsChange));
2503
+ this.subs.add(this.timeSlotTemplate.changes.subscribe(this.notifyOptionsChange));
2504
+ this.subs.add(this.timeSlotTemplate.changes.subscribe(this.notifyOptionsChange));
2505
+ this.subs.add(this.minorTimeHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2506
+ this.subs.add(this.majorTimeHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2507
+ this.subs.add(this.monthDaySlotTemplate.changes.subscribe(this.notifyOptionsChange));
2508
+ this.subs.add(this.dateHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2509
+ this.subs.add(this.allDaySlotTemplate.changes.subscribe(this.notifyOptionsChange));
2510
+ this.subs.add(this.groupHeaderTemplate.changes.subscribe(this.notifyOptionsChange));
2511
+ this.subs.add(this.agendaDateTemplate.changes.subscribe(this.notifyOptionsChange));
2512
+ this.subs.add(this.agendaTimeTemplate.changes.subscribe(this.notifyOptionsChange));
2513
+ this.subs.add(this.views.changes.subscribe(() => {
2514
+ this.changeDetector.markForCheck();
2515
+ }));
2516
+ //this.editService.timezone = this.timezone;
2517
+ this.attachEditHandlers();
2518
+ this.dialogsService.container = this.confirmationDialogContainerRef;
2519
+ this.notifyOptionsChange();
2520
+ this.subs.add(this.pdfService.exportClick.subscribe(() => {
2521
+ const args = new PDFExportEvent();
2522
+ this.pdfExport.emit(args);
2523
+ if (!args.isDefaultPrevented()) {
2524
+ this.saveAsPDF();
2525
+ }
2526
+ }));
2527
+ this.subs.add(this.pdfService.done.subscribe(() => {
2528
+ this.loadingComponent.toggle(false);
2529
+ }));
2530
+ this.subs.add(this.localization.changes.subscribe(({ rtl }) => {
2531
+ this.rtl = rtl;
2532
+ this.direction = this.rtl ? 'rtl' : 'ltr';
2533
+ }));
2534
+ this.subs.add(this.viewState.optionsChange.subscribe(() => {
2535
+ this.changeDetector.markForCheck();
2536
+ }));
2537
+ this.attachElementEventHandlers();
2392
2538
  }
2393
- onViewIndexChange() {
2394
- if (!this.views) {
2395
- return;
2539
+ ngOnChanges(changes) {
2540
+ if (isChanged('resources', changes) && !isChanged('events', changes) && this.viewItems) {
2541
+ this.viewItems.forEach(item => {
2542
+ copyResources(item.event, this.resources);
2543
+ });
2396
2544
  }
2397
- const views = this.views.toArray();
2398
- const selectedView = views[this.viewIndex];
2399
- if (selectedView) {
2400
- this.selectedView = selectedView;
2545
+ if (anyChanged([
2546
+ 'group', 'resources', 'min', 'max', 'showWorkHours', 'startTime', 'scrollTime', 'endTime', 'eventHeight',
2547
+ 'workDayStart', 'workDayEnd', 'workWeekStart', 'workWeekEnd', 'weekStart', 'slotDuration', 'slotDivisions',
2548
+ 'editable', 'timezone', 'slotClass', 'slotFill', 'columnWidth', 'eventClass', 'eventStyles', 'isSlotSelected', 'selectable'
2549
+ ], changes)) {
2550
+ this.notifyOptionsChange(changes);
2401
2551
  }
2402
2552
  }
2403
- setViewIndex(newIndex) {
2404
- const changed = this.selectedViewIndex !== newIndex;
2405
- if (changed) {
2406
- this.selectedViewIndex = newIndex;
2407
- this.selectedViewIndexChange.emit(newIndex);
2553
+ ngOnDestroy() {
2554
+ if (this.subs) {
2555
+ this.subs.unsubscribe();
2556
+ }
2557
+ if (this.detachElementEventHandlers) {
2558
+ this.detachElementEventHandlers();
2408
2559
  }
2409
- return changed;
2410
2560
  }
2411
- processEvents(dataItems) {
2412
- const timezone = this.timezone;
2413
- const fields = this.modelFields;
2414
- const items = dataItems
2415
- .map(dataItem => readEvent(dataItem, fields, this.resources))
2416
- .filter(event => !isRecurrenceMaster(event))
2417
- .map(event => {
2418
- const start = ZonedDate.fromLocalDate(event.start, timezone);
2419
- const end = ZonedDate.fromLocalDate(event.end, timezone);
2420
- return { start, end, event };
2421
- });
2422
- this.viewItems = items;
2423
- this.viewContext.notifyItems(items);
2561
+ /**
2562
+ * @hidden
2563
+ */
2564
+ onResize(_event) {
2565
+ this.viewContext.notifyResize();
2424
2566
  }
2425
- attachEditHandlers() {
2426
- if (!this.editService) {
2427
- return;
2567
+ /**
2568
+ * @hidden
2569
+ */
2570
+ onNavigationAction(action) {
2571
+ const args = new NavigateEvent(this, action);
2572
+ this.navigate.next(args);
2573
+ if (args.isDefaultPrevented()) {
2574
+ return true;
2428
2575
  }
2429
- this.subs.add(this.editService.changes.subscribe(this.emitCRUDEvent.bind(this)));
2430
- }
2431
- emitCRUDEvent(args) {
2432
- Object.assign(args, { sender: this });
2433
- switch (args.action) {
2434
- case 'cancel':
2435
- this.cancel.emit(args);
2436
- break;
2437
- case 'save':
2438
- this.save.emit(args);
2439
- break;
2440
- default: break;
2576
+ if (action.type === 'view-change') {
2577
+ const views = this.views.toArray();
2578
+ const index = views.indexOf(action.view);
2579
+ this.selectedView = action.view;
2580
+ this.setViewIndex(index);
2441
2581
  }
2442
- }
2443
- intlChange() {
2444
- const currentView = this.selectedView;
2445
- this.selectedView = null;
2446
- if (!isPresent(this.workWeekStart) || !isPresent(this.workWeekEnd)) {
2447
- this.notifyOptionsChange();
2582
+ else if (action.type === 'select-date') {
2583
+ if (this.isInRange(action.date)) {
2584
+ this.selectedDate = action.date;
2585
+ }
2448
2586
  }
2449
- this.changeDetector.detectChanges();
2450
- this.selectedView = currentView;
2451
- if (NgZone.isInAngularZone()) {
2452
- this.changeDetector.markForCheck();
2587
+ else if (action.type === 'today') {
2588
+ const date = new Date();
2589
+ if (this.isInRange(date)) {
2590
+ this.selectedDate = date;
2591
+ }
2453
2592
  }
2454
2593
  else {
2455
- this.changeDetector.detectChanges();
2594
+ this.viewContext.notifyAction(action);
2456
2595
  }
2457
2596
  }
2458
- attachElementEventHandlers() {
2459
- if (!isDocumentAvailable()) {
2460
- return;
2597
+ /**
2598
+ * Creates a popup editor for the new event.
2599
+ *
2600
+ * @param group - The [`FormGroup`](https://angular.io/docs/ts/latest/api/forms/index/FormGroup-class.html) that describes
2601
+ * the edit form. If called with a data item, the parameter will build the `FormGroup` from the data item fields.
2602
+ */
2603
+ addEvent(group) {
2604
+ const isFormGroup = group instanceof FormGroup;
2605
+ if (!isFormGroup) {
2606
+ const createControl = (source) => (acc, key) => {
2607
+ acc[key] = new FormControl(source[key]);
2608
+ return acc;
2609
+ };
2610
+ const fields = Object.keys(group).reduce(createControl(group), {});
2611
+ group = new FormGroup(fields);
2461
2612
  }
2462
- const wrapper = this.wrapper.nativeElement;
2613
+ this.editService.addEvent(group);
2614
+ }
2615
+ /**
2616
+ * Switches the specified event in edit mode.
2617
+ *
2618
+ * @param dataItem - The event that will be switched to edit mode.
2619
+ * @param options - An object which contains the form `group` that will be bound in the edit dialog and the current edit `mode`.
2620
+ *
2621
+ */
2622
+ editEvent(dataItem, options = {}) {
2623
+ const { group, mode } = options;
2624
+ this.editService.editEvent(dataItem, group, mode);
2625
+ }
2626
+ /**
2627
+ * Closes the event editor, if open.
2628
+ */
2629
+ closeEvent() {
2630
+ this.editService.close();
2631
+ }
2632
+ /**
2633
+ * Returns a flag which indicates if an event is currently edited.
2634
+ *
2635
+ * @return {boolean} - A flag which indicates if an event is currently edited.
2636
+ */
2637
+ isEditing() {
2638
+ return this.editService.isEditing();
2639
+ }
2640
+ /**
2641
+ * Opens the built-in confirmation dialog for defining the edit mode
2642
+ * that will be used when the user edits or removes a recurring event.
2643
+ *
2644
+ * @param operation - The type of operation that will be confirmed. Has to be either **Edit** or **Remove**.
2645
+ *
2646
+ * @return {Observable<EditMode>}
2647
+ */
2648
+ openRecurringConfirmationDialog(operation) {
2649
+ return this.dialogsService.openRecurringConfirmationDialog(operation);
2650
+ }
2651
+ /**
2652
+ * Opens the built-in removal confirmation dialog.
2653
+ *
2654
+ * @return {Observable<boolean>}
2655
+ */
2656
+ openRemoveConfirmationDialog() {
2657
+ return this.dialogsService.openRemoveConfirmationDialog();
2658
+ }
2659
+ /**
2660
+ * Saves the current view as PDF.
2661
+ */
2662
+ saveAsPDF() {
2663
+ this.loadingComponent.toggle(true);
2463
2664
  this.zone.runOutsideAngular(() => {
2464
- const windowBlurSubscription = this.renderer.listen('window', 'blur', (args) => {
2465
- this.domEvents.windowBlur.emit(args);
2466
- });
2467
- const clickSubscription = this.renderer.listen(wrapper, 'click', (args) => {
2468
- this.domEvents.click.emit(args);
2469
- });
2470
- const keydownSubscription = this.renderer.listen(wrapper, 'keydown', args => {
2471
- this.domEvents.keydown.emit(args);
2472
- });
2473
- let focused = false;
2474
- const focusInSubscription = this.renderer.listen(wrapper, 'focusin', (args) => {
2475
- this.domEvents.focus.emit(args);
2476
- if (!focused) {
2477
- this.domEvents.focusIn.emit(args);
2478
- this.renderer.addClass(this.wrapper.nativeElement, 'k-state-focused');
2479
- focused = true;
2480
- }
2481
- });
2482
- const focusOutSubscription = this.renderer.listen(wrapper, 'focusout', (args) => {
2483
- const next = args.relatedTarget || document.activeElement;
2484
- const outside = !closest(next, (node) => node === wrapper);
2485
- if (outside) {
2486
- this.domEvents.focusOut.emit(args);
2487
- this.renderer.removeClass(this.wrapper.nativeElement, 'k-state-focused');
2488
- focused = false;
2489
- }
2490
- });
2491
- this.detachElementEventHandlers = () => {
2492
- windowBlurSubscription();
2493
- clickSubscription();
2494
- keydownSubscription();
2495
- focusInSubscription();
2496
- focusOutSubscription();
2497
- };
2665
+ // wait a tick in order for the loading element style to be updated by the browser.
2666
+ // if the export is synchronous, the browser will not update the element before the export is finished.
2667
+ setTimeout(() => {
2668
+ this.pdfService.save();
2669
+ }, 0);
2498
2670
  });
2499
2671
  }
2500
- };
2501
- __decorate([
2502
- HostBinding('class.k-widget'),
2503
- HostBinding('class.k-scheduler'),
2504
- HostBinding('class.k-floatwrap'),
2505
- __metadata("design:type", Boolean)
2506
- ], SchedulerComponent.prototype, "hostClasses", void 0);
2507
- __decorate([
2508
- HostBinding('class.k-rtl'),
2509
- __metadata("design:type", Boolean)
2510
- ], SchedulerComponent.prototype, "rtl", void 0);
2511
- __decorate([
2512
- HostBinding('attr.dir'),
2513
- __metadata("design:type", String),
2514
- __metadata("design:paramtypes", [])
2515
- ], SchedulerComponent.prototype, "dir", null);
2516
- __decorate([
2517
- Input(),
2518
- __metadata("design:type", Number),
2519
- __metadata("design:paramtypes", [Number])
2520
- ], SchedulerComponent.prototype, "selectedViewIndex", null);
2521
- __decorate([
2522
- Input(),
2523
- __metadata("design:type", Object)
2524
- ], SchedulerComponent.prototype, "editable", void 0);
2525
- __decorate([
2526
- Input(),
2527
- __metadata("design:type", Date)
2528
- ], SchedulerComponent.prototype, "min", void 0);
2529
- __decorate([
2530
- Input(),
2531
- __metadata("design:type", Date)
2532
- ], SchedulerComponent.prototype, "max", void 0);
2533
- __decorate([
2534
- Input(),
2535
- __metadata("design:type", Number)
2536
- ], SchedulerComponent.prototype, "eventHeight", void 0);
2537
- __decorate([
2538
- Input(),
2539
- __metadata("design:type", Number)
2540
- ], SchedulerComponent.prototype, "columnWidth", void 0);
2541
- __decorate([
2542
- Input(),
2543
- __metadata("design:type", Boolean)
2544
- ], SchedulerComponent.prototype, "showWorkHours", void 0);
2545
- __decorate([
2546
- Input(),
2547
- __metadata("design:type", String)
2548
- ], SchedulerComponent.prototype, "startTime", void 0);
2549
- __decorate([
2550
- Input(),
2551
- __metadata("design:type", String)
2552
- ], SchedulerComponent.prototype, "endTime", void 0);
2553
- __decorate([
2554
- Input(),
2555
- __metadata("design:type", String)
2556
- ], SchedulerComponent.prototype, "workDayStart", void 0);
2557
- __decorate([
2558
- Input(),
2559
- __metadata("design:type", String)
2560
- ], SchedulerComponent.prototype, "workDayEnd", void 0);
2561
- __decorate([
2562
- Input(),
2563
- __metadata("design:type", Number)
2564
- ], SchedulerComponent.prototype, "workWeekStart", void 0);
2565
- __decorate([
2566
- Input(),
2567
- __metadata("design:type", Number)
2568
- ], SchedulerComponent.prototype, "workWeekEnd", void 0);
2569
- __decorate([
2570
- Input(),
2571
- __metadata("design:type", Number),
2572
- __metadata("design:paramtypes", [Number])
2573
- ], SchedulerComponent.prototype, "weekStart", null);
2574
- __decorate([
2575
- Input(),
2576
- __metadata("design:type", Number)
2577
- ], SchedulerComponent.prototype, "slotDuration", void 0);
2578
- __decorate([
2579
- Input(),
2580
- __metadata("design:type", Number)
2581
- ], SchedulerComponent.prototype, "slotDivisions", void 0);
2582
- __decorate([
2583
- Input(),
2584
- __metadata("design:type", Number)
2585
- ], SchedulerComponent.prototype, "slotFill", void 0);
2672
+ /**
2673
+ * Scrolls the view to the specified time.
2674
+ */
2675
+ scrollToTime(time) {
2676
+ this.viewContext.notifyAction({
2677
+ type: 'scroll-time',
2678
+ time: time
2679
+ });
2680
+ }
2681
+ /**
2682
+ * Returns the current view slot that matches the passed document position.
2683
+ *
2684
+ * @param x - The x document position.
2685
+ * @param y - The y document position.
2686
+ *
2687
+ * @return {SchedulerSlot} - The slot.
2688
+ *
2689
+ * {% embed_file drag-and-drop/app.component.ts %}
2690
+ * {% embed_file drag-and-drop/draggable.directive.ts %}
2691
+ * {% embed_file drag-and-drop/app.module.ts %}
2692
+ * {% embed_file shared/main.ts %}
2693
+ */
2694
+ slotByPosition(x, y) {
2695
+ return this.viewContext.executeMethod('slotByPosition', { x, y });
2696
+ }
2697
+ /**
2698
+ * Returns the event associated with the specified DOM element, if any.
2699
+ *
2700
+ * @param element - The DOM element document position.
2701
+ * @return the event instance, if found.
2702
+ */
2703
+ eventFromElement(element) {
2704
+ return this.viewContext.executeMethod('eventFromElement', { element });
2705
+ }
2706
+ /**
2707
+ * Gets the currently active event, if any.
2708
+ * The active event is the event that can currently receive focus.
2709
+ */
2710
+ get activeEvent() {
2711
+ const activeElement = this.focusService.activeElement;
2712
+ if (activeElement) {
2713
+ return this.eventFromElement(activeElement.nativeElement);
2714
+ }
2715
+ }
2716
+ /**
2717
+ * Focuses the next event or an event at a specified relative position.
2718
+ * The `options` parameter can be used to set a positive or negative offset
2719
+ * that is relative to the currently focused event.
2720
+ * A `nowrap` flag toggles the wrapping to the first or to the last item.
2721
+ *
2722
+ * @example
2723
+ * ```ts-no-run
2724
+ * scheduler.focusNext(); // Focuses the next event.
2725
+ * scheduler.focusNext({ offset: 1 }); // Focuses the next event.
2726
+ * scheduler.focusNext({ offset: -1 }); // Focuses the previous event.
2727
+ * scheduler.focusNext({ nowrap: true }); // If the focus is on the last event, does not move the focus to the first event.
2728
+ * ```
2729
+ *
2730
+ * @param position The relative position of the event to focus.
2731
+ * @returns `true` if the focused event changed. Otherwise, returns `false`.
2732
+ */
2733
+ focusNext(position) {
2734
+ return this.focusService.focusNext(position);
2735
+ }
2736
+ /**
2737
+ * Focuses the previous event or an event at a specified relative position.
2738
+ * The `options` parameter can be used to set a positive or negative offset
2739
+ * that is relative to the currently focused event.
2740
+ * A `nowrap` flag toggles the wrapping to the first or to the last item.
2741
+ *
2742
+ * @example
2743
+ * ```ts-no-run
2744
+ * scheduler.focusPrev(); // Focuses the previous event
2745
+ * scheduler.focusPrev({ nowrap: true }); // Does not move the focus to the last event, if focus is on the first one.
2746
+ * ```
2747
+ *
2748
+ * @param position The relative position of the event to focus.
2749
+ * @returns `true` if the focused event changed. Otherwise, returns `false`.
2750
+ */
2751
+ focusPrev(position) {
2752
+ const prevPosition = Object.assign({ offset: -1 }, position);
2753
+ return this.focusService.focusNext(prevPosition);
2754
+ }
2755
+ /**
2756
+ * Focuses the last focused event or the Scheduler element, if no events are available.
2757
+ */
2758
+ focus() {
2759
+ return this.focusService.focus();
2760
+ }
2761
+ isInRange(date) {
2762
+ return (!this.min || this.min <= date) && (!this.max || date <= this.max);
2763
+ }
2764
+ notifyOptionsChange(changes) {
2765
+ const workweek = this.workWeek;
2766
+ this.viewContext.notifyOptionsChange({
2767
+ group: this.group,
2768
+ resources: this.resources,
2769
+ allDayEventTemplate: this.allDayEventTemplate ? this.allDayEventTemplate.first : null,
2770
+ eventTemplate: this.eventTemplate ? this.eventTemplate.first : null,
2771
+ timeSlotTemplate: this.timeSlotTemplate ? this.timeSlotTemplate.first : null,
2772
+ minorTimeHeaderTemplate: this.minorTimeHeaderTemplate ? this.minorTimeHeaderTemplate.first : null,
2773
+ majorTimeHeaderTemplate: this.majorTimeHeaderTemplate ? this.majorTimeHeaderTemplate.first : null,
2774
+ monthDaySlotTemplate: this.monthDaySlotTemplate ? this.monthDaySlotTemplate.first : null,
2775
+ dateHeaderTemplate: this.dateHeaderTemplate ? this.dateHeaderTemplate.first : null,
2776
+ allDaySlotTemplate: this.allDaySlotTemplate ? this.allDaySlotTemplate.first : null,
2777
+ groupHeaderTemplate: this.groupHeaderTemplate ? this.groupHeaderTemplate.first : null,
2778
+ agendaDateTemplate: this.agendaDateTemplate ? this.agendaDateTemplate.first : null,
2779
+ agendaTimeTemplate: this.agendaTimeTemplate ? this.agendaTimeTemplate.first : null,
2780
+ min: this.min,
2781
+ max: this.max,
2782
+ showWorkHours: this.showWorkHours,
2783
+ startTime: this.startTime,
2784
+ scrollTime: this.scrollTime,
2785
+ endTime: this.endTime,
2786
+ workDayStart: this.workDayStart,
2787
+ workDayEnd: this.workDayEnd,
2788
+ workWeekStart: workweek.start,
2789
+ workWeekEnd: workweek.end,
2790
+ weekStart: this.weekStart,
2791
+ slotDuration: this.slotDuration,
2792
+ slotDivisions: this.slotDivisions,
2793
+ eventHeight: this.eventHeight,
2794
+ editable: this.editable,
2795
+ selectable: this.selectable,
2796
+ timezone: this.timezone,
2797
+ currentTimeMarker: this.currentTimeMarker,
2798
+ slotClass: this.slotClass,
2799
+ slotFill: this.slotFill,
2800
+ columnWidth: this.columnWidth,
2801
+ eventClass: this.eventClass,
2802
+ eventStyles: this.eventStyles,
2803
+ isSlotSelected: this.isSlotSelected,
2804
+ changes: changes
2805
+ });
2806
+ }
2807
+ get workWeek() {
2808
+ let { start, end } = this.intlService.weekendRange();
2809
+ const workWeekStart = isPresent(this.workWeekStart) ? this.workWeekStart : (end + 1) % DAYS_IN_WEEK;
2810
+ const weekEnd = start > 0 ? start - 1 : Day.Saturday;
2811
+ const workWeekEnd = isPresent(this.workWeekEnd) ? this.workWeekEnd : weekEnd;
2812
+ return { start: workWeekStart, end: workWeekEnd };
2813
+ }
2814
+ resetViewIndex() {
2815
+ const index = this.selectedViewIndex;
2816
+ const newIndex = Math.max(0, Math.min(index, this.views.length - 1));
2817
+ this.setViewIndex(newIndex);
2818
+ this.onViewIndexChange();
2819
+ }
2820
+ onViewIndexChange() {
2821
+ if (!this.views) {
2822
+ return;
2823
+ }
2824
+ const views = this.views.toArray();
2825
+ const selectedView = views[this.viewIndex];
2826
+ if (selectedView) {
2827
+ this.selectedView = selectedView;
2828
+ }
2829
+ }
2830
+ setViewIndex(newIndex) {
2831
+ const changed = this.selectedViewIndex !== newIndex;
2832
+ if (changed) {
2833
+ this.selectedViewIndex = newIndex;
2834
+ this.selectedViewIndexChange.emit(newIndex);
2835
+ }
2836
+ return changed;
2837
+ }
2838
+ processEvents(dataItems) {
2839
+ const timezone = this.timezone;
2840
+ const fields = this.modelFields;
2841
+ const items = dataItems
2842
+ .map(dataItem => readEvent(dataItem, fields, this.resources))
2843
+ .filter(event => !isRecurrenceMaster(event))
2844
+ .map(event => {
2845
+ const start = ZonedDate.fromLocalDate(event.start, timezone);
2846
+ const end = ZonedDate.fromLocalDate(event.end, timezone);
2847
+ return { start, end, event };
2848
+ });
2849
+ this.viewItems = items;
2850
+ this.viewContext.notifyItems(items);
2851
+ }
2852
+ attachEditHandlers() {
2853
+ if (!this.editService) {
2854
+ return;
2855
+ }
2856
+ this.subs.add(this.editService.changes.subscribe(this.emitCRUDEvent.bind(this)));
2857
+ }
2858
+ emitCRUDEvent(args) {
2859
+ Object.assign(args, { sender: this });
2860
+ switch (args.action) {
2861
+ case 'cancel':
2862
+ this.cancel.emit(args);
2863
+ break;
2864
+ case 'save':
2865
+ this.save.emit(args);
2866
+ break;
2867
+ default: break;
2868
+ }
2869
+ }
2870
+ intlChange() {
2871
+ const currentView = this.selectedView;
2872
+ this.selectedView = null;
2873
+ if (!isPresent(this.workWeekStart) || !isPresent(this.workWeekEnd)) {
2874
+ this.notifyOptionsChange();
2875
+ }
2876
+ this.changeDetector.detectChanges();
2877
+ this.selectedView = currentView;
2878
+ if (NgZone.isInAngularZone()) {
2879
+ this.changeDetector.markForCheck();
2880
+ }
2881
+ else {
2882
+ this.changeDetector.detectChanges();
2883
+ }
2884
+ }
2885
+ attachElementEventHandlers() {
2886
+ if (!isDocumentAvailable()) {
2887
+ return;
2888
+ }
2889
+ const wrapper = this.wrapper.nativeElement;
2890
+ this.zone.runOutsideAngular(() => {
2891
+ const windowBlurSubscription = this.renderer.listen('window', 'blur', (args) => {
2892
+ this.domEvents.windowBlur.emit(args);
2893
+ });
2894
+ const clickSubscription = this.renderer.listen(wrapper, 'click', (args) => {
2895
+ this.domEvents.click.emit(args);
2896
+ });
2897
+ const keydownSubscription = this.renderer.listen(wrapper, 'keydown', args => {
2898
+ this.domEvents.keydown.emit(args);
2899
+ });
2900
+ let focused = false;
2901
+ const focusInSubscription = this.renderer.listen(wrapper, 'focusin', (args) => {
2902
+ this.domEvents.focus.emit(args);
2903
+ if (!focused) {
2904
+ this.domEvents.focusIn.emit(args);
2905
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-state-focused');
2906
+ focused = true;
2907
+ }
2908
+ });
2909
+ const focusOutSubscription = this.renderer.listen(wrapper, 'focusout', (args) => {
2910
+ const next = args.relatedTarget || document.activeElement;
2911
+ const outside = !closest(next, (node) => node === wrapper);
2912
+ if (outside) {
2913
+ this.domEvents.focusOut.emit(args);
2914
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-state-focused');
2915
+ focused = false;
2916
+ }
2917
+ });
2918
+ this.detachElementEventHandlers = () => {
2919
+ windowBlurSubscription();
2920
+ clickSubscription();
2921
+ keydownSubscription();
2922
+ focusInSubscription();
2923
+ focusOutSubscription();
2924
+ };
2925
+ });
2926
+ }
2927
+ };
2586
2928
  __decorate([
2587
- Input(),
2588
- __metadata("design:type", Object)
2929
+ HostBinding('class.k-widget'),
2930
+ HostBinding('class.k-scheduler'),
2931
+ HostBinding('class.k-floatwrap'),
2932
+ __metadata("design:type", Boolean)
2933
+ ], SchedulerComponent.prototype, "hostClasses", void 0);
2934
+ __decorate([
2935
+ HostBinding('class.k-rtl'),
2936
+ __metadata("design:type", Boolean)
2937
+ ], SchedulerComponent.prototype, "rtl", void 0);
2938
+ __decorate([
2939
+ HostBinding('attr.dir'),
2940
+ __metadata("design:type", String),
2941
+ __metadata("design:paramtypes", [])
2942
+ ], SchedulerComponent.prototype, "dir", null);
2943
+ __decorate([
2944
+ Input(),
2945
+ __metadata("design:type", Number),
2946
+ __metadata("design:paramtypes", [Number])
2947
+ ], SchedulerComponent.prototype, "selectedViewIndex", null);
2948
+ __decorate([
2949
+ Input(),
2950
+ __metadata("design:type", Object)
2951
+ ], SchedulerComponent.prototype, "editable", void 0);
2952
+ __decorate([
2953
+ Input(),
2954
+ __metadata("design:type", Boolean)
2955
+ ], SchedulerComponent.prototype, "selectable", void 0);
2956
+ __decorate([
2957
+ Input(),
2958
+ __metadata("design:type", Date)
2959
+ ], SchedulerComponent.prototype, "min", void 0);
2960
+ __decorate([
2961
+ Input(),
2962
+ __metadata("design:type", Date)
2963
+ ], SchedulerComponent.prototype, "max", void 0);
2964
+ __decorate([
2965
+ Input(),
2966
+ __metadata("design:type", Number)
2967
+ ], SchedulerComponent.prototype, "eventHeight", void 0);
2968
+ __decorate([
2969
+ Input(),
2970
+ __metadata("design:type", Number)
2971
+ ], SchedulerComponent.prototype, "columnWidth", void 0);
2972
+ __decorate([
2973
+ Input(),
2974
+ __metadata("design:type", Boolean)
2975
+ ], SchedulerComponent.prototype, "showWorkHours", void 0);
2976
+ __decorate([
2977
+ Input(),
2978
+ __metadata("design:type", String)
2979
+ ], SchedulerComponent.prototype, "startTime", void 0);
2980
+ __decorate([
2981
+ Input(),
2982
+ __metadata("design:type", String)
2983
+ ], SchedulerComponent.prototype, "endTime", void 0);
2984
+ __decorate([
2985
+ Input(),
2986
+ __metadata("design:type", String)
2987
+ ], SchedulerComponent.prototype, "workDayStart", void 0);
2988
+ __decorate([
2989
+ Input(),
2990
+ __metadata("design:type", String)
2991
+ ], SchedulerComponent.prototype, "workDayEnd", void 0);
2992
+ __decorate([
2993
+ Input(),
2994
+ __metadata("design:type", Number)
2995
+ ], SchedulerComponent.prototype, "workWeekStart", void 0);
2996
+ __decorate([
2997
+ Input(),
2998
+ __metadata("design:type", Number)
2999
+ ], SchedulerComponent.prototype, "workWeekEnd", void 0);
3000
+ __decorate([
3001
+ Input(),
3002
+ __metadata("design:type", Number),
3003
+ __metadata("design:paramtypes", [Number])
3004
+ ], SchedulerComponent.prototype, "weekStart", null);
3005
+ __decorate([
3006
+ Input(),
3007
+ __metadata("design:type", Number)
3008
+ ], SchedulerComponent.prototype, "slotDuration", void 0);
3009
+ __decorate([
3010
+ Input(),
3011
+ __metadata("design:type", Number)
3012
+ ], SchedulerComponent.prototype, "slotDivisions", void 0);
3013
+ __decorate([
3014
+ Input(),
3015
+ __metadata("design:type", Number)
3016
+ ], SchedulerComponent.prototype, "slotFill", void 0);
3017
+ __decorate([
3018
+ Input(),
3019
+ __metadata("design:type", Object)
2589
3020
  ], SchedulerComponent.prototype, "scrollTime", void 0);
2590
3021
  __decorate([
2591
3022
  Input(),
@@ -2635,6 +3066,10 @@ __decorate([
2635
3066
  Input(),
2636
3067
  __metadata("design:type", Function)
2637
3068
  ], SchedulerComponent.prototype, "eventStyles", void 0);
3069
+ __decorate([
3070
+ Input(),
3071
+ __metadata("design:type", Function)
3072
+ ], SchedulerComponent.prototype, "isSlotSelected", void 0);
2638
3073
  __decorate([
2639
3074
  Output(),
2640
3075
  __metadata("design:type", EventEmitter)
@@ -2707,6 +3142,18 @@ __decorate([
2707
3142
  Output(),
2708
3143
  __metadata("design:type", EventEmitter)
2709
3144
  ], SchedulerComponent.prototype, "dragEnd", void 0);
3145
+ __decorate([
3146
+ Output(),
3147
+ __metadata("design:type", EventEmitter)
3148
+ ], SchedulerComponent.prototype, "slotDragStart", void 0);
3149
+ __decorate([
3150
+ Output(),
3151
+ __metadata("design:type", EventEmitter)
3152
+ ], SchedulerComponent.prototype, "slotDrag", void 0);
3153
+ __decorate([
3154
+ Output(),
3155
+ __metadata("design:type", EventEmitter)
3156
+ ], SchedulerComponent.prototype, "slotDragEnd", void 0);
2710
3157
  __decorate([
2711
3158
  Output(),
2712
3159
  __metadata("design:type", EventEmitter)
@@ -2922,428 +3369,167 @@ SchedulerComponent = __decorate([
2922
3369
  i18n-recurrenceEditorWeeklyRepeatEvery="kendo.scheduler.recurrenceEditorWeeklyRepeatEvery|The text similar to 'Repeat every' displayed in the scheduler recurrence editor."
2923
3370
  recurrenceEditorWeeklyRepeatEvery='Repeat every'
2924
3371
 
2925
- i18n-recurrenceEditorWeeklyRepeatOn="kendo.scheduler.recurrenceEditorWeeklyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
2926
- recurrenceEditorWeeklyRepeatOn='Repeat on'
2927
-
2928
- i18n-recurrenceEditorMonthlyDay="kendo.scheduler.recurrenceEditorMonthlyDay|The text similar to 'Day' displayed in the scheduler recurrence editor."
2929
- recurrenceEditorMonthlyDay='Day'
2930
-
2931
- i18n-recurrenceEditorMonthlyInterval="kendo.scheduler.recurrenceEditorMonthlyInterval|The text similar to 'month(s)' displayed in the scheduler recurrence editor."
2932
- recurrenceEditorMonthlyInterval='month(s)'
2933
-
2934
- i18n-recurrenceEditorMonthlyRepeatEvery="kendo.scheduler.recurrenceEditorMonthlyRepeatEvery|The text similar to 'Repeat every' displayed in the scheduler recurrence editor."
2935
- recurrenceEditorMonthlyRepeatEvery='Repeat every'
2936
-
2937
- i18n-recurrenceEditorMonthlyRepeatOn="kendo.scheduler.recurrenceEditorMonthlyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
2938
- recurrenceEditorMonthlyRepeatOn='Repeat on'
2939
-
2940
- i18n-recurrenceEditorYearlyOf="kendo.scheduler.recurrenceEditorYearlyOf|The text similar to 'of' displayed in the scheduler recurrence editor."
2941
- recurrenceEditorYearlyOf='of'
2942
-
2943
- i18n-recurrenceEditorYearlyRepeatEvery="kendo.scheduler.recurrenceEditorYearlyRepeatEvery|The text similar to 'Repeat every' displayed in the scheduler recurrence editor."
2944
- recurrenceEditorYearlyRepeatEvery='Repeat every'
2945
-
2946
- i18n-recurrenceEditorYearlyRepeatOn="kendo.scheduler.recurrenceEditorYearlyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
2947
- recurrenceEditorYearlyRepeatOn='Repeat on'
2948
-
2949
- i18n-recurrenceEditorYearlyInterval="kendo.scheduler.recurrenceEditorYearlyInterval|The text similar to 'year(s)' displayed in the scheduler recurrence editor."
2950
- recurrenceEditorYearlyInterval='year(s)'
2951
-
2952
- i18n-recurrenceEditorFrequenciesDaily="kendo.scheduler.recurrenceEditorFrequenciesDaily|The text similar to 'Daily' displayed in the scheduler recurrence editor."
2953
- recurrenceEditorFrequenciesDaily='Daily'
2954
-
2955
- i18n-recurrenceEditorFrequenciesMonthly="kendo.scheduler.recurrenceEditorFrequenciesMonthly|The text similar to 'Monthly' displayed in the scheduler recurrence editor."
2956
- recurrenceEditorFrequenciesMonthly='Monthly'
2957
-
2958
- i18n-recurrenceEditorFrequenciesNever="kendo.scheduler.recurrenceEditorFrequenciesNever|The text similar to 'Never' displayed in the scheduler recurrence editor."
2959
- recurrenceEditorFrequenciesNever='Never'
2960
-
2961
- i18n-recurrenceEditorFrequenciesWeekly="kendo.scheduler.recurrenceEditorFrequenciesWeekly|The text similar to 'Weekly' displayed in the scheduler recurrence editor."
2962
- recurrenceEditorFrequenciesWeekly='Weekly'
2963
-
2964
- i18n-recurrenceEditorFrequenciesYearly="kendo.scheduler.recurrenceEditorFrequenciesYearly|The text similar to 'Yearly' displayed in the scheduler recurrence editor."
2965
- recurrenceEditorFrequenciesYearly='Yearly'
2966
-
2967
- i18n-recurrenceEditorOffsetPositionsFirst="kendo.scheduler.recurrenceEditorOffsetPositionsFirst|The text similar to 'First' displayed in the scheduler recurrence editor."
2968
- recurrenceEditorOffsetPositionsFirst='First'
2969
-
2970
- i18n-recurrenceEditorOffsetPositionsSecond="kendo.scheduler.recurrenceEditorOffsetPositionsSecond|The text similar to 'Second' displayed in the scheduler recurrence editor."
2971
- recurrenceEditorOffsetPositionsSecond='Second'
2972
-
2973
- i18n-recurrenceEditorOffsetPositionsThird="kendo.scheduler.recurrenceEditorOffsetPositionsThird|The text similar to 'Third' displayed in the scheduler recurrence editor."
2974
- recurrenceEditorOffsetPositionsThird='Third'
2975
-
2976
- i18n-recurrenceEditorOffsetPositionsFourth="kendo.scheduler.recurrenceEditorOffsetPositionsFourth|The text similar to 'Fourth' displayed in the scheduler recurrence editor."
2977
- recurrenceEditorOffsetPositionsFourth='Fourth'
2978
-
2979
- i18n-recurrenceEditorOffsetPositionsLast="kendo.scheduler.recurrenceEditorOffsetPositionsLast|The text similar to 'Last' displayed in the scheduler recurrence editor."
2980
- recurrenceEditorOffsetPositionsLast='Last'
2981
-
2982
- i18n-recurrenceEditorWeekdaysDay="kendo.scheduler.recurrenceEditorWeekdaysDay|The text similar to 'Day' displayed in the repeat by section of the monthly recurrence pattern."
2983
- recurrenceEditorWeekdaysDay='Day'
2984
-
2985
- i18n-recurrenceEditorWeekdaysWeekday="kendo.scheduler.recurrenceEditorWeekdaysWeekday|The text similar to 'Weekday' displayed in the repeat by section of the monthly recurrence pattern."
2986
- recurrenceEditorWeekdaysWeekday='Weekday'
2987
-
2988
- i18n-recurrenceEditorWeekdaysWeekendday="kendo.scheduler.recurrenceEditorWeekdaysWeekendday|The text similar to 'Weekend Day' displayed in the repeat by section of the monthly recurrence pattern."
2989
- recurrenceEditorWeekdaysWeekendday='Weekend Day'
2990
-
2991
- i18n-recurrenceEditorEndAfter="kendo.scheduler.recurrenceEditorEndAfter|The text similar to 'After' displayed in the scheduler recurrence editor."
2992
- recurrenceEditorEndAfter='After'
2993
-
2994
- i18n-recurrenceEditorEndOccurrence="kendo.scheduler.recurrenceEditorEndOccurrence|The text similar to 'occurrence(s)' displayed in the scheduler recurrence editor."
2995
- recurrenceEditorEndOccurrence='occurrence(s)'
2996
-
2997
- i18n-recurrenceEditorEndLabel="kendo.scheduler.recurrenceEditorEndLabel|The text similar to 'End' displayed in the scheduler recurrence editor."
2998
- recurrenceEditorEndLabel='End'
2999
-
3000
- i18n-recurrenceEditorEndNever="kendo.scheduler.recurrenceEditorEndNever|The text similar to 'Never' displayed in the scheduler recurrence editor."
3001
- recurrenceEditorEndNever='Never'
3002
-
3003
- i18n-recurrenceEditorEndOn="kendo.scheduler.recurrenceEditorEndOn|The text similar to 'On' displayed in the scheduler recurrence editor."
3004
- recurrenceEditorEndOn='On'
3005
-
3006
- i18n-destroy="kendo.scheduler.destroy|The text of the 'Delete' button displayed in the scheduler remove confirmation dialog."
3007
- destroy='Delete'
3008
-
3009
- i18n-deleteConfirmation="kendo.scheduler.deleteConfirmation|The text similar to 'Are you sure you want to delete this event?' displayed in scheduler remove confirmation dialog."
3010
- deleteConfirmation='Are you sure you want to delete this event?'
3011
-
3012
- i18n-editRecurringConfirmation="kendo.scheduler.editRecurringConfirmation|The text similar to 'Do you want to edit only this event occurrence or the whole series?' displayed in the scheduler recurring confirmation dialog."
3013
- editRecurringConfirmation='Do you want to edit only this event occurrence or the whole series?'
3014
-
3015
- i18n-editOccurrence="kendo.scheduler.editOccurrence|The text of the 'Edit current occurrence' button displayed in the scheduler recurring confirmation dialog."
3016
- editOccurrence='Edit current occurrence'
3017
-
3018
- i18n-editSeries="kendo.scheduler.editSeries|The text of the 'Edit the series' button displayed in the scheduler recurring confirmation dialog."
3019
- editSeries='Edit the series'
3020
-
3021
- i18n-deleteRecurringConfirmation="kendo.scheduler.deleteRecurringConfirmation|The text similar to 'Do you want to delete only this event occurrence or the whole series?' displayed in the scheduler recurring confirmation dialog."
3022
- deleteRecurringConfirmation='Do you want to delete only this event occurrence or the whole series?'
3023
-
3024
- i18n-deleteOccurrence="kendo.scheduler.deleteOccurrence|The text of the 'Delete current occurrence' button displayed in the scheduler recurring confirmation dialog."
3025
- deleteOccurrence='Delete current occurrence'
3026
-
3027
- i18n-deleteSeries="kendo.scheduler.deleteSeries|The text similar of the 'Delete the series' button displayed in the scheduler recurring confirmation dialog."
3028
- deleteSeries='Delete the series'
3029
-
3030
- i18n-deleteDialogTitle="kendo.scheduler.deleteDialogTitle|The title of the remove confirmation dialog, similar to 'Delete Event'."
3031
- deleteDialogTitle='Delete Event'
3032
-
3033
- i18n-deleteRecurringDialogTitle="kendo.scheduler.deleteRecurringDialogTitle|The title of the recurring remove confirmation dialog, similar to 'Delete Recurring Item'"
3034
- deleteRecurringDialogTitle='Delete Recurring Item'
3035
-
3036
- i18n-editRecurringDialogTitle="kendo.scheduler.editRecurringDialogTitle|The title of the recurring edit confirmation dialog, similar to 'Edit Recurring Item'"
3037
- editRecurringDialogTitle='Edit Recurring Item'
3038
- >
3039
- </ng-container>
3040
-
3041
- <kendo-scheduler-toolbar
3042
- [dateRange]="dateRangeStream"
3043
- [selectedDate]="selectedDateStream"
3044
- [views]="views"
3045
- [selectedView]="selectedView"
3046
- [template]="toolbarTemplate"
3047
- (navigate)="onNavigationAction($event)"
3048
- [min]="min"
3049
- [max]="max"
3050
- ></kendo-scheduler-toolbar>
3051
-
3052
- <ng-container *ngTemplateOutlet="selectedView?.template">
3053
- </ng-container>
3054
-
3055
- <ng-container #confirmationDialogContainer>
3056
- </ng-container>
3057
-
3058
- <kendo-scheduler-edit-dialog
3059
- [resources]="resources"
3060
- [editTemplate]="editDialogTemplate"
3061
- [timezone]="timezone"
3062
- [weekStart]="weekStart"
3063
- [fields]="modelFields"
3064
- ></kendo-scheduler-edit-dialog>
3065
-
3066
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
3067
-
3068
- <div [loading]="loading" kendoSchedulerLoading>
3069
- </div>
3070
- `
3071
- }),
3072
- __metadata("design:paramtypes", [ElementRef,
3073
- ViewContextService,
3074
- ViewStateService,
3075
- EditService,
3076
- DialogsService,
3077
- IntlService,
3078
- ChangeDetectorRef,
3079
- NgZone,
3080
- PDFService,
3081
- LocalizationService,
3082
- DomEventsService,
3083
- Renderer2,
3084
- FocusService])
3085
- ], SchedulerComponent);
3086
-
3087
- /** @hidden */
3088
- const intersects = (startTime, endTime, periodStart, periodEnd) => (startTime < periodStart && endTime > periodEnd) ||
3089
- (periodStart <= startTime && startTime < periodEnd) ||
3090
- (periodStart < endTime && endTime <= periodEnd && startTime < endTime);
3091
- /** @hidden */
3092
- const dateInRange = (date, start, end) => start.getTime() <= date.getTime() && date.getTime() <= end.getTime();
3093
- /** @hidden */
3094
- const roundAllDayEnd = ({ start, end }) => {
3095
- const startDate = start.stripTime();
3096
- const endDate = end.stripTime();
3097
- return endDate.getTime() !== end.getTime() || startDate.getTime() === endDate.getTime() ? endDate.addDays(1) : endDate;
3098
- };
3099
- /** @hidden */
3100
- function toInvariantTime(date) {
3101
- var staticDate = new Date(1980, 0, 1, 0, 0, 0);
3102
- if (date) {
3103
- staticDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
3104
- }
3105
- return staticDate;
3106
- }
3107
- /**
3108
- * @hidden
3109
- * TODO Move to date-math
3110
- */
3111
- const addUTCDays = (date, offset) => {
3112
- const newDate = new Date(date.getTime());
3113
- newDate.setUTCDate(newDate.getUTCDate() + offset);
3114
- return newDate;
3115
- };
3116
- // TODO: name? move to date-math
3117
- /** @hidden */
3118
- function toUTCTime(localDate, localTime) {
3119
- return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localTime.getHours(), localTime.getMinutes(), localTime.getSeconds(), localTime.getMilliseconds()));
3120
- }
3121
- // TODO: move to date-math
3122
- /** @hidden */
3123
- function toUTCDate(localDate) {
3124
- return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()));
3125
- }
3126
- // TODO: move to date-math
3127
- /** @hidden */
3128
- function getUTCDate(utcDate) {
3129
- return new Date(Date.UTC(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate()));
3130
- }
3131
- // TODO: move to date-math
3132
- /** @hidden */
3133
- function toUTCDateTime(localDate) {
3134
- return new Date(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localDate.getHours(), localDate.getMinutes(), localDate.getSeconds(), localDate.getMilliseconds()));
3135
- }
3136
- /** @hidden */
3137
- function dateWithTime(target, time) {
3138
- return new Date(target.getFullYear(), target.getMonth(), target.getDate(), time.getHours(), time.getMinutes());
3139
- }
3140
- function getDataIdx(value, resource) {
3141
- const data = resource.data;
3142
- for (let dataIdx = 0; dataIdx < data.length; dataIdx++) {
3143
- if (getField(data[dataIdx], resource.valueField) === value) {
3144
- return dataIdx;
3145
- }
3146
- }
3147
- return -1;
3148
- }
3149
- function resourceItem(value, resource) {
3150
- const index = getDataIdx(value, resource);
3151
- return index >= 0 ? resource.data[index] : {};
3152
- }
3153
- function resourceItems(values, resource) {
3154
- return values.map(value => resourceItem(value, resource));
3155
- }
3156
- function cloneResources(arr) {
3157
- const result = [];
3158
- for (let idx = 0; idx < arr.length; idx++) {
3159
- const clone$$1 = Object.assign({}, arr[idx]);
3160
- clone$$1.resources = clone$$1.resources.slice(0);
3161
- result.push(clone$$1);
3162
- }
3163
- return result;
3164
- }
3165
- /** @hidden */
3166
- function resourceItemByValue(event, resource) {
3167
- const value = getField(event, resource.field);
3168
- if (Array.isArray(value)) {
3169
- return resourceItems(value, resource);
3170
- }
3171
- return resourceItem(value, resource);
3172
- }
3173
- function addNotGroupedResources(event, resources, allResources) {
3174
- for (let resourceIdx = 0; resourceIdx < resources.length; resourceIdx++) {
3175
- const current = resources[resourceIdx];
3176
- for (let idx = 0; idx < allResources.length; idx++) {
3177
- const item = allResources[idx];
3178
- if (!current.resources[idx] && item.data) {
3179
- current.resources[idx] = resourceItemByValue(event, item);
3180
- }
3181
- }
3182
- }
3183
- }
3184
- /** @hidden */
3185
- function eventResources(event, { taskResources, hasGroups, spans, allResources = [] }) {
3186
- let resources = [];
3187
- for (let resourceIdx = 0; resourceIdx < taskResources.length; resourceIdx++) {
3188
- const resource = taskResources[resourceIdx];
3189
- if (!resource.data) {
3190
- resources = [{ leafIdx: 0, resources: [] }];
3191
- continue;
3192
- }
3193
- const resourceIndex = allResources.indexOf(resource);
3194
- let values = getField(event, resource.field);
3195
- if (!Array.isArray(values)) {
3196
- values = [values];
3197
- }
3198
- const expandedResources = [];
3199
- for (let valueIdx = 0; valueIdx < values.length; valueIdx++) {
3200
- const dataIdx = getDataIdx(values[valueIdx], resource);
3201
- if (dataIdx < 0) {
3202
- return [{ leafIdx: hasGroups ? -1 : 0, resources: [] }];
3203
- }
3204
- const item = resource.data[dataIdx];
3205
- // has groups - need all copies of the multiple resource
3206
- // no groups - just the first
3207
- if (resourceIdx === 0 && (hasGroups || valueIdx === 0)) {
3208
- const resourceItems = [];
3209
- resourceItems[resourceIndex] = resource.multiple && !hasGroups ? [item] : item;
3210
- resources.push({
3211
- leafIdx: hasGroups ? dataIdx * spans[resourceIdx] : 0,
3212
- color: getField(item, resource.colorField),
3213
- resources: resourceItems
3214
- });
3215
- }
3216
- else if (hasGroups) { // don't create multiple resource groups if no groups for multiple resources
3217
- let currentResources = resources;
3218
- if (values.length > 1) {
3219
- currentResources = cloneResources(resources);
3220
- expandedResources.push.apply(expandedResources, currentResources);
3221
- }
3222
- for (let currentIdx = 0; currentIdx < currentResources.length; currentIdx++) {
3223
- currentResources[currentIdx].leafIdx += dataIdx * spans[resourceIdx];
3224
- currentResources[currentIdx].resources[resourceIndex] = item;
3225
- }
3226
- }
3227
- else if (valueIdx > 0) {
3228
- for (let idx = 0; idx < resources.length; idx++) {
3229
- resources[idx].resources[resourceIndex].push(item);
3230
- }
3231
- }
3232
- }
3233
- if (expandedResources.length) {
3234
- resources = expandedResources;
3235
- }
3236
- }
3237
- addNotGroupedResources(event, resources, allResources);
3238
- return resources;
3239
- }
3240
- /** @hidden */
3241
- function assignTasksResources(tasks, options) {
3242
- for (let idx = 0; idx < tasks.length; idx++) {
3243
- const task = tasks[idx];
3244
- task.resources = eventResources(task.event, options);
3245
- }
3246
- }
3247
- /** @hidden */
3248
- function findRowIndex(events, data) {
3249
- if (data.rowIndex !== undefined) {
3250
- return data.rowIndex;
3251
- }
3252
- for (let idx = 0; idx < events.length; idx++) {
3253
- if (!events[idx]) {
3254
- return idx;
3255
- }
3256
- }
3257
- return events.length;
3258
- }
3259
- /** @hidden */
3260
- function isRecurrence(task) {
3261
- return Boolean(task.event && task.event.recurrenceRule);
3262
- }
3263
- /** @hidden */
3264
- function isRecurrenceException(task) {
3265
- return task.event && isPresent(task.event.recurrenceId) && !task.event.recurrenceRule;
3266
- }
3267
- /** @hidden */
3268
- const rectContains = (rect, left, top) => rect.left <= left && left <= rect.left + rect.width && rect.top <= top && top <= rect.top + rect.height;
3269
- /** @hidden */
3270
- const rectContainsX = (rect, left) => rect.left <= left && left <= rect.left + rect.width;
3271
- /** @hidden */
3272
- const toPx = value => `${value}px`;
3273
- /** @hidden */
3274
- const elementOffset = (element) => {
3275
- if (!element) {
3276
- return null;
3277
- }
3278
- const box = element.getBoundingClientRect();
3279
- const documentElement = document.documentElement;
3280
- return {
3281
- top: box.top + (window.pageYOffset || documentElement.scrollTop) - (documentElement.clientTop || 0),
3282
- left: box.left + (window.pageXOffset || documentElement.scrollLeft) - (documentElement.clientLeft || 0),
3283
- width: box.width,
3284
- height: box.height
3285
- };
3286
- };
3287
- /** @hidden */
3288
- const pointDistance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
3289
- /** @hidden */
3290
- const ignoreContentChild = child => child.nodeName === 'KENDO-RESIZE-SENSOR' || hasClasses(child, 'k-loading-mask');
3291
- /** @hidden */
3292
- const setCoordinates = (element, coordinates) => {
3293
- for (let field in coordinates) {
3294
- if (coordinates.hasOwnProperty(field)) {
3295
- element.style[field] = toPx(coordinates[field]);
3296
- }
3297
- }
3298
- };
3299
- /** @hidden */
3300
- const convertNgClassBindings = (bindingValues) => {
3301
- const result = [];
3302
- if (isString(bindingValues)) {
3303
- result.push(bindingValues);
3304
- }
3305
- else if (isArray(bindingValues)) {
3306
- result.push.apply(result, bindingValues);
3307
- }
3308
- else if (isObject(bindingValues)) {
3309
- for (let field in bindingValues) {
3310
- if (bindingValues.hasOwnProperty(field) && bindingValues[field]) {
3311
- result.push(field);
3312
- }
3313
- }
3314
- }
3315
- return result;
3316
- };
3317
- /**
3318
- * @hidden
3319
- */
3320
- function formatEventTime(start, end, isAllDay, localeId) {
3321
- const startTimeFormat = { skeleton: 'yMMMMEEEEdhm' };
3322
- const startDateFormat = { skeleton: 'yMMMMEEEEd' };
3323
- const endFormat = isEqualDate(start, end) ? 't' : startTimeFormat;
3324
- return isAllDay ?
3325
- `${formatDate(start, startDateFormat, localeId)}` :
3326
- `${formatDate(start, startTimeFormat, localeId)}–${formatDate(end, endFormat, localeId)}`;
3327
- }
3328
- /**
3329
- * @hidden
3330
- */
3331
- function formValueOrDefault(group, field, defaultValue) {
3332
- const control = group.get(field);
3333
- if (!control) {
3334
- return defaultValue;
3335
- }
3336
- return control.value || defaultValue;
3337
- }
3338
- /**
3339
- * @hidden
3340
- */
3341
- const isWorkWeekDay = (day, start, end) => {
3342
- if (end < start) {
3343
- return day <= end || start <= day;
3344
- }
3345
- return start <= day && day <= end;
3346
- };
3372
+ i18n-recurrenceEditorWeeklyRepeatOn="kendo.scheduler.recurrenceEditorWeeklyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
3373
+ recurrenceEditorWeeklyRepeatOn='Repeat on'
3374
+
3375
+ i18n-recurrenceEditorMonthlyDay="kendo.scheduler.recurrenceEditorMonthlyDay|The text similar to 'Day' displayed in the scheduler recurrence editor."
3376
+ recurrenceEditorMonthlyDay='Day'
3377
+
3378
+ i18n-recurrenceEditorMonthlyInterval="kendo.scheduler.recurrenceEditorMonthlyInterval|The text similar to 'month(s)' displayed in the scheduler recurrence editor."
3379
+ recurrenceEditorMonthlyInterval='month(s)'
3380
+
3381
+ i18n-recurrenceEditorMonthlyRepeatEvery="kendo.scheduler.recurrenceEditorMonthlyRepeatEvery|The text similar to 'Repeat every' displayed in the scheduler recurrence editor."
3382
+ recurrenceEditorMonthlyRepeatEvery='Repeat every'
3383
+
3384
+ i18n-recurrenceEditorMonthlyRepeatOn="kendo.scheduler.recurrenceEditorMonthlyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
3385
+ recurrenceEditorMonthlyRepeatOn='Repeat on'
3386
+
3387
+ i18n-recurrenceEditorYearlyOf="kendo.scheduler.recurrenceEditorYearlyOf|The text similar to 'of' displayed in the scheduler recurrence editor."
3388
+ recurrenceEditorYearlyOf='of'
3389
+
3390
+ i18n-recurrenceEditorYearlyRepeatEvery="kendo.scheduler.recurrenceEditorYearlyRepeatEvery|The text similar to 'Repeat every' displayed in the scheduler recurrence editor."
3391
+ recurrenceEditorYearlyRepeatEvery='Repeat every'
3392
+
3393
+ i18n-recurrenceEditorYearlyRepeatOn="kendo.scheduler.recurrenceEditorYearlyRepeatOn|The text similar to 'Repeat on' displayed in the scheduler recurrence editor."
3394
+ recurrenceEditorYearlyRepeatOn='Repeat on'
3395
+
3396
+ i18n-recurrenceEditorYearlyInterval="kendo.scheduler.recurrenceEditorYearlyInterval|The text similar to 'year(s)' displayed in the scheduler recurrence editor."
3397
+ recurrenceEditorYearlyInterval='year(s)'
3398
+
3399
+ i18n-recurrenceEditorFrequenciesDaily="kendo.scheduler.recurrenceEditorFrequenciesDaily|The text similar to 'Daily' displayed in the scheduler recurrence editor."
3400
+ recurrenceEditorFrequenciesDaily='Daily'
3401
+
3402
+ i18n-recurrenceEditorFrequenciesMonthly="kendo.scheduler.recurrenceEditorFrequenciesMonthly|The text similar to 'Monthly' displayed in the scheduler recurrence editor."
3403
+ recurrenceEditorFrequenciesMonthly='Monthly'
3404
+
3405
+ i18n-recurrenceEditorFrequenciesNever="kendo.scheduler.recurrenceEditorFrequenciesNever|The text similar to 'Never' displayed in the scheduler recurrence editor."
3406
+ recurrenceEditorFrequenciesNever='Never'
3407
+
3408
+ i18n-recurrenceEditorFrequenciesWeekly="kendo.scheduler.recurrenceEditorFrequenciesWeekly|The text similar to 'Weekly' displayed in the scheduler recurrence editor."
3409
+ recurrenceEditorFrequenciesWeekly='Weekly'
3410
+
3411
+ i18n-recurrenceEditorFrequenciesYearly="kendo.scheduler.recurrenceEditorFrequenciesYearly|The text similar to 'Yearly' displayed in the scheduler recurrence editor."
3412
+ recurrenceEditorFrequenciesYearly='Yearly'
3413
+
3414
+ i18n-recurrenceEditorOffsetPositionsFirst="kendo.scheduler.recurrenceEditorOffsetPositionsFirst|The text similar to 'First' displayed in the scheduler recurrence editor."
3415
+ recurrenceEditorOffsetPositionsFirst='First'
3416
+
3417
+ i18n-recurrenceEditorOffsetPositionsSecond="kendo.scheduler.recurrenceEditorOffsetPositionsSecond|The text similar to 'Second' displayed in the scheduler recurrence editor."
3418
+ recurrenceEditorOffsetPositionsSecond='Second'
3419
+
3420
+ i18n-recurrenceEditorOffsetPositionsThird="kendo.scheduler.recurrenceEditorOffsetPositionsThird|The text similar to 'Third' displayed in the scheduler recurrence editor."
3421
+ recurrenceEditorOffsetPositionsThird='Third'
3422
+
3423
+ i18n-recurrenceEditorOffsetPositionsFourth="kendo.scheduler.recurrenceEditorOffsetPositionsFourth|The text similar to 'Fourth' displayed in the scheduler recurrence editor."
3424
+ recurrenceEditorOffsetPositionsFourth='Fourth'
3425
+
3426
+ i18n-recurrenceEditorOffsetPositionsLast="kendo.scheduler.recurrenceEditorOffsetPositionsLast|The text similar to 'Last' displayed in the scheduler recurrence editor."
3427
+ recurrenceEditorOffsetPositionsLast='Last'
3428
+
3429
+ i18n-recurrenceEditorWeekdaysDay="kendo.scheduler.recurrenceEditorWeekdaysDay|The text similar to 'Day' displayed in the repeat by section of the monthly recurrence pattern."
3430
+ recurrenceEditorWeekdaysDay='Day'
3431
+
3432
+ i18n-recurrenceEditorWeekdaysWeekday="kendo.scheduler.recurrenceEditorWeekdaysWeekday|The text similar to 'Weekday' displayed in the repeat by section of the monthly recurrence pattern."
3433
+ recurrenceEditorWeekdaysWeekday='Weekday'
3434
+
3435
+ i18n-recurrenceEditorWeekdaysWeekendday="kendo.scheduler.recurrenceEditorWeekdaysWeekendday|The text similar to 'Weekend Day' displayed in the repeat by section of the monthly recurrence pattern."
3436
+ recurrenceEditorWeekdaysWeekendday='Weekend Day'
3437
+
3438
+ i18n-recurrenceEditorEndAfter="kendo.scheduler.recurrenceEditorEndAfter|The text similar to 'After' displayed in the scheduler recurrence editor."
3439
+ recurrenceEditorEndAfter='After'
3440
+
3441
+ i18n-recurrenceEditorEndOccurrence="kendo.scheduler.recurrenceEditorEndOccurrence|The text similar to 'occurrence(s)' displayed in the scheduler recurrence editor."
3442
+ recurrenceEditorEndOccurrence='occurrence(s)'
3443
+
3444
+ i18n-recurrenceEditorEndLabel="kendo.scheduler.recurrenceEditorEndLabel|The text similar to 'End' displayed in the scheduler recurrence editor."
3445
+ recurrenceEditorEndLabel='End'
3446
+
3447
+ i18n-recurrenceEditorEndNever="kendo.scheduler.recurrenceEditorEndNever|The text similar to 'Never' displayed in the scheduler recurrence editor."
3448
+ recurrenceEditorEndNever='Never'
3449
+
3450
+ i18n-recurrenceEditorEndOn="kendo.scheduler.recurrenceEditorEndOn|The text similar to 'On' displayed in the scheduler recurrence editor."
3451
+ recurrenceEditorEndOn='On'
3452
+
3453
+ i18n-destroy="kendo.scheduler.destroy|The text of the 'Delete' button displayed in the scheduler remove confirmation dialog."
3454
+ destroy='Delete'
3455
+
3456
+ i18n-deleteConfirmation="kendo.scheduler.deleteConfirmation|The text similar to 'Are you sure you want to delete this event?' displayed in scheduler remove confirmation dialog."
3457
+ deleteConfirmation='Are you sure you want to delete this event?'
3458
+
3459
+ i18n-editRecurringConfirmation="kendo.scheduler.editRecurringConfirmation|The text similar to 'Do you want to edit only this event occurrence or the whole series?' displayed in the scheduler recurring confirmation dialog."
3460
+ editRecurringConfirmation='Do you want to edit only this event occurrence or the whole series?'
3461
+
3462
+ i18n-editOccurrence="kendo.scheduler.editOccurrence|The text of the 'Edit current occurrence' button displayed in the scheduler recurring confirmation dialog."
3463
+ editOccurrence='Edit current occurrence'
3464
+
3465
+ i18n-editSeries="kendo.scheduler.editSeries|The text of the 'Edit the series' button displayed in the scheduler recurring confirmation dialog."
3466
+ editSeries='Edit the series'
3467
+
3468
+ i18n-deleteRecurringConfirmation="kendo.scheduler.deleteRecurringConfirmation|The text similar to 'Do you want to delete only this event occurrence or the whole series?' displayed in the scheduler recurring confirmation dialog."
3469
+ deleteRecurringConfirmation='Do you want to delete only this event occurrence or the whole series?'
3470
+
3471
+ i18n-deleteOccurrence="kendo.scheduler.deleteOccurrence|The text of the 'Delete current occurrence' button displayed in the scheduler recurring confirmation dialog."
3472
+ deleteOccurrence='Delete current occurrence'
3473
+
3474
+ i18n-deleteSeries="kendo.scheduler.deleteSeries|The text similar of the 'Delete the series' button displayed in the scheduler recurring confirmation dialog."
3475
+ deleteSeries='Delete the series'
3476
+
3477
+ i18n-deleteDialogTitle="kendo.scheduler.deleteDialogTitle|The title of the remove confirmation dialog, similar to 'Delete Event'."
3478
+ deleteDialogTitle='Delete Event'
3479
+
3480
+ i18n-deleteRecurringDialogTitle="kendo.scheduler.deleteRecurringDialogTitle|The title of the recurring remove confirmation dialog, similar to 'Delete Recurring Item'"
3481
+ deleteRecurringDialogTitle='Delete Recurring Item'
3482
+
3483
+ i18n-editRecurringDialogTitle="kendo.scheduler.editRecurringDialogTitle|The title of the recurring edit confirmation dialog, similar to 'Edit Recurring Item'"
3484
+ editRecurringDialogTitle='Edit Recurring Item'
3485
+ >
3486
+ </ng-container>
3487
+
3488
+ <kendo-scheduler-toolbar
3489
+ [dateRange]="dateRangeStream"
3490
+ [selectedDate]="selectedDateStream"
3491
+ [views]="views"
3492
+ [selectedView]="selectedView"
3493
+ [template]="toolbarTemplate"
3494
+ (navigate)="onNavigationAction($event)"
3495
+ [min]="min"
3496
+ [max]="max"
3497
+ ></kendo-scheduler-toolbar>
3498
+
3499
+ <ng-container *ngTemplateOutlet="selectedView?.template">
3500
+ </ng-container>
3501
+
3502
+ <ng-container #confirmationDialogContainer>
3503
+ </ng-container>
3504
+
3505
+ <kendo-scheduler-edit-dialog
3506
+ [resources]="resources"
3507
+ [editTemplate]="editDialogTemplate"
3508
+ [timezone]="timezone"
3509
+ [weekStart]="weekStart"
3510
+ [fields]="modelFields"
3511
+ ></kendo-scheduler-edit-dialog>
3512
+
3513
+ <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
3514
+
3515
+ <div [loading]="loading" kendoSchedulerLoading>
3516
+ </div>
3517
+ `
3518
+ }),
3519
+ __metadata("design:paramtypes", [ElementRef,
3520
+ ViewContextService,
3521
+ ViewStateService,
3522
+ EditService,
3523
+ DialogsService,
3524
+ IntlService,
3525
+ ChangeDetectorRef,
3526
+ NgZone,
3527
+ PDFService,
3528
+ LocalizationService,
3529
+ DomEventsService,
3530
+ Renderer2,
3531
+ FocusService])
3532
+ ], SchedulerComponent);
3347
3533
 
3348
3534
  // TODO
3349
3535
  // Extract as public method
@@ -4245,7 +4431,7 @@ ToolbarViewSelectorComponent = __decorate([
4245
4431
  template: `
4246
4432
  <select *ngIf="ctx.views?.length > 1"
4247
4433
  (change)="onChange($event)"
4248
- class="k-views-dropdown k-dropdown">
4434
+ class="k-views-dropdown k-picker-md k-rounded-md k-picker-solid k-dropdownlist k-picker">
4249
4435
  <option *ngFor="let view of ctx.views"
4250
4436
  [selected]="isSelected(view) == true"
4251
4437
  [value]="view.name"
@@ -4255,6 +4441,7 @@ ToolbarViewSelectorComponent = __decorate([
4255
4441
  </select>
4256
4442
  <span class="k-scheduler-views k-button-group">
4257
4443
  <button kendoButton
4444
+ type="button"
4258
4445
  *ngFor="let view of ctx.views"
4259
4446
  [selected]="isSelected(view)"
4260
4447
  [attr.aria-pressed]="isSelected(view)"
@@ -6209,7 +6396,7 @@ const SCROLL_INTERVAL = 50;
6209
6396
  const MIN_MOVE_DISTANCE = 10;
6210
6397
  /** @hidden */
6211
6398
  class BaseView {
6212
- constructor(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization) {
6399
+ constructor(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, cdr) {
6213
6400
  this.viewContext = viewContext;
6214
6401
  this.viewState = viewState;
6215
6402
  this.intl = intl;
@@ -6219,6 +6406,7 @@ class BaseView {
6219
6406
  this.element = element;
6220
6407
  this.pdfService = pdfService;
6221
6408
  this.localization = localization;
6409
+ this.cdr = cdr;
6222
6410
  this.items = new BehaviorSubject(null);
6223
6411
  this.horizontalResources = [];
6224
6412
  this.verticalResources = [];
@@ -6232,8 +6420,17 @@ class BaseView {
6232
6420
  this.spans = [];
6233
6421
  this.domEvents = [];
6234
6422
  this.resourcesCache = {};
6423
+ /**
6424
+ * The slot which is currently being dragged over while selecting a range of slots.
6425
+ */
6426
+ this.dragSelecting = null;
6427
+ /**
6428
+ * The slot where the drag-selecting originated. Used for flipping the start and end of the emitted range.
6429
+ */
6430
+ this.dragSelectOrigin = null;
6235
6431
  this.autoHeight = false;
6236
6432
  this.rtl = false;
6433
+ this.isSlotSelected = () => false;
6237
6434
  this.setSlotClass = this.setSlotClass.bind(this);
6238
6435
  this.setHintClass = this.setHintClass.bind(this);
6239
6436
  this.weekStart = intl.firstDay();
@@ -6350,6 +6547,20 @@ class BaseView {
6350
6547
  }
6351
6548
  return result;
6352
6549
  }
6550
+ // Similar to https://tc39.es/proposal-temporal/docs/plaindate.html
6551
+ // Stores a "plain date" in the UTC parts of a regular `Date`.
6552
+ toPlainDate(date) {
6553
+ const result = toUTCDateTime(this.convertDate(date));
6554
+ return result;
6555
+ }
6556
+ // Similar to https://tc39.es/proposal-temporal/docs/plaindatetime.html
6557
+ // Stores a "plain date-time" in the UTC parts of a regular `Date`.
6558
+ toPlainDateTime(date, time) {
6559
+ if (!date || !time) {
6560
+ return null;
6561
+ }
6562
+ return this.toPlainDate(dateWithTime(date, time));
6563
+ }
6353
6564
  optionsChange(options) {
6354
6565
  this.schedulerEventTemplate = options.eventTemplate;
6355
6566
  this.schedulerGroupHeaderTemplate = options.groupHeaderTemplate;
@@ -6357,6 +6568,8 @@ class BaseView {
6357
6568
  this.max = options.max;
6358
6569
  this.editable = options.editable;
6359
6570
  this.timezone = options.timezone;
6571
+ this.selectable = options.selectable;
6572
+ this.isSlotSelected = options.isSlotSelected;
6360
6573
  if (!options.changes || anyChanged(['group', 'resources'], options.changes, false) ||
6361
6574
  options.group !== this.group || options.resources !== this.resources) {
6362
6575
  this.group = options.group;
@@ -6383,6 +6596,7 @@ class BaseView {
6383
6596
  this.toggleElement(true);
6384
6597
  this.reflow();
6385
6598
  this.viewState.notifyLayoutEnd();
6599
+ this.viewState.emitEvent(slotDragEventName.refreshSlotSelection);
6386
6600
  }
6387
6601
  assignResources() {
6388
6602
  assignTasksResources(this.tasks, {
@@ -6423,16 +6637,16 @@ class BaseView {
6423
6637
  });
6424
6638
  }
6425
6639
  onPress(args) {
6426
- const resizable = this.editable && this.editable.resize !== false;
6427
- const draggable = this.editable && this.editable.drag !== false;
6640
+ const editResizable = this.editable && this.editable.resize !== false;
6641
+ const editDraggable = this.editable && this.editable.drag !== false;
6428
6642
  const target = args.originalEvent.target;
6429
6643
  if (hasClasses(target, 'k-resize-handle')) {
6430
- if (!resizable) {
6644
+ if (!editResizable) {
6431
6645
  return;
6432
6646
  }
6433
6647
  this.initResize(args);
6434
6648
  }
6435
- else if (draggable) {
6649
+ else if (editDraggable) {
6436
6650
  const task = this.targetTask(target);
6437
6651
  if (task) {
6438
6652
  if (!args.isTouch) {
@@ -6442,6 +6656,10 @@ class BaseView {
6442
6656
  this.pressTarget = task;
6443
6657
  }
6444
6658
  }
6659
+ const notDraggingEvent = !this.pressTarget;
6660
+ if (notDraggingEvent && this.selectable) {
6661
+ this.initDragSelect(args);
6662
+ }
6445
6663
  this.dragArgs = args;
6446
6664
  }
6447
6665
  onDrag(args) {
@@ -6456,12 +6674,15 @@ class BaseView {
6456
6674
  args.originalEvent.preventDefault();
6457
6675
  this.scrollContainer(this.drag, args);
6458
6676
  }
6677
+ if (this.dragSelecting) {
6678
+ this.dragSelect(args);
6679
+ }
6459
6680
  }
6460
6681
  this.dragArgs = args;
6461
6682
  }
6462
- onRelease() {
6683
+ onRelease(args) {
6463
6684
  clearInterval(this.scrollInterval);
6464
- const { resizing, dragging } = this;
6685
+ const { resizing, dragging, dragSelecting } = this;
6465
6686
  if (resizing) {
6466
6687
  this.emitEvent('resizeEnd', {
6467
6688
  event: resizing.task.event,
@@ -6488,6 +6709,20 @@ class BaseView {
6488
6709
  this.resizing = null;
6489
6710
  this.dragging = null;
6490
6711
  }
6712
+ if (dragSelecting) {
6713
+ const { start, end } = normaliseRangeStartAndEnd(this.dragSelectOrigin, this.dragSelecting);
6714
+ const range = {
6715
+ start: this.convertDate(start),
6716
+ end: this.convertDate(end),
6717
+ isAllDay: this.dragSelecting.isDaySlot,
6718
+ resources: this.resourcesByIndex(this.dragSelecting.id.resourceIndex),
6719
+ originalEvent: args.originalEvent
6720
+ };
6721
+ this.viewState.notifySlotSelectionEnd(range);
6722
+ this.dragSelectOrigin = null;
6723
+ this.dragSelecting = null;
6724
+ this.cdr.markForCheck();
6725
+ }
6491
6726
  this.container = null;
6492
6727
  this.dragArgs = null;
6493
6728
  this.pressLocation = null;
@@ -6635,6 +6870,51 @@ class BaseView {
6635
6870
  this.updateHintContainer();
6636
6871
  }
6637
6872
  }
6873
+ initDragSelect(args) {
6874
+ this.updateDragContainer(args);
6875
+ if (!this.containerOffset) {
6876
+ return;
6877
+ }
6878
+ const { x, y } = this.coordinatesOffset(args.pageX, args.pageY);
6879
+ const slot = this.slotByPosition(x, y, this.container);
6880
+ if (!slot) {
6881
+ return;
6882
+ }
6883
+ const range = {
6884
+ start: this.convertDate(slot.start),
6885
+ end: this.convertDate(slot.end),
6886
+ isAllDay: slot.isDaySlot,
6887
+ resources: this.resourcesByIndex(slot.id.resourceIndex),
6888
+ originalEvent: args.originalEvent
6889
+ };
6890
+ const slotDragStartEvent = new SlotDragStartEvent(null, range);
6891
+ this.viewState.notifySlotSelectionStart(slotDragStartEvent);
6892
+ if (!slotDragStartEvent.isDefaultPrevented()) {
6893
+ this.dragSelecting = slot;
6894
+ this.dragSelectOrigin = slot;
6895
+ this.cdr.markForCheck();
6896
+ }
6897
+ }
6898
+ dragSelect(args) {
6899
+ const { x, y } = this.coordinatesOffset(args.pageX, args.pageY);
6900
+ const slot = this.slotByPosition(x, y, this.container);
6901
+ if (!slot) {
6902
+ return;
6903
+ }
6904
+ if (this.dragSelecting !== slot) {
6905
+ this.dragSelecting = slot;
6906
+ const { start, end } = normaliseRangeStartAndEnd(this.dragSelectOrigin, this.dragSelecting);
6907
+ const range = {
6908
+ start: this.convertDate(start),
6909
+ end: this.convertDate(end),
6910
+ isAllDay: slot.isDaySlot,
6911
+ resources: this.resourcesByIndex(slot.id.resourceIndex),
6912
+ originalEvent: args.originalEvent
6913
+ };
6914
+ this.viewState.notifySlotSelectionDrag(range);
6915
+ this.cdr.markForCheck();
6916
+ }
6917
+ }
6638
6918
  dragHintClasses() {
6639
6919
  const hintClass = this.dragging.hintClass;
6640
6920
  let result = [];
@@ -7115,8 +7395,8 @@ const WEEKS_COUNT = 6;
7115
7395
  * @hidden
7116
7396
  */
7117
7397
  let MonthViewRendererComponent = class MonthViewRendererComponent extends BaseView {
7118
- constructor(viewContext, viewState, intl, slotService, zone, element, renderer, pdfService, localization) {
7119
- super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization);
7398
+ constructor(viewContext, viewState, intl, slotService, zone, element, renderer, pdfService, localization, changeDetector) {
7399
+ super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, changeDetector);
7120
7400
  this.resizeHintFormat = { skeleton: 'Md' };
7121
7401
  this.weeks = [];
7122
7402
  }
@@ -7167,6 +7447,9 @@ let MonthViewRendererComponent = class MonthViewRendererComponent extends BaseVi
7167
7447
  cellTitle(value) {
7168
7448
  return this.intl.formatDate(value, 'D');
7169
7449
  }
7450
+ addDay(dayStart) {
7451
+ return addDays(dayStart, 1);
7452
+ }
7170
7453
  optionsChange(changes) {
7171
7454
  this.schedulerMonthDaySlotTemplate = changes.monthDaySlotTemplate;
7172
7455
  super.optionsChange(changes);
@@ -7331,7 +7614,7 @@ MonthViewRendererComponent = __decorate([
7331
7614
  </table>
7332
7615
  </div>
7333
7616
  <div class="k-scheduler-content" #content>
7334
- <table class="k-scheduler-table" #contentTable role="presentation">
7617
+ <table class="k-scheduler-table k-user-select-none" #contentTable role="presentation">
7335
7618
  <ng-container *ngFor="let resourceItem of verticalResources | resourceIterator; let verticalIndex = index; trackBy: itemIndex">
7336
7619
  <tr *ngFor="let week of weeks; let rangeIndex = index; trackBy: itemIndex">
7337
7620
  <ng-container *ngFor="let resource of horizontalResources | resourceIterator; let horizontalIndex = index; trackBy: itemIndex">
@@ -7341,8 +7624,14 @@ MonthViewRendererComponent = __decorate([
7341
7624
  [start]="day"
7342
7625
  [id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
7343
7626
  [title]="cellTitle(day)"
7344
- >
7345
- <span aria-hidden="true" class="k-link k-nav-day" *ngIf="!monthDaySlotTemplateRef" >{{ day | kendoDate: 'dd' }}</span>
7627
+ [class.k-state-selected]="isSlotSelected({
7628
+ start: toPlainDate(day),
7629
+ end: addDay(toPlainDate(day)),
7630
+ isAllDay: true,
7631
+ resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
7632
+ })"
7633
+ >
7634
+ <span aria-hidden="true" class="k-link k-nav-day" *ngIf="!monthDaySlotTemplateRef">{{ day | kendoDate: 'dd' }}</span>
7346
7635
  <ng-container *ngIf="monthDaySlotTemplateRef" [ngTemplateOutlet]="monthDaySlotTemplateRef"
7347
7636
  [ngTemplateOutletContext]="{ date: day, resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex) }"></ng-container>
7348
7637
  </td>
@@ -7399,7 +7688,8 @@ MonthViewRendererComponent = __decorate([
7399
7688
  ElementRef,
7400
7689
  Renderer2,
7401
7690
  PDFService,
7402
- LocalizationService])
7691
+ LocalizationService,
7692
+ ChangeDetectorRef])
7403
7693
  ], MonthViewRendererComponent);
7404
7694
 
7405
7695
  /**
@@ -7590,7 +7880,7 @@ ViewFooterComponent = __decorate([
7590
7880
  // tslint:disable-next-line:component-selector
7591
7881
  selector: '[viewFooter]',
7592
7882
  template: `
7593
- <button type="button" class="k-button" *ngFor="let item of items" [ngClass]="item.cssClass" (click)="onItemClick($event, item)">
7883
+ <button type="button" kendoButton *ngFor="let item of items" [ngClass]="item.cssClass" (click)="onItemClick($event, item)">
7594
7884
  <span class="k-button-icon k-icon" [ngClass]="item.iconClass"></span>
7595
7885
  <span class="k-button-text">{{ item.text }}</span>
7596
7886
  </button>
@@ -7786,7 +8076,7 @@ let ViewsSharedModule = class ViewsSharedModule {
7786
8076
  };
7787
8077
  ViewsSharedModule = __decorate([
7788
8078
  NgModule({
7789
- imports: [CommonModule, IntlModule, SharedModule],
8079
+ imports: [CommonModule, IntlModule, SharedModule, ButtonsModule],
7790
8080
  exports: [
7791
8081
  DECLARATIONS,
7792
8082
  IntlModule,
@@ -9115,7 +9405,7 @@ const getNextDate = (date, count, numberOfDays) => getDate(addDays(date, numberO
9115
9405
  */
9116
9406
  class DayTimeViewComponent extends BaseView {
9117
9407
  constructor(changeDetector, viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization) {
9118
- super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization);
9408
+ super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, changeDetector);
9119
9409
  this.changeDetector = changeDetector;
9120
9410
  this.numberOfDays = 1;
9121
9411
  this.startTime = '00:00';
@@ -9601,8 +9891,8 @@ let MultiDayViewRendererComponent = class MultiDayViewRendererComponent extends
9601
9891
  }
9602
9892
  super.updateHintContainer();
9603
9893
  }
9604
- onRelease() {
9605
- super.onRelease();
9894
+ onRelease(args) {
9895
+ super.onRelease(args);
9606
9896
  this.dragContainers = null;
9607
9897
  }
9608
9898
  updateDragContainer(args) {
@@ -9763,7 +10053,7 @@ MultiDayViewRendererComponent = __decorate([
9763
10053
  </tr>
9764
10054
  </table>
9765
10055
  <div style="position: relative;" *ngIf="!verticalResources.length">
9766
- <table class="k-scheduler-table k-scheduler-header-all-day" aria-hidden="true">
10056
+ <table class="k-scheduler-table k-scheduler-header-all-day k-user-select-none" aria-hidden="true">
9767
10057
  <tr>
9768
10058
  <ng-container *ngFor="let resource of horizontalResources | resourceIterator; let resourceIndex = index; trackBy: itemIndex;">
9769
10059
  <td *ngFor="let slot of daySlots; let index = index; trackBy: itemIndex"
@@ -9771,6 +10061,12 @@ MultiDayViewRendererComponent = __decorate([
9771
10061
  [start]="slot.start"
9772
10062
  [end]="slot.end"
9773
10063
  [id]="{ resourceIndex: resourceIndex, rangeIndex: 0, index: index }"
10064
+ [class.k-state-selected]="isSlotSelected({
10065
+ start: toPlainDate(slot.start),
10066
+ end: toPlainDate(slot.end),
10067
+ isAllDay: true,
10068
+ resources: resourcesByIndex(resourceIndex)
10069
+ })"
9774
10070
  [ngClass]="allDaySlotClass(slot, resourceIndex)">
9775
10071
  <ng-container *ngIf="allDaySlotTemplateRef" [ngTemplateOutlet]="allDaySlotTemplateRef"
9776
10072
  [ngTemplateOutletContext]="{ date: slot.start, resources: resourcesByIndex(resourceIndex) }"></ng-container>
@@ -9852,7 +10148,7 @@ MultiDayViewRendererComponent = __decorate([
9852
10148
  </ng-container>
9853
10149
  </table>
9854
10150
  </div>
9855
- <div class="k-scheduler-content" #content>
10151
+ <div class="k-scheduler-content k-user-select-none" #content>
9856
10152
  <ng-container *ngIf="showCurrentTime">
9857
10153
  <div *ngFor="let resource of verticalResources | resourceIterator; trackBy: itemIndex;"
9858
10154
  #currentTimeMarker class="k-current-time">
@@ -9865,6 +10161,12 @@ MultiDayViewRendererComponent = __decorate([
9865
10161
  daySlot
9866
10162
  [start]="slot.start"
9867
10163
  [end]="slot.end"
10164
+ [class.k-state-selected]="isSlotSelected({
10165
+ start: toPlainDate(slot.start),
10166
+ end: toPlainDate(slot.end),
10167
+ isAllDay: true,
10168
+ resources: resourcesByIndex(verticalIndex)
10169
+ })"
9868
10170
  [id]="{ resourceIndex: verticalIndex, rangeIndex: 0, index: index }">
9869
10171
  <ng-container *ngIf="allDaySlotTemplateRef" [ngTemplateOutlet]="allDaySlotTemplateRef"
9870
10172
  [ngTemplateOutletContext]="{ date: slot.start, resources: resourcesByIndex(verticalIndex) }"></ng-container>
@@ -9883,6 +10185,12 @@ MultiDayViewRendererComponent = __decorate([
9883
10185
  [workWeekStart]="workWeekStart"
9884
10186
  [workWeekEnd]="workWeekEnd"
9885
10187
  [id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
10188
+ [class.k-state-selected]="isSlotSelected({
10189
+ start: toPlainDateTime(daySlot.start, slot.start),
10190
+ end: toPlainDateTime(daySlot.start, slot.end),
10191
+ isAllDay: false,
10192
+ resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
10193
+ })"
9886
10194
  >
9887
10195
  <ng-container *ngIf="timeSlotTemplateRef" [ngTemplateOutlet]="timeSlotTemplateRef"
9888
10196
  [ngTemplateOutletContext]="{ date: timeSlot.startLocalTime, resources: resourcesByIndex(timeSlot.id.resourceIndex) }">
@@ -10188,7 +10496,7 @@ let DayTimeModule = class DayTimeModule {
10188
10496
  };
10189
10497
  DayTimeModule = __decorate([
10190
10498
  NgModule({
10191
- imports: [CommonModule, SharedModule],
10499
+ imports: [CommonModule, SharedModule, ViewsSharedModule],
10192
10500
  exports: [
10193
10501
  DIRECTIVES
10194
10502
  ],
@@ -10498,7 +10806,7 @@ TimelineMultiDayViewComponent = __decorate([
10498
10806
  class="k-current-time" #currentTimeMarker>
10499
10807
  </div>
10500
10808
  </ng-container>
10501
- <table class="k-scheduler-table" #contentTable role="presentation">
10809
+ <table class="k-scheduler-table k-user-select-none" #contentTable role="presentation">
10502
10810
  <colgroup>
10503
10811
  <col *ngFor="let slotIndex of slotsCount | repeat; trackBy: itemIndex;" [ngStyle]="{ 'width.px': columnWidth }" />
10504
10812
  </colgroup>
@@ -10515,7 +10823,14 @@ TimelineMultiDayViewComponent = __decorate([
10515
10823
  [workDayEnd]="workDayEndTime"
10516
10824
  [workWeekStart]="workWeekStart"
10517
10825
  [workWeekEnd]="workWeekEnd"
10826
+ selectableSlot
10518
10827
  [id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
10828
+ [class.k-state-selected]="isSlotSelected({
10829
+ start: toPlainDateTime(daySlot.start, slot.start),
10830
+ end: toPlainDateTime(daySlot.start, slot.end),
10831
+ isAllDay: false,
10832
+ resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
10833
+ })"
10519
10834
  >
10520
10835
  <ng-container *ngIf="timeSlotTemplateRef" [ngTemplateOutlet]="timeSlotTemplateRef"
10521
10836
  [ngTemplateOutletContext]="{ date: timeSlot.start, resources: resourcesByIndex(timeSlot.id.resourceIndex ) }">
@@ -11815,7 +12130,7 @@ EditDialogComponent = __decorate([
11815
12130
  <label for='k-event-title'>{{ textFor('editorEventTitle') }}</label>
11816
12131
  </div>
11817
12132
  <div class='k-edit-field'>
11818
- <input #title id='k-event-title' class='k-textbox' placeholder='Title' [formControl]='formGroup.get(fields.title)' />
12133
+ <input #title id='k-event-title' kendoTextBox placeholder='Title' [formControl]='formGroup.get(fields.title)' />
11819
12134
  </div>
11820
12135
 
11821
12136
  <div class='k-edit-label'>
@@ -11857,17 +12172,17 @@ EditDialogComponent = __decorate([
11857
12172
  </ng-container>
11858
12173
 
11859
12174
  <div class='k-edit-field' *ngIf="hasAllDay">
11860
- <input type='checkbox' id='k-is-allday-chkbox' class='k-checkbox' [formControl]='formGroup.get(fields.isAllDay)' />
12175
+ <input type='checkbox' id='k-is-allday-chkbox' kendoCheckBox [formControl]='formGroup.get(fields.isAllDay)' />
11861
12176
  <label class='k-checkbox-label' for='k-is-allday-chkbox'>{{ textFor('editorEventAllDay') }}</label>
11862
12177
  </div>
11863
12178
 
11864
12179
  <div class='k-edit-field' *ngIf="hasStartTimeZone">
11865
- <input type='checkbox' id='k-set-timezone' class='k-checkbox'
12180
+ <input type='checkbox' id='k-set-timezone' kendoCheckBox
11866
12181
  formControlName='startTimezoneCheckbox' />
11867
12182
  <label class='k-checkbox-label' for='k-set-timezone'>{{ textFor('editorEventTimeZone') }}</label>
11868
12183
 
11869
12184
  <ng-container *ngIf="isStartTimeZoneVisible && hasEndTimeZone">
11870
- <input type='checkbox' id='k-use-separate' class='k-checkbox' formControlName='endTimezoneCheckbox' />
12185
+ <input type='checkbox' id='k-use-separate' kendoCheckBox formControlName='endTimezoneCheckbox' />
11871
12186
  <label class='k-checkbox-label' for='k-use-separate'>{{ textFor('editorEventSeparateTimeZones') }}</label>
11872
12187
  </ng-container>
11873
12188
  </div>
@@ -11886,7 +12201,7 @@ EditDialogComponent = __decorate([
11886
12201
  <label for='k-event-description'>{{ textFor('editorEventDescription') }}</label>
11887
12202
  </div>
11888
12203
  <div class='k-edit-field'>
11889
- <textarea id='k-event-description' class='k-textbox' [formControl]='formGroup.get(fields.description)'></textarea>
12204
+ <textarea id='k-event-description' kendoTextArea [formControl]='formGroup.get(fields.description)'></textarea>
11890
12205
  </div>
11891
12206
  </ng-container>
11892
12207
 
@@ -11931,8 +12246,8 @@ EditDialogComponent = __decorate([
11931
12246
  </ng-container>
11932
12247
 
11933
12248
  <kendo-dialog-actions>
11934
- <button class="k-button" (click)="onCancel($event)">{{ textFor('cancel') }}</button>
11935
- <button class="k-button k-primary" (click)="onSave($event)" [disabled]="!formGroup.valid">{{ textFor('save') }}</button>
12249
+ <button kendoButton (click)="onCancel($event)">{{ textFor('cancel') }}</button>
12250
+ <button kendoButton themeColor="primary" (click)="onSave($event)" [disabled]="!formGroup.valid">{{ textFor('save') }}</button>
11936
12251
  </kendo-dialog-actions>
11937
12252
  </kendo-dialog>
11938
12253
  `
@@ -12023,7 +12338,13 @@ SchedulerDateTimePickerComponent = __decorate([
12023
12338
  [(value)]='date'
12024
12339
  (valueChange)='onValueChange($event)'
12025
12340
  ></kendo-timepicker>
12026
- `
12341
+ `,
12342
+ styles: [`
12343
+ kendo-datepicker,
12344
+ kendo-timepicker {
12345
+ width: 170px;
12346
+ }
12347
+ `]
12027
12348
  })
12028
12349
  ], SchedulerDateTimePickerComponent);
12029
12350
 
@@ -12625,6 +12946,7 @@ let EndRuleRadioButtonDirective = class EndRuleRadioButtonDirective {
12625
12946
  this.changeDetector = changeDetector;
12626
12947
  this.type = 'radio';
12627
12948
  this.radioClass = true;
12949
+ this.radioSizeClass = true;
12628
12950
  this.destroyChange = this.renderer.listen(this.elem, 'change', this.onChange.bind(this));
12629
12951
  }
12630
12952
  ngOnInit() {
@@ -12662,6 +12984,10 @@ __decorate([
12662
12984
  HostBinding('class.k-radio'),
12663
12985
  __metadata("design:type", Boolean)
12664
12986
  ], EndRuleRadioButtonDirective.prototype, "radioClass", void 0);
12987
+ __decorate([
12988
+ HostBinding('class.k-radio-md'),
12989
+ __metadata("design:type", Boolean)
12990
+ ], EndRuleRadioButtonDirective.prototype, "radioSizeClass", void 0);
12665
12991
  __decorate([
12666
12992
  Input("kendoRecurrenceEndRuleRadioButton"),
12667
12993
  __metadata("design:type", String)
@@ -12985,6 +13311,7 @@ let RepeatOnRadioButtonDirective = class RepeatOnRadioButtonDirective {
12985
13311
  this.changeDetector = changeDetector;
12986
13312
  this.type = 'radio';
12987
13313
  this.radioClass = true;
13314
+ this.radioSizeClass = true;
12988
13315
  this.destroyChange = this.renderer.listen(this.elem, 'change', this.onChange.bind(this));
12989
13316
  }
12990
13317
  /* tslint:disable-next-line:no-input-rename */
@@ -13027,6 +13354,10 @@ __decorate([
13027
13354
  HostBinding('class.k-radio'),
13028
13355
  __metadata("design:type", Boolean)
13029
13356
  ], RepeatOnRadioButtonDirective.prototype, "radioClass", void 0);
13357
+ __decorate([
13358
+ HostBinding('class.k-radio-md'),
13359
+ __metadata("design:type", Boolean)
13360
+ ], RepeatOnRadioButtonDirective.prototype, "radioSizeClass", void 0);
13030
13361
  __decorate([
13031
13362
  Input("kendoRecurrenceRepeatOnRadioButton"),
13032
13363
  __metadata("design:type", String),
@@ -13296,7 +13627,9 @@ RecurrenceMonthlyYearlyEditorComponent = __decorate([
13296
13627
  [value]='currentMonthMonthDay'
13297
13628
  [valuePrimitive]='true'
13298
13629
  (valueChange)="onMonthChange($event, 'monthday')"
13299
- [disabled]="isDisabled('monthday')">
13630
+ [disabled]="isDisabled('monthday')"
13631
+ [style.width.px]="170"
13632
+ [style.margin]="'0 .4ex 0 1ex'">
13300
13633
  </kendo-dropdownlist>
13301
13634
  </ng-template>
13302
13635
 
@@ -13314,7 +13647,8 @@ RecurrenceMonthlyYearlyEditorComponent = __decorate([
13314
13647
  [title]="numericOptions.title"
13315
13648
  [value]='monthDay'
13316
13649
  (valueChange)='onMonthDayChange($event)'
13317
- [disabled]="isDisabled('monthday')">
13650
+ [disabled]="isDisabled('monthday')"
13651
+ [style.margin]="'0 .4ex 0 1ex'">
13318
13652
  </kendo-numerictextbox>
13319
13653
  </li>
13320
13654
  <li>
@@ -13328,7 +13662,9 @@ RecurrenceMonthlyYearlyEditorComponent = __decorate([
13328
13662
  [value]='offset'
13329
13663
  [valuePrimitive]='true'
13330
13664
  (valueChange)='onOffsetPositionChange($event)'
13331
- [disabled]="isDisabled('weekday')">
13665
+ [disabled]="isDisabled('weekday')"
13666
+ [style.width.px]="170"
13667
+ [style.margin]="'0 .4ex 0 1ex'">
13332
13668
  </kendo-dropdownlist>
13333
13669
 
13334
13670
  <kendo-dropdownlist
@@ -13338,7 +13674,9 @@ RecurrenceMonthlyYearlyEditorComponent = __decorate([
13338
13674
  [value]='weekDay'
13339
13675
  [valuePrimitive]='true'
13340
13676
  (valueChange)='onWeekDayChange($event)'
13341
- [disabled]="isDisabled('weekday')">
13677
+ [disabled]="isDisabled('weekday')"
13678
+ [style.width.px]="170"
13679
+ [style.margin]="'0 .4ex 0 1ex'">
13342
13680
  </kendo-dropdownlist>
13343
13681
 
13344
13682
  <ng-template [ngIf]="currentFreq === 'yearly'">
@@ -13351,7 +13689,9 @@ RecurrenceMonthlyYearlyEditorComponent = __decorate([
13351
13689
  [value]='currentMonthWeekDay'
13352
13690
  [valuePrimitive]='true'
13353
13691
  (valueChange)="onMonthChange($event, 'weekday')"
13354
- [disabled]="isDisabled('weekday')">
13692
+ [disabled]="isDisabled('weekday')"
13693
+ [style.width.px]="170"
13694
+ [style.margin]="'0 .4ex 0 1ex'">
13355
13695
  </kendo-dropdownlist>
13356
13696
  </ng-template>
13357
13697
  </li>
@@ -13877,6 +14217,107 @@ ShortcutsDirective = __decorate([
13877
14217
  DialogsService])
13878
14218
  ], ShortcutsDirective);
13879
14219
 
14220
+ /**
14221
+ * A directive which manages the in-memory selection state of the Scheduler slots
14222
+ * ([see example]({% slug slotselection_scheduler %}#toc-built-in-directive)).
14223
+ */
14224
+ let SlotSelectableDirective = class SlotSelectableDirective {
14225
+ constructor(scheduler, cdr) {
14226
+ this.scheduler = scheduler;
14227
+ this.cdr = cdr;
14228
+ /**
14229
+ * Fires when the currently selected slot range has changed through user interaction.
14230
+ */
14231
+ this.slotSelectionChange = new EventEmitter();
14232
+ this.selectedRange = null;
14233
+ this.slotSelectionChangeSource = new EventEmitter();
14234
+ this.subscriptions = new Subscription();
14235
+ this.scheduler.selectable = true;
14236
+ this.subscriptions.add(this.slotSelectionChangeSource
14237
+ .pipe(distinctUntilChanged(isSameRange)).subscribe((v) => {
14238
+ this.slotSelectionChange.emit(v);
14239
+ }));
14240
+ const start$ = this.scheduler.slotDragStart;
14241
+ const drag$ = this.scheduler.slotDrag;
14242
+ const end$ = this.scheduler.slotDragEnd;
14243
+ const startSource = start$.pipe(filter(e => !e.isDefaultPrevented()));
14244
+ this.subscriptions.add(startSource.subscribe(e => this.initDragSelect(e)));
14245
+ this.subscriptions.add(drag$.subscribe(e => this.onDrag(e)));
14246
+ this.subscriptions.add(end$.subscribe(() => this.onRelease()));
14247
+ }
14248
+ ngOnInit() {
14249
+ this.scheduler.isSlotSelected = this.isSlotSelected.bind(this);
14250
+ }
14251
+ ngOnChanges(changes) {
14252
+ if (isChanged("slotSelection", changes, false)) {
14253
+ /**
14254
+ * The default values for resources below are necessarry because this is not fixed yet: https://github.com/telerik/kendo-angular-scheduler/pull/338
14255
+ */
14256
+ const resources = this.scheduler.resources ? [this.scheduler.resources[0].data[0]] : [undefined];
14257
+ this.selectedRange = Object.assign({}, { isAllDay: false, resources }, changes.slotSelection.currentValue);
14258
+ this.cdr.markForCheck();
14259
+ }
14260
+ }
14261
+ ngOnDestroy() {
14262
+ this.subscriptions.unsubscribe();
14263
+ }
14264
+ isSlotSelected({ start, end, isAllDay, resources }) {
14265
+ if (!start || !end || !this.selectedRange) {
14266
+ return false;
14267
+ }
14268
+ const match = resourcesMatch(this.selectedRange.resources, resources, true);
14269
+ if (!match) {
14270
+ return false; // Limit selection to the grouped resource where the drag started.
14271
+ }
14272
+ return this.selectedRange && isAllDay === this.selectedRange.isAllDay && this.isInRange(start, end);
14273
+ }
14274
+ initDragSelect({ start, end, isAllDay, resources }) {
14275
+ this.selectionOriginResources = resources.slice();
14276
+ this.selectedRange = { start, end, isAllDay, resources: resources.slice() };
14277
+ this.cdr.markForCheck();
14278
+ }
14279
+ onDrag({ start, end, resources }) {
14280
+ const match = resourcesMatch(this.selectionOriginResources, resources, false); // Not strict - allow matching [ undefined ] and [ undefined ]
14281
+ if (!match) {
14282
+ return; // Don't change selection when dragging over a different grouped resource's cells.
14283
+ }
14284
+ this.selectedRange.start = start;
14285
+ this.selectedRange.end = end;
14286
+ this.cdr.markForCheck();
14287
+ }
14288
+ onRelease() {
14289
+ this.selectionOriginResources = null;
14290
+ if (this.selectedRange) {
14291
+ this.slotSelectionChangeSource.emit(this.selectedRange);
14292
+ }
14293
+ }
14294
+ /**
14295
+ * @hidden
14296
+ * Checks if the selected range contains a local date range.
14297
+ */
14298
+ isInRange(start, end) {
14299
+ if (!this.selectedRange) {
14300
+ return;
14301
+ }
14302
+ return intersects(start, end, this.selectedRange.start, this.selectedRange.end);
14303
+ }
14304
+ };
14305
+ __decorate([
14306
+ Input(),
14307
+ __metadata("design:type", Object)
14308
+ ], SlotSelectableDirective.prototype, "slotSelection", void 0);
14309
+ __decorate([
14310
+ Output(),
14311
+ __metadata("design:type", EventEmitter)
14312
+ ], SlotSelectableDirective.prototype, "slotSelectionChange", void 0);
14313
+ SlotSelectableDirective = __decorate([
14314
+ Directive({
14315
+ selector: '[kendoSchedulerSlotSelectable]'
14316
+ }),
14317
+ __metadata("design:paramtypes", [SchedulerComponent,
14318
+ ChangeDetectorRef])
14319
+ ], SlotSelectableDirective);
14320
+
13880
14321
  const TEMPLATES = [
13881
14322
  AgendaDateTemplateDirective,
13882
14323
  AgendaTimeTemplateDirective,
@@ -13897,6 +14338,7 @@ const declarations = [
13897
14338
  DataBindingDirective,
13898
14339
  ShortcutsDirective,
13899
14340
  ReactiveEditingDirective,
14341
+ SlotSelectableDirective,
13900
14342
  SchedulerDateTimePickerComponent,
13901
14343
  RecurrenceEditorComponent,
13902
14344
  RecurrenceEndRuleEditorComponent,
@@ -13928,6 +14370,8 @@ const publicDirectives$1 = [
13928
14370
  ];
13929
14371
  const importedKendoModules = [
13930
14372
  ButtonsModule,
14373
+ CheckBoxModule,
14374
+ TextAreaModule,
13931
14375
  DateInputsModule,
13932
14376
  DialogModule,
13933
14377
  NumericTextBoxModule,
@@ -14538,4 +14982,4 @@ PDFModule = __decorate([
14538
14982
  * Generated bundle index. Do not edit.
14539
14983
  */
14540
14984
 
14541
- export { DataBindingDirective, EditingDirectiveBase, ReactiveEditingDirective, SCHEDULER_DATETIMEPICKER_VALUE_ACCESSOR, SchedulerDateTimePickerComponent, DialogsService, EditDialogTemplateDirective, EditDialogComponent, EditService, LocalDataChangesService, EndRuleRadioButtonDirective, RecurrenceEditorCustomMessagesComponent, RecurrenceEditorLocalizedMessagesDirective, Messages$1 as Messages, RecurrenceLocalizationService, RECURRENCE_VALUE_ACCESSOR, RecurrenceEndRuleEditorComponent, RecurrenceFrequencyEditorComponent, RecurrenceIntervalEditorComponent, RecurrenceMonthlyYearlyEditorComponent, RecurrenceWeekdayRuleEditorComponent, RecurrenceService, RepeatOnRadioButtonDirective, ResourceEditorBase, MULTIPLE_RESOURCE_VALUE_ACCESSOR, MultipleResourceEditorComponent, SINGLE_RESOURCE_VALUE_ACCESSOR, SingleResourceEditorComponent, TIME_ZONE_VALUE_ACCESSOR, TimeZoneEditorComponent, CreateEvent, PreventableEvent$1 as PreventableEvent, LoadingComponent, SchedulerCustomMessagesComponent, LocalizedMessagesDirective, Messages as Messages$1, SchedulerLocalizationService, FocusService, ShortcutsDirective, ToolbarNavigationComponent, ToolbarTemplateDirective, ToolbarComponent, ToolbarModule, publicDirectives, ToolbarViewSelectorComponent, AgendaHeaderItemComponent, AgendaHeaderComponent, AgendaTaskItemComponent, AgendaViewInternalComponent, AgendaListComponent, AgendaViewModule, BaseView, ConfigurationViewBase, DomEventsService, HintContainerComponent, RepeatPipe, ResizeHintComponent, ResourceIteratorPipe, ViewFooterComponent, ViewsSharedModule, WorkHoursFooterDirective, DayTimeSlotService, DayTimeViewBase, DayTimeViewItemComponent, DayTimeViewComponent, DayTimeModule, DaySlotDirective, TimeSlotDirective, MonthSlotDirective, MonthSlotService, MonthViewItemComponent, MonthViewRendererComponent, MonthViewComponent, MonthViewModule, MultiDayViewBase, MultiDayViewRendererComponent, MultiDayViewComponent, MultiDayViewModule, WorkWeekViewComponent, SchedulerViewDirective, AgendaDateTemplateDirective, AgendaTimeTemplateDirective, AllDayEventTemplateDirective, AllDaySlotTemplateDirective, DateHeaderTemplateDirective, EventTemplateDirective, GroupHeaderTemplateDirective, MajorTimeHeaderTemplateDirective, MinorTimeHeaderTemplateDirective, MonthDaySlotTemplateDirective, TimeSlotTemplateDirective, TimelineBase, TimelineMonthViewComponent, TimelineMultiDayViewComponent, TimelineViewComponent, TimelineViewModule, TimelineWeekViewComponent, BaseSlotDirective, BaseSlotService, BaseViewItem, SchedulerComponent, SchedulerModule, ViewContextService, ViewStateService, ToolbarService, AgendaViewComponent, DayViewComponent, WeekViewComponent, RecurrenceEditorComponent, BaseEditService, PDFModule, PDFComponent, PDFService, PDFCommandDirective, PDFExportEvent, FocusableDirective, SharedModule, SchedulerView, DateChangeEvent, NavigateEvent, SlotClickEvent, EventClickEvent, EventKeydownEvent, VIEW_EVENT_MAP, CancelEvent, EditEventBase, RemoveEvent, SaveEvent, ResizeStartEvent, ResizeEvent, ResizeEndEvent, DragStartEvent, DragEvent, DragEndEvent, EditEvent, AddEvent };
14985
+ export { DataBindingDirective, EditingDirectiveBase, ReactiveEditingDirective, SCHEDULER_DATETIMEPICKER_VALUE_ACCESSOR, SchedulerDateTimePickerComponent, DialogsService, EditDialogTemplateDirective, EditDialogComponent, EditService, LocalDataChangesService, EndRuleRadioButtonDirective, RecurrenceEditorCustomMessagesComponent, RecurrenceEditorLocalizedMessagesDirective, Messages$1 as Messages, RecurrenceLocalizationService, RECURRENCE_VALUE_ACCESSOR, RecurrenceEndRuleEditorComponent, RecurrenceFrequencyEditorComponent, RecurrenceIntervalEditorComponent, RecurrenceMonthlyYearlyEditorComponent, RecurrenceWeekdayRuleEditorComponent, RecurrenceService, RepeatOnRadioButtonDirective, ResourceEditorBase, MULTIPLE_RESOURCE_VALUE_ACCESSOR, MultipleResourceEditorComponent, SINGLE_RESOURCE_VALUE_ACCESSOR, SingleResourceEditorComponent, TIME_ZONE_VALUE_ACCESSOR, TimeZoneEditorComponent, CreateEvent, PreventableEvent$1 as PreventableEvent, LoadingComponent, SchedulerCustomMessagesComponent, LocalizedMessagesDirective, Messages as Messages$1, SchedulerLocalizationService, FocusService, ShortcutsDirective, ToolbarNavigationComponent, ToolbarTemplateDirective, ToolbarComponent, ToolbarModule, publicDirectives, ToolbarViewSelectorComponent, AgendaHeaderItemComponent, AgendaHeaderComponent, AgendaTaskItemComponent, AgendaViewInternalComponent, AgendaListComponent, AgendaViewModule, BaseView, ConfigurationViewBase, DomEventsService, HintContainerComponent, RepeatPipe, ResizeHintComponent, ResourceIteratorPipe, SlotSelectableDirective, ViewFooterComponent, ViewsSharedModule, WorkHoursFooterDirective, DayTimeSlotService, DayTimeViewBase, DayTimeViewItemComponent, DayTimeViewComponent, DayTimeModule, DaySlotDirective, TimeSlotDirective, MonthSlotDirective, MonthSlotService, MonthViewItemComponent, MonthViewRendererComponent, MonthViewComponent, MonthViewModule, MultiDayViewBase, MultiDayViewRendererComponent, MultiDayViewComponent, MultiDayViewModule, WorkWeekViewComponent, SchedulerViewDirective, AgendaDateTemplateDirective, AgendaTimeTemplateDirective, AllDayEventTemplateDirective, AllDaySlotTemplateDirective, DateHeaderTemplateDirective, EventTemplateDirective, GroupHeaderTemplateDirective, MajorTimeHeaderTemplateDirective, MinorTimeHeaderTemplateDirective, MonthDaySlotTemplateDirective, TimeSlotTemplateDirective, TimelineBase, TimelineMonthViewComponent, TimelineMultiDayViewComponent, TimelineViewComponent, TimelineViewModule, TimelineWeekViewComponent, BaseSlotDirective, BaseSlotService, BaseViewItem, SchedulerComponent, SchedulerModule, ViewContextService, ViewStateService, ToolbarService, AgendaViewComponent, DayViewComponent, WeekViewComponent, RecurrenceEditorComponent, BaseEditService, PDFModule, PDFComponent, PDFService, PDFCommandDirective, PDFExportEvent, FocusableDirective, SharedModule, IsSlotSelectedArgs, SchedulerView, DateChangeEvent, NavigateEvent, SlotClickEvent, EventClickEvent, EventKeydownEvent, VIEW_EVENT_MAP, CancelEvent, EditEventBase, RemoveEvent, SaveEvent, ResizeStartEvent, ResizeEvent, ResizeEndEvent, DragStartEvent, DragEvent, DragEndEvent, EditEvent, AddEvent, SlotDragStartEvent, SlotDragEvent, SlotDragEndEvent };