@event-calendar/core 5.0.5 → 5.1.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 (79) hide show
  1. package/README.md +15 -4
  2. package/dist/index.css +2 -2
  3. package/dist/index.js +2201 -2128
  4. package/package.json +2 -2
  5. package/src/Buttons.svelte +36 -37
  6. package/src/Calendar.svelte +34 -37
  7. package/src/Toolbar.svelte +4 -4
  8. package/src/lib/components/BaseDay.svelte +13 -10
  9. package/src/lib/components/BaseEvent.svelte +17 -17
  10. package/src/lib/components/ColHead.svelte +6 -6
  11. package/src/lib/components/DayHeader.svelte +3 -3
  12. package/src/lib/components/InteractableEvent.svelte +7 -8
  13. package/src/lib/derived.js +80 -0
  14. package/src/lib/index.js +1 -2
  15. package/src/lib/slots.js +16 -16
  16. package/src/lib/utils.js +4 -9
  17. package/src/lib/view.js +0 -8
  18. package/src/plugins/day-grid/Day.svelte +25 -23
  19. package/src/plugins/day-grid/Event.svelte +15 -13
  20. package/src/plugins/day-grid/Popup.svelte +12 -12
  21. package/src/plugins/day-grid/View.svelte +24 -36
  22. package/src/plugins/day-grid/derived.js +102 -0
  23. package/src/plugins/day-grid/index.js +47 -36
  24. package/src/plugins/day-grid/state.svelte.js +19 -0
  25. package/src/plugins/interaction/Action.svelte +108 -76
  26. package/src/plugins/interaction/Auxiliary.svelte +9 -38
  27. package/src/plugins/interaction/Pointer.svelte +12 -17
  28. package/src/plugins/interaction/Resizer.svelte +9 -7
  29. package/src/plugins/interaction/effects.js +37 -0
  30. package/src/plugins/interaction/index.js +44 -38
  31. package/src/plugins/interaction/lib/utils.js +1 -1
  32. package/src/plugins/interaction/state.svelte.js +12 -0
  33. package/src/plugins/list/Day.svelte +8 -7
  34. package/src/plugins/list/Event.svelte +3 -3
  35. package/src/plugins/list/View.svelte +18 -13
  36. package/src/plugins/list/index.js +51 -43
  37. package/src/plugins/list/state.svelte.js +8 -0
  38. package/src/plugins/resource-time-grid/Label.svelte +8 -8
  39. package/src/plugins/resource-time-grid/View.svelte +38 -17
  40. package/src/plugins/resource-time-grid/derived.js +67 -0
  41. package/src/plugins/resource-time-grid/index.js +34 -28
  42. package/src/plugins/resource-time-grid/state.svelte.js +21 -0
  43. package/src/plugins/resource-timeline/Day.svelte +9 -4
  44. package/src/plugins/resource-timeline/Event.svelte +7 -6
  45. package/src/plugins/resource-timeline/Expander.svelte +7 -6
  46. package/src/plugins/resource-timeline/NowIndicator.svelte +10 -11
  47. package/src/plugins/resource-timeline/View.svelte +45 -63
  48. package/src/plugins/resource-timeline/derived.js +167 -0
  49. package/src/plugins/resource-timeline/index.js +17 -21
  50. package/src/plugins/resource-timeline/lib.js +4 -65
  51. package/src/plugins/resource-timeline/state.svelte.js +18 -0
  52. package/src/plugins/time-grid/Day.svelte +7 -2
  53. package/src/plugins/time-grid/Event.svelte +6 -6
  54. package/src/plugins/time-grid/NowIndicator.svelte +10 -9
  55. package/src/plugins/time-grid/View.svelte +46 -59
  56. package/src/plugins/time-grid/derived.js +162 -0
  57. package/src/plugins/time-grid/index.js +31 -25
  58. package/src/plugins/time-grid/lib.js +18 -74
  59. package/src/plugins/time-grid/options.js +21 -16
  60. package/src/plugins/time-grid/state.svelte.js +44 -0
  61. package/src/storage/derived.js +144 -0
  62. package/src/storage/effects.js +156 -0
  63. package/src/storage/options.svelte.js +275 -0
  64. package/src/storage/state.svelte.js +69 -0
  65. package/src/styles/events.css +1 -1
  66. package/src/Auxiliary.svelte +0 -47
  67. package/src/lib/debounce.js +0 -20
  68. package/src/lib/stores.js +0 -63
  69. package/src/plugins/day-grid/lib.js +0 -61
  70. package/src/plugins/day-grid/stores.js +0 -5
  71. package/src/plugins/resource-time-grid/lib.js +0 -31
  72. package/src/plugins/resource-time-grid/stores.js +0 -34
  73. package/src/plugins/resource-timeline/Header.svelte +0 -44
  74. package/src/plugins/resource-timeline/Label.svelte +0 -38
  75. package/src/plugins/resource-timeline/stores.js +0 -48
  76. package/src/plugins/time-grid/stores.js +0 -49
  77. package/src/storage/options.js +0 -136
  78. package/src/storage/state.js +0 -168
  79. package/src/storage/stores.js +0 -234
