@event-calendar/core 5.0.6 → 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.
- package/README.md +15 -4
- package/dist/index.css +2 -2
- package/dist/index.js +2200 -2122
- package/package.json +2 -2
- package/src/Buttons.svelte +36 -37
- package/src/Calendar.svelte +34 -37
- package/src/Toolbar.svelte +4 -4
- package/src/lib/components/BaseDay.svelte +13 -10
- package/src/lib/components/BaseEvent.svelte +17 -17
- package/src/lib/components/ColHead.svelte +6 -6
- package/src/lib/components/DayHeader.svelte +3 -3
- package/src/lib/components/InteractableEvent.svelte +7 -8
- package/src/lib/derived.js +80 -0
- package/src/lib/index.js +1 -2
- package/src/lib/slots.js +16 -16
- package/src/lib/utils.js +4 -9
- package/src/lib/view.js +0 -8
- package/src/plugins/day-grid/Day.svelte +25 -23
- package/src/plugins/day-grid/Event.svelte +15 -13
- package/src/plugins/day-grid/Popup.svelte +12 -12
- package/src/plugins/day-grid/View.svelte +24 -33
- package/src/plugins/day-grid/derived.js +102 -0
- package/src/plugins/day-grid/index.js +47 -36
- package/src/plugins/day-grid/state.svelte.js +19 -0
- package/src/plugins/interaction/Action.svelte +108 -76
- package/src/plugins/interaction/Auxiliary.svelte +9 -38
- package/src/plugins/interaction/Pointer.svelte +12 -17
- package/src/plugins/interaction/Resizer.svelte +9 -7
- package/src/plugins/interaction/effects.js +37 -0
- package/src/plugins/interaction/index.js +44 -38
- package/src/plugins/interaction/lib/utils.js +1 -1
- package/src/plugins/interaction/state.svelte.js +12 -0
- package/src/plugins/list/Day.svelte +8 -7
- package/src/plugins/list/Event.svelte +3 -3
- package/src/plugins/list/View.svelte +17 -16
- package/src/plugins/list/index.js +51 -43
- package/src/plugins/list/state.svelte.js +8 -0
- package/src/plugins/resource-time-grid/Label.svelte +8 -8
- package/src/plugins/resource-time-grid/View.svelte +38 -17
- package/src/plugins/resource-time-grid/derived.js +67 -0
- package/src/plugins/resource-time-grid/index.js +34 -28
- package/src/plugins/resource-time-grid/state.svelte.js +21 -0
- package/src/plugins/resource-timeline/Day.svelte +9 -4
- package/src/plugins/resource-timeline/Event.svelte +7 -6
- package/src/plugins/resource-timeline/Expander.svelte +7 -6
- package/src/plugins/resource-timeline/NowIndicator.svelte +10 -11
- package/src/plugins/resource-timeline/View.svelte +45 -60
- package/src/plugins/resource-timeline/derived.js +167 -0
- package/src/plugins/resource-timeline/index.js +17 -21
- package/src/plugins/resource-timeline/lib.js +4 -65
- package/src/plugins/resource-timeline/state.svelte.js +18 -0
- package/src/plugins/time-grid/Day.svelte +7 -2
- package/src/plugins/time-grid/Event.svelte +6 -6
- package/src/plugins/time-grid/NowIndicator.svelte +10 -9
- package/src/plugins/time-grid/View.svelte +46 -55
- package/src/plugins/time-grid/derived.js +162 -0
- package/src/plugins/time-grid/index.js +31 -25
- package/src/plugins/time-grid/lib.js +18 -74
- package/src/plugins/time-grid/options.js +21 -16
- package/src/plugins/time-grid/state.svelte.js +44 -0
- package/src/storage/derived.js +144 -0
- package/src/storage/effects.js +156 -0
- package/src/storage/options.svelte.js +275 -0
- package/src/storage/state.svelte.js +69 -0
- package/src/styles/events.css +1 -1
- package/src/Auxiliary.svelte +0 -47
- package/src/lib/debounce.js +0 -20
- package/src/lib/stores.js +0 -63
- package/src/plugins/day-grid/lib.js +0 -61
- package/src/plugins/day-grid/stores.js +0 -5
- package/src/plugins/resource-time-grid/lib.js +0 -31
- package/src/plugins/resource-time-grid/stores.js +0 -34
- package/src/plugins/resource-timeline/Header.svelte +0 -44
- package/src/plugins/resource-timeline/Label.svelte +0 -38
- package/src/plugins/resource-timeline/stores.js +0 -48
- package/src/plugins/time-grid/stores.js +0 -49
- package/src/storage/options.js +0 -136
- package/src/storage/state.js +0 -168
- 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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
+
}
|