@@ -1,38 +1,44 @@
1
- import {btnTextDay, btnTextWeek, themeView} from '#lib';
1
+ import {assign, btnTextDay, btnTextWeek, themeView} from '#lib';
2
+ import {setExtensions} from './lib.js';
2
3
  import {createTROptions, createTRROptions, createTRRParsers} from './options.js';
3
- import {createTRRStores, createTRStores} from './stores.js';
4
4
  import View from './View.svelte';
5
5
 
6
6
  export default {
7
7
  createOptions(options) {
8
- createTROptions(options);
9
8
  createTRROptions(options);
9
+ createTROptions(options);
10
10
  // Common options
11
- options.buttonText.timeGridDay = 'day';
12
- options.buttonText.timeGridWeek = 'week';
13
- options.view = 'timeGridWeek';
14
- options.views.timeGridDay = {
15
- buttonText: btnTextDay,
16
- component: View,
17
- dayHeaderFormat: {weekday: 'long'},
18
- duration: {days: 1},
19
- theme: themeView('ec-time-grid ec-day-view'),
20
- titleFormat: {year: 'numeric', month: 'long', day: 'numeric'}
21
- };
22
- options.views.timeGridWeek = {
23
- buttonText: btnTextWeek,
24
- component: View,
25
- duration: {weeks: 1},
26
- theme: themeView('ec-time-grid ec-week-view')
27
- };
11
+ assign(options.buttonText, {
12
+ timeGridDay: 'day',
13
+ timeGridWeek: 'week'
14
+ });
15
+ assign(options, {
16
+ view: 'timeGridWeek'
17
+ });
18
+ assign(options.views, {
19
+ timeGridDay: {
20
+ buttonText: btnTextDay,
21
+ component: initViewComponent,
22
+ dayHeaderFormat: {weekday: 'long'},
23
+ duration: {days: 1},
24
+ theme: themeView('ec-time-grid ec-day-view'),
25
+ titleFormat: {year: 'numeric', month: 'long', day: 'numeric'}
26
+ },
27
+ timeGridWeek: {
28
+ buttonText: btnTextWeek,
29
+ component: initViewComponent,
30
+ duration: {weeks: 1},
31
+ theme: themeView('ec-time-grid ec-week-view')
32
+ }
33
+ });
28
34
  },
29
35
 
30
36
  createParsers(parsers) {
31
37
  createTRRParsers(parsers);
32
- },
33
-
34
- createStores(state) {
35
- createTRRStores(state);
36
- createTRStores(state);
37
38
  }
38
39
  }
40
+
41
+ function initViewComponent(mainState) {
42
+ setExtensions(mainState);
43
+ return View;
44
+ }
@@ -1,79 +1,8 @@
1
1
  import {
2
- addDay, addDuration, assign, bgEvent, cloneDate, createAllDayChunks, createEventChunk, datesEqual, eventIntersects,
3
- isFunction, outsideRange, prepareAllDayChunks,
2
+ addDuration, assign, cloneDate, createEventChunk, DAY_IN_SECONDS, eventIntersects, isFunction, subtractDay
4
3
  } from '#lib';
5
4
 
6
- /**
7
- * Days with prepared start and end times
8
- */
9
- export function createGrid($_viewDates, $_slotTimeLimits, $validRange, $highlightedDates) {
10
- let days = [];
11
- let gridColumn = 1;
12
- for (let date of $_viewDates) {
13
- days.push({
14
- gridColumn,
15
- gridRow: 1,
16
- resource: undefined,
17
- start: addDuration(cloneDate(date), $_slotTimeLimits.min),
18
- end: addDuration(cloneDate(date), $_slotTimeLimits.max),
19
- dayStart: date,
20
- dayEnd: addDay(cloneDate(date)),
21
- disabled: outsideRange(date, $validRange),
22
- highlight: $highlightedDates.some(d => datesEqual(d, date))
23
- });
24
- ++ gridColumn;
25
- }
26
-
27
- return [days];
28
- }
29
-
30
- export function createEventChunks($_filteredEvents, grid) {
31
- let chunks = [];
32
- let bgChunks = [];
33
- let allDayChunks = [];
34
- let allDayBgChunks = [];
35
- for (let event of $_filteredEvents) {
36
- for (let days of grid) {
37
- if (bgEvent(event.display)) {
38
- bgChunks = bgChunks.concat(createChunks(event, days));
39
- if (event.allDay) {
40
- allDayBgChunks = allDayBgChunks.concat(createAllDayChunks(event, days));
41
- }
42
- } else {
43
- if (event.allDay) {
44
- allDayChunks = allDayChunks.concat(createAllDayChunks(event, days));
45
- } else {
46
- chunks = chunks.concat(createChunks(event, days));
47
- }
48
- }
49
- }
50
- }
51
- groupChunks(chunks);
52
- prepareAllDayChunks(allDayChunks);
53
-
54
- return {chunks, bgChunks, allDayChunks, allDayBgChunks};
55
- }
56
-
57
- export function createIEventChunks($_iEvents, grid) {
58
- let iChunks = [];
59
- let allDayIChunks = [];
60
- for (let event of $_iEvents) {
61
- if (!event) {
62
- continue;
63
- }
64
- for (let days of grid) {
65
- if (event.allDay) {
66
- allDayIChunks = allDayIChunks.concat(createAllDayChunks(event, days));
67
- } else {
68
- iChunks = iChunks.concat(createChunks(event, days));
69
- }
70
- }
71
- }
72
-
73
- return {iChunks, allDayIChunks};
74
- }
75
-
76
- function createChunks(event, days) {
5
+ export function createChunks(event, days) {
77
6
  let chunks = [];
78
7
  for (let {gridColumn, gridRow, resource, start, end, disabled} of days) {
79
8
  if (!disabled && eventIntersects(event, start, end, resource)) {
@@ -92,7 +21,7 @@ function createChunks(event, days) {
92
21
  return chunks;
93
22
  }
94
23
 
95
- function groupChunks(chunks) {
24
+ export function groupChunks(chunks) {
96
25
  let groups = {};
97
26
  for (let chunk of chunks) {
98
27
  let {gridColumn} = chunk;
@@ -140,3 +69,18 @@ export function createAllDayContent(allDayContent) {
140
69
 
141
70
  return content;
142
71
  }
72
+
73
+ export function setExtensions(mainState) {
74
+ mainState.extensions.activeRange = (start, end) => {
75
+ // Dependencies
76
+ let {options: {slotMaxTime}} = mainState;
77
+ if (slotMaxTime.days || slotMaxTime.seconds > DAY_IN_SECONDS) {
78
+ addDuration(subtractDay(end), slotMaxTime);
79
+ let start2 = subtractDay(cloneDate(end));
80
+ if (start2 < start) {
81
+ start = start2;
82
+ }
83
+ }
84
+ return {start, end};
85
+ };
86
+ }
@@ -1,18 +1,5 @@
1
1
  import {assign, createDuration} from '#lib';
2
2
 
3
- /**
4
- * TimeGrid + ResourceTimeGrid
5
- */
6
- export function createTROptions(options) {
7
- if (!('allDaySlot' in options)) {
8
- assign(options, {
9
- allDayContent: undefined,
10
- allDaySlot: true,
11
- slotEventOverlap: true
12
- });
13
- }
14
- }
15
-
16
3
  /**
17
4
  * TimeGrid + ResourceTimeGrid + ResourceTimeline
18
5
  */
@@ -31,7 +18,8 @@ export function createTRROptions(options) {
31
18
  minute: '2-digit'
32
19
  },
33
20
  slotMaxTime: '24:00:00',
34
- slotMinTime: '00:00:00'
21
+ slotMinTime: '00:00:00',
22
+ snapDuration: undefined
35
23
  });
36
24
  assign(options.theme, {
37
25
  nowIndicator: 'ec-now-indicator',
@@ -41,6 +29,22 @@ export function createTRROptions(options) {
41
29
  }
42
30
  }
43
31
 
32
+ /**
33
+ * TimeGrid + ResourceTimeGrid
34
+ */
35
+ export function createTROptions(options) {
36
+ if (!('allDaySlot' in options)) {
37
+ assign(options, {
38
+ allDayContent: undefined,
39
+ allDaySlot: true,
40
+ slotEventOverlap: true
41
+ });
42
+ assign(options.theme, {
43
+ allDay: 'ec-all-day'
44
+ });
45
+ }
46
+ }
47
+
44
48
  /**
45
49
  * TimeGrid + ResourceTimeGrid + ResourceTimeline
46
50
  */
@@ -51,7 +55,8 @@ export function createTRRParsers(parsers) {
51
55
  slotDuration: createDuration,
52
56
  slotLabelInterval: input => input !== undefined ? createDuration(input) : undefined,
53
57
  slotMaxTime: createDuration,
54
- slotMinTime: createDuration
58
+ slotMinTime: createDuration,
59
+ snapDuration: input => input !== undefined ? createDuration(input) : undefined
55
60
  });
56
61
  }
57
- }
62
+ }
@@ -0,0 +1,44 @@
1
+ import {intl} from '#lib';
2
+ import {slots, slotLabelPeriodicity, slotTimeLimits, grid, eventChunks, iEventChunks, snap} from './derived.js';
3
+
4
+ /**
5
+ * TimeGrid + ResourceTimeGrid + ResourceTimeline
6
+ */
7
+ export function TRRState() {
8
+ return class {
9
+ constructor(mainState) {
10
+ this.intlSlotLabel = $derived.by(intl(mainState, 'slotLabelFormat'));
11
+ this.slotLabelPeriodicity = $derived.by(slotLabelPeriodicity(mainState));
12
+ this.sidebarWidth = $state(0);
13
+ this.snap = $derived.by(snap(mainState));
14
+ }
15
+ };
16
+ }
17
+
18
+ /**
19
+ * TimeGrid + ResourceTimeGrid
20
+ */
21
+ export function TRState(Base) {
22
+ return class extends Base {
23
+ constructor(mainState) {
24
+ super(mainState);
25
+ this.slotTimeLimits = $derived.by(slotTimeLimits(mainState)); // flexible limits
26
+ this.slots = $derived.by(slots(mainState, this));
27
+ let {chunks, bgChunks, allDayChunks, allDayBgChunks} = $derived.by(eventChunks(mainState, this));
28
+ this.chunks = $derived(chunks);
29
+ this.bgChunks = $derived(bgChunks);
30
+ this.allDayChunks = $derived(allDayChunks);
31
+ this.allDayBgChunks = $derived(allDayBgChunks);
32
+ let {iChunks, allDayIChunks} = $derived.by(iEventChunks(mainState, this));
33
+ this.iChunks = $derived(iChunks);
34
+ this.allDayIChunks = $derived(allDayIChunks);
35
+ }
36
+ };
37
+ }
38
+
39
+ export default class ViewState extends TRState(TRRState()) {
40
+ constructor(mainState) {
41
+ super(mainState);
42
+ this.grid = $derived.by(grid(mainState, this));
43
+ }
44
+ }
@@ -0,0 +1,144 @@
1
+ import {untrack} from 'svelte';
2
+ import {
3
+ addDay, addDuration, cloneDate, createView, isFunction, prevClosestDay, setMidnight, subtractDay,
4
+ toEventWithLocalDates, toViewWithLocalDates
5
+ } from '#lib';
6
+
7
+ export function currentRange(mainState) {
8
+ return () => {
9
+ // Dependencies
10
+ let {options: {date, duration, firstDay}} = mainState;
11
+
12
+ let start, end;
13
+
14
+ untrack(() => {
15
+ start = cloneDate(date);
16
+ if (duration.months) {
17
+ start.setUTCDate(1);
18
+ } else if (duration.inWeeks) {
19
+ // First day of week
20
+ prevClosestDay(start, firstDay);
21
+ }
22
+ end = addDuration(cloneDate(start), duration);
23
+ });
24
+
25
+ return {start, end};
26
+ };
27
+ }
28
+
29
+ export function activeRange(mainState) {
30
+ return () => {
31
+ // Dependencies
32
+ let {currentRange, extensions: {activeRange}} = mainState;
33
+
34
+ let start, end;
35
+
36
+ untrack(() => {
37
+ start = cloneDate(currentRange.start);
38
+ end = cloneDate(currentRange.end);
39
+ });
40
+
41
+ return activeRange ? activeRange(start, end) : {start, end};
42
+ };
43
+ }
44
+
45
+ export function filteredEvents(mainState) {
46
+ return () => {
47
+ // Dependencies
48
+ let {events, options: {eventFilter, eventOrder, filterEventsWithResources, resources}} = mainState;
49
+
50
+ let result = [...events];
51
+
52
+ untrack(() => {
53
+ // Filter events
54
+ if (isFunction(eventFilter)) {
55
+ let events2 = events.map(toEventWithLocalDates);
56
+ let view = toViewWithLocalDates(mainState.view);
57
+ result = result
58
+ .filter((event, index) => eventFilter({
59
+ event: toEventWithLocalDates(event),
60
+ index,
61
+ events: events2,
62
+ view
63
+ }));
64
+ }
65
+ if (filterEventsWithResources) {
66
+ result = result.filter(event => resources.some(resource => event.resourceIds.includes(resource.id)));
67
+ }
68
+
69
+ // Sort events
70
+ if (isFunction(eventOrder)) {
71
+ result.sort((a, b) => eventOrder(
72
+ toEventWithLocalDates(a),
73
+ toEventWithLocalDates(b)
74
+ ));
75
+ } else {
76
+ // Sort by start date (all-day events always on top)
77
+ result.sort((a, b) => a.start - b.start || b.allDay - a.allDay);
78
+ }
79
+ });
80
+
81
+ return result;
82
+ };
83
+ }
84
+
85
+ export function viewDates(mainState) {
86
+ return () => {
87
+ // Dependencies
88
+ let {options, activeRange} = mainState;
89
+ let {hiddenDays} = options;
90
+
91
+ let dates = [];
92
+
93
+ untrack(() => {
94
+ let date = setMidnight(cloneDate(activeRange.start));
95
+ let end = setMidnight(cloneDate(activeRange.end));
96
+ while (date < end) {
97
+ if (!hiddenDays.includes(date.getUTCDay())) {
98
+ dates.push(cloneDate(date));
99
+ }
100
+ addDay(date);
101
+ }
102
+ if (!dates.length && hiddenDays.length && hiddenDays.length < 7) {
103
+ // Try to move the date
104
+ while (hiddenDays.includes(options.date.getUTCDay())) {
105
+ mainState.setOption('date', addDay(cloneDate(options.date)));
106
+ }
107
+ }
108
+ });
109
+
110
+ return dates;
111
+ };
112
+ }
113
+
114
+ export function viewTitle(mainState) {
115
+ return () => {
116
+ // Dependencies
117
+ let {activeRange, intlTitle, features, options: {date}} = mainState;
118
+
119
+ let title;
120
+
121
+ untrack(() => {
122
+ title = features.includes('day-grid')
123
+ ? intlTitle.formatRange(date, date)
124
+ : intlTitle.formatRange(activeRange.start, subtractDay(cloneDate(activeRange.end)));
125
+ });
126
+
127
+ return title;
128
+ }
129
+ }
130
+
131
+ export function view(mainState) {
132
+ return () => {
133
+ // Dependencies
134
+ let {activeRange, currentRange, viewTitle, options: {view}} = mainState;
135
+
136
+ let viewObj;
137
+
138
+ untrack(() => {
139
+ viewObj = createView(view, viewTitle, currentRange, activeRange);
140
+ });
141
+
142
+ return viewObj;
143
+ };
144
+ }
@@ -0,0 +1,156 @@
1
+ import {getAbortSignal, tick, untrack} from 'svelte';
2
+ import {
3
+ assign, cloneDate, createDate, createEvents, datesEqual, isFunction, setMidnight, toISOString, toLocalDate,
4
+ toViewWithLocalDates
5
+ } from '#lib';
6
+
7
+ export function loadEvents(mainState) {
8
+ let fetching = 0;
9
+ return () => {
10
+ // Dependencies
11
+ let {activeRange, fetchedRange, options: {events, eventSources, lazyFetching, loading}} = mainState;
12
+
13
+ untrack(() => {
14
+ if (!eventSources.length) {
15
+ mainState.events = events;
16
+ }
17
+ // Do not fetch if new range is within the previous one
18
+ if (
19
+ !fetchedRange.start ||
20
+ fetchedRange.start > activeRange.start ||
21
+ fetchedRange.end < activeRange.end ||
22
+ !lazyFetching
23
+ ) {
24
+ // Call loading hook
25
+ if (isFunction(loading) && !fetching) {
26
+ loading(true);
27
+ }
28
+ let stopLoading = () => {
29
+ if (--fetching === 0 && isFunction(loading)) {
30
+ loading(false);
31
+ }
32
+ };
33
+ let events = [];
34
+ // Prepare handlers
35
+ let failure = e => stopLoading();
36
+ let success = data => {
37
+ events = events.concat(createEvents(data));
38
+ mainState.events = events;
39
+ stopLoading();
40
+ };
41
+ // Prepare other stuff
42
+ let startStr = toISOString(activeRange.start)
43
+ let endStr = toISOString(activeRange.end);
44
+ // Loop over event sources
45
+ for (let source of eventSources) {
46
+ if (isFunction(source.events)) {
47
+ // Events as a function
48
+ let result = source.events({
49
+ start: toLocalDate(activeRange.start),
50
+ end: toLocalDate(activeRange.end),
51
+ startStr,
52
+ endStr
53
+ }, success, failure);
54
+ if (result !== undefined) {
55
+ Promise.resolve(result).then(success, failure);
56
+ }
57
+ } else {
58
+ // Events as a JSON feed
59
+ // Prepare params
60
+ let params = isFunction(source.extraParams) ? source.extraParams() : assign({}, source.extraParams);
61
+ params.start = startStr;
62
+ params.end = endStr;
63
+ params = new URLSearchParams(params);
64
+ // Prepare fetch
65
+ let url = source.url, headers = {}, body;
66
+ if (['GET', 'HEAD'].includes(source.method)) {
67
+ url += (url.includes('?') ? '&' : '?') + params;
68
+ } else {
69
+ headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
70
+ body = String(params); // Safari 10.1 doesn't convert to string automatically
71
+ }
72
+ // Do the fetch
73
+ fetch(url, {
74
+ method: source.method, headers, body, signal: getAbortSignal(), credentials: 'same-origin'
75
+ })
76
+ .then(response => response.json())
77
+ .then(success)
78
+ .catch(failure);
79
+ }
80
+ ++fetching;
81
+ }
82
+ // Save current range for future requests
83
+ mainState.fetchedRange = activeRange;
84
+ }
85
+ });
86
+ };
87
+ }
88
+
89
+ export function setNowAndToday(mainState) {
90
+ return () => {
91
+ // Now and today
92
+ let interval = setInterval(() => {
93
+ let now = createDate();
94
+ let today = setMidnight(cloneDate(now));
95
+ mainState.now = now;
96
+ if (!datesEqual(mainState.today, today)) {
97
+ mainState.today = today;
98
+ }
99
+ }, 1000);
100
+
101
+ return () => clearInterval(interval);
102
+ }
103
+ }
104
+
105
+ export function runDatesSet(mainState) {
106
+ return () => {
107
+ // Dependencies
108
+ let {activeRange, options: {datesSet}} = mainState;
109
+
110
+ untrack(() => {
111
+ if (isFunction(datesSet)) {
112
+ datesSet({
113
+ start: toLocalDate(activeRange.start),
114
+ end: toLocalDate(activeRange.end),
115
+ startStr: toISOString(activeRange.start),
116
+ endStr: toISOString(activeRange.end),
117
+ view: toViewWithLocalDates(mainState.view)
118
+ });
119
+ }
120
+ });
121
+ }
122
+ }
123
+
124
+ export function runEventAllUpdated(mainState) {
125
+ let timer;
126
+ return () => {
127
+ // Dependencies
128
+ let {filteredEvents, options: {eventAllUpdated}} = mainState;
129
+
130
+ untrack(() => {
131
+ if (isFunction(eventAllUpdated)) {
132
+ if (!timer) {
133
+ timer = setTimeout(() => {
134
+ timer = null;
135
+ eventAllUpdated({view: toViewWithLocalDates(mainState.view)});
136
+ });
137
+ }
138
+ }
139
+ });
140
+ }
141
+ }
142
+
143
+ export function runViewDidMount(mainState) {
144
+ return () => {
145
+ // Dependencies
146
+ let {viewComponent, options: {viewDidMount}} = mainState;
147
+
148
+ untrack(() => {
149
+ if (isFunction(viewDidMount)) {
150
+ tick().then(() => viewDidMount({
151
+ view: toViewWithLocalDates(mainState.view)
152
+ }));
153
+ }
154
+ });
155
+ };
156
+ }