@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 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import {getContext, onMount} from 'svelte';
|
|
3
|
-
import {contentFrom, toLocalDate, isFunction} from '#lib';
|
|
4
|
-
|
|
5
|
-
let {resource, date = undefined} = $props();
|
|
6
|
-
|
|
7
|
-
let {resourceLabelContent, resourceLabelDidMount} = getContext('state');
|
|
8
|
-
|
|
9
|
-
let el = $state();
|
|
10
|
-
// Content
|
|
11
|
-
let content = $derived.by(() => {
|
|
12
|
-
if ($resourceLabelContent) {
|
|
13
|
-
return isFunction($resourceLabelContent)
|
|
14
|
-
? $resourceLabelContent({
|
|
15
|
-
resource,
|
|
16
|
-
date: date ? toLocalDate(date) : undefined,
|
|
17
|
-
})
|
|
18
|
-
: $resourceLabelContent;
|
|
19
|
-
} else {
|
|
20
|
-
return resource.title;
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
onMount(() => {
|
|
25
|
-
if (isFunction($resourceLabelDidMount)) {
|
|
26
|
-
$resourceLabelDidMount({
|
|
27
|
-
resource,
|
|
28
|
-
date: date ? toLocalDate(date) : undefined,
|
|
29
|
-
el
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<span
|
|
36
|
-
bind:this={el}
|
|
37
|
-
{@attach contentFrom(content)}
|
|
38
|
-
></span>
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {derived} from 'svelte/store';
|
|
2
|
-
import {createSlotTimeLimits, createSlots, getPayload, toSeconds} from '#lib';
|
|
3
|
-
|
|
4
|
-
// slotTimeLimits per day
|
|
5
|
-
export function dayTimeLimits(state) {
|
|
6
|
-
return derived(
|
|
7
|
-
[state.slotMinTime, state.slotMaxTime, state.flexibleSlotTimeLimits, state._viewDates, state._filteredEvents],
|
|
8
|
-
([$slotMinTime, $slotMaxTime, $flexibleSlotTimeLimits, $_viewDates, $_filteredEvents]) => {
|
|
9
|
-
let dayTimeLimits = {};
|
|
10
|
-
for (let date of $_viewDates) {
|
|
11
|
-
dayTimeLimits[date.getTime()] = createSlotTimeLimits(
|
|
12
|
-
$slotMinTime,
|
|
13
|
-
$slotMaxTime,
|
|
14
|
-
$flexibleSlotTimeLimits,
|
|
15
|
-
[date],
|
|
16
|
-
$_filteredEvents
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return dayTimeLimits;
|
|
21
|
-
}
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function daySlots(state) {
|
|
26
|
-
return derived(
|
|
27
|
-
[state._viewDates, state.slotDuration, state._slotLabelPeriodicity, state._dayTimeLimits, state._intlSlotLabel],
|
|
28
|
-
([$_viewDates, $slotDuration, $_slotLabelPeriodicity, $_dayTimeLimits, $_intlSlotLabel]) => {
|
|
29
|
-
let dayTimes = {};
|
|
30
|
-
for (let date of $_viewDates) {
|
|
31
|
-
let key = date.getTime();
|
|
32
|
-
dayTimes[key] = key in $_dayTimeLimits
|
|
33
|
-
? createSlots(date, $slotDuration, $_slotLabelPeriodicity, $_dayTimeLimits[key], $_intlSlotLabel)
|
|
34
|
-
: [];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return dayTimes;
|
|
38
|
-
}
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function nestedResources(state) {
|
|
43
|
-
return derived(state.resources, $resources => $resources.some(resource => getPayload(resource).children.length));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function monthView(state) {
|
|
47
|
-
return derived(state.slotDuration, $slotDuration => !toSeconds($slotDuration));
|
|
48
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import {derived, writable} from 'svelte/store';
|
|
2
|
-
import {ceil, createDate, createSlotTimeLimits, createSlots, intl, setMidnight, toSeconds} from '#lib';
|
|
3
|
-
|
|
4
|
-
function slotTimeLimits(state) {
|
|
5
|
-
return derived(
|
|
6
|
-
[state.slotMinTime, state.slotMaxTime, state.flexibleSlotTimeLimits, state._viewDates, state._filteredEvents],
|
|
7
|
-
args => createSlotTimeLimits(...args)
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function slotLabelPeriodicity(state) {
|
|
12
|
-
return derived(
|
|
13
|
-
[state.slotDuration, state.slotLabelInterval],
|
|
14
|
-
([$slotDuration, $slotLabelInterval]) => {
|
|
15
|
-
if ($slotLabelInterval === undefined) {
|
|
16
|
-
return toSeconds($slotDuration) < 3600 ? 2 : 1;
|
|
17
|
-
}
|
|
18
|
-
return ceil(toSeconds($slotLabelInterval) / toSeconds($slotDuration)) || 1;
|
|
19
|
-
}
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function slots(state) {
|
|
24
|
-
return derived(
|
|
25
|
-
[state.slotDuration, state._slotLabelPeriodicity, state._slotTimeLimits, state._intlSlotLabel],
|
|
26
|
-
args => createSlots(setMidnight(createDate()), ...args)
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* TimeGrid + ResourceTimeGrid + ResourceTimeline
|
|
32
|
-
*/
|
|
33
|
-
export function createTRRStores(state) {
|
|
34
|
-
if (!('_sidebarWidth' in state)) {
|
|
35
|
-
state._intlSlotLabel = intl(state.locale, state.slotLabelFormat);
|
|
36
|
-
state._slotLabelPeriodicity = slotLabelPeriodicity(state);
|
|
37
|
-
state._sidebarWidth = writable(0);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* TimeGrid + ResourceTimeGrid
|
|
43
|
-
*/
|
|
44
|
-
export function createTRStores(state) {
|
|
45
|
-
if (!('_slots' in state)) {
|
|
46
|
-
state._slotTimeLimits = slotTimeLimits(state); // flexible limits
|
|
47
|
-
state._slots = slots(state);
|
|
48
|
-
}
|
|
49
|
-
}
|
package/src/storage/options.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createDate, createDuration, createEvents, createEventSources, createResources, createDateRange, keys, setMidnight
|
|
3
|
-
} from '#lib';
|
|
4
|
-
|
|
5
|
-
// Options where initial value is passed to the function
|
|
6
|
-
export const specialOptions = ['buttonText', 'customButtons', 'theme'];
|
|
7
|
-
|
|
8
|
-
export function createOptions(plugins) {
|
|
9
|
-
let options = {
|
|
10
|
-
buttonText: {
|
|
11
|
-
today: 'today',
|
|
12
|
-
},
|
|
13
|
-
customButtons: {},
|
|
14
|
-
date: new Date(),
|
|
15
|
-
datesSet: undefined,
|
|
16
|
-
dayHeaderFormat: {
|
|
17
|
-
weekday: 'short',
|
|
18
|
-
month: 'numeric',
|
|
19
|
-
day: 'numeric'
|
|
20
|
-
},
|
|
21
|
-
dayHeaderAriaLabelFormat: {
|
|
22
|
-
dateStyle: 'full'
|
|
23
|
-
},
|
|
24
|
-
displayEventEnd: true,
|
|
25
|
-
duration: {weeks: 1},
|
|
26
|
-
events: [],
|
|
27
|
-
eventAllUpdated: undefined,
|
|
28
|
-
eventBackgroundColor: undefined,
|
|
29
|
-
eventClassNames: undefined,
|
|
30
|
-
eventClick: undefined,
|
|
31
|
-
eventColor: undefined,
|
|
32
|
-
eventContent: undefined,
|
|
33
|
-
eventDidMount: undefined,
|
|
34
|
-
eventFilter: undefined, // ec option
|
|
35
|
-
eventMouseEnter: undefined,
|
|
36
|
-
eventMouseLeave: undefined,
|
|
37
|
-
eventOrder: undefined,
|
|
38
|
-
eventSources: [],
|
|
39
|
-
eventTextColor: undefined,
|
|
40
|
-
eventTimeFormat: {
|
|
41
|
-
hour: 'numeric',
|
|
42
|
-
minute: '2-digit'
|
|
43
|
-
},
|
|
44
|
-
filterEventsWithResources: false,
|
|
45
|
-
firstDay: 0,
|
|
46
|
-
headerToolbar: {
|
|
47
|
-
start: 'title',
|
|
48
|
-
center: '',
|
|
49
|
-
end: 'today prev,next'
|
|
50
|
-
},
|
|
51
|
-
height: undefined,
|
|
52
|
-
hiddenDays: [],
|
|
53
|
-
highlightedDates: [], // ec option
|
|
54
|
-
lazyFetching: true,
|
|
55
|
-
loading: undefined,
|
|
56
|
-
locale: undefined,
|
|
57
|
-
resources: [],
|
|
58
|
-
selectable: false,
|
|
59
|
-
theme: {
|
|
60
|
-
allDay: 'ec-all-day',
|
|
61
|
-
active: 'ec-active',
|
|
62
|
-
bgEvent: 'ec-bg-event',
|
|
63
|
-
bgEvents: 'ec-bg-events',
|
|
64
|
-
body: 'ec-body',
|
|
65
|
-
button: 'ec-button',
|
|
66
|
-
buttonGroup: 'ec-button-group',
|
|
67
|
-
calendar: 'ec',
|
|
68
|
-
colHead: 'ec-col-head',
|
|
69
|
-
day: 'ec-day',
|
|
70
|
-
dayHead: 'ec-day-head',
|
|
71
|
-
disabled: 'ec-disabled',
|
|
72
|
-
event: 'ec-event',
|
|
73
|
-
eventBody: 'ec-event-body',
|
|
74
|
-
eventTime: 'ec-event-time',
|
|
75
|
-
eventTitle: 'ec-event-title',
|
|
76
|
-
events: 'ec-events',
|
|
77
|
-
grid: 'ec-grid',
|
|
78
|
-
header: 'ec-header',
|
|
79
|
-
hidden: 'ec-hidden',
|
|
80
|
-
highlight: 'ec-highlight',
|
|
81
|
-
icon: 'ec-icon',
|
|
82
|
-
main: 'ec-main',
|
|
83
|
-
noBeb: 'ec-no-beb', // no block end border
|
|
84
|
-
noIeb: 'ec-no-ieb', // no inline end border
|
|
85
|
-
today: 'ec-today',
|
|
86
|
-
title: 'ec-title',
|
|
87
|
-
toolbar: 'ec-toolbar',
|
|
88
|
-
view: '',
|
|
89
|
-
weekdays: ['ec-sun', 'ec-mon', 'ec-tue', 'ec-wed', 'ec-thu', 'ec-fri', 'ec-sat'],
|
|
90
|
-
},
|
|
91
|
-
titleFormat: {
|
|
92
|
-
year: 'numeric',
|
|
93
|
-
month: 'short',
|
|
94
|
-
day: 'numeric'
|
|
95
|
-
},
|
|
96
|
-
validRange: undefined,
|
|
97
|
-
view: undefined,
|
|
98
|
-
viewDidMount: undefined,
|
|
99
|
-
views: {}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
for (let plugin of plugins) {
|
|
103
|
-
plugin.createOptions?.(options);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return options;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function createParsers(plugins) {
|
|
110
|
-
let parsers = {
|
|
111
|
-
date: date => setMidnight(createDate(date)),
|
|
112
|
-
duration: createDuration,
|
|
113
|
-
events: createEvents,
|
|
114
|
-
eventSources: createEventSources,
|
|
115
|
-
hiddenDays: days => [...new Set(days)],
|
|
116
|
-
highlightedDates: dates => dates.map(date => setMidnight(createDate(date))),
|
|
117
|
-
resources: createResources,
|
|
118
|
-
validRange: createDateRange
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
for (let plugin of plugins) {
|
|
122
|
-
plugin.createParsers?.(parsers);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return parsers;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function diff(options, prevOptions) {
|
|
129
|
-
let diff = [];
|
|
130
|
-
for (let key of keys(options)) {
|
|
131
|
-
if (options[key] !== prevOptions[key]) {
|
|
132
|
-
diff.push([key, options[key]]);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return diff;
|
|
136
|
-
}
|
package/src/storage/state.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import {get, writable} from 'svelte/store';
|
|
2
|
-
import {tick} from 'svelte';
|
|
3
|
-
import {createOptions, createParsers, specialOptions} from './options.js';
|
|
4
|
-
import {activeRange, currentRange, dayGrid, events, now, today, view as view2, viewDates, viewTitle, filteredEvents} from './stores.js';
|
|
5
|
-
import {identity, intl, intlRange, isFunction, keys, toViewWithLocalDates} from '#lib';
|
|
6
|
-
|
|
7
|
-
export default class {
|
|
8
|
-
constructor(plugins, input) {
|
|
9
|
-
plugins = plugins || [];
|
|
10
|
-
|
|
11
|
-
// Create options
|
|
12
|
-
let options = createOptions(plugins);
|
|
13
|
-
let parsers = createParsers(plugins);
|
|
14
|
-
|
|
15
|
-
// Parse options
|
|
16
|
-
options = parseOpts(options, parsers);
|
|
17
|
-
input = parseOpts(input, parsers);
|
|
18
|
-
|
|
19
|
-
// Create stores for options
|
|
20
|
-
for (let [option, value] of Object.entries(options)) {
|
|
21
|
-
this[option] = writable(value);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Private stores
|
|
25
|
-
this._queue = writable(new Map()); // debounce queue (beforeUpdate)
|
|
26
|
-
this._tasks = new Map(); // timeout IDs for tasks
|
|
27
|
-
this._auxiliary = writable([]); // auxiliary components
|
|
28
|
-
this._dayGrid = dayGrid(this);
|
|
29
|
-
this._currentRange = currentRange(this);
|
|
30
|
-
this._activeRangeExt = writable(identity);
|
|
31
|
-
this._activeRange = activeRange(this);
|
|
32
|
-
this._fetchedRange = writable({start: undefined, end: undefined});
|
|
33
|
-
this._events = events(this);
|
|
34
|
-
this._mainEl = writable(undefined);
|
|
35
|
-
this._now = now();
|
|
36
|
-
this._today = today(this);
|
|
37
|
-
this._intlEventTime = intlRange(this.locale, this.eventTimeFormat);
|
|
38
|
-
this._intlDayHeader = intl(this.locale, this.dayHeaderFormat);
|
|
39
|
-
this._intlDayHeaderAL = intl(this.locale, this.dayHeaderAriaLabelFormat);
|
|
40
|
-
this._intlTitle = intlRange(this.locale, this.titleFormat);
|
|
41
|
-
this._viewTitle = viewTitle(this);
|
|
42
|
-
this._viewDates = viewDates(this);
|
|
43
|
-
this._view = view2(this);
|
|
44
|
-
this._viewComponent = writable(undefined);
|
|
45
|
-
this._filteredEvents = filteredEvents(this);
|
|
46
|
-
// Interaction
|
|
47
|
-
this._interaction = writable({});
|
|
48
|
-
this._iEvents = writable([null, null]); // interaction events: [drag/resize, pointer]
|
|
49
|
-
this._iClasses = writable(identity); // interaction event css classes
|
|
50
|
-
this._iClass = writable(undefined); // interaction css class for entire calendar
|
|
51
|
-
|
|
52
|
-
// Set & Get
|
|
53
|
-
this._set = (key, value) => {
|
|
54
|
-
if (validKey(key, this)) {
|
|
55
|
-
if (parsers[key]) {
|
|
56
|
-
value = parsers[key](value);
|
|
57
|
-
}
|
|
58
|
-
this[key].set(value);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
this._get = key => validKey(key, this) ? get(this[key]) : undefined;
|
|
62
|
-
|
|
63
|
-
// Let plugins create their private stores
|
|
64
|
-
for (let plugin of plugins) {
|
|
65
|
-
plugin.createStores?.(this);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (input.view) {
|
|
69
|
-
// Set initial view based on input
|
|
70
|
-
this.view.set(input.view);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Set options for each view
|
|
74
|
-
let views = new Set([...keys(options.views), ...keys(input.views ?? {})]);
|
|
75
|
-
for (let view of views) {
|
|
76
|
-
let defOpts = mergeOpts(options, options.views[view] ?? {});
|
|
77
|
-
let opts = mergeOpts(defOpts, input, input.views?.[view] ?? {});
|
|
78
|
-
let component = opts.component;
|
|
79
|
-
// Make sure we deal with valid opts from now on
|
|
80
|
-
filterOpts(opts, this);
|
|
81
|
-
// Process options
|
|
82
|
-
for (let key of keys(opts)) {
|
|
83
|
-
let {set, _set = set, ...rest} = this[key];
|
|
84
|
-
|
|
85
|
-
this[key] = {
|
|
86
|
-
// Set value in all views
|
|
87
|
-
set: specialOptions.includes(key)
|
|
88
|
-
? value => {
|
|
89
|
-
if (isFunction(value)) {
|
|
90
|
-
let result = value(defOpts[key]);
|
|
91
|
-
opts[key] = result;
|
|
92
|
-
set(set === _set ? result : value);
|
|
93
|
-
} else {
|
|
94
|
-
opts[key] = value;
|
|
95
|
-
set(value);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
: value => {
|
|
99
|
-
opts[key] = value;
|
|
100
|
-
set(value);
|
|
101
|
-
},
|
|
102
|
-
_set,
|
|
103
|
-
...rest
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
// When view changes...
|
|
107
|
-
this.view.subscribe(newView => {
|
|
108
|
-
if (newView === view) {
|
|
109
|
-
// switch view component
|
|
110
|
-
this._viewComponent.set(component);
|
|
111
|
-
if (isFunction(opts.viewDidMount)) {
|
|
112
|
-
tick().then(() => opts.viewDidMount({
|
|
113
|
-
view: toViewWithLocalDates(get(this._view))
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
// update store values
|
|
117
|
-
for (let key of keys(opts)) {
|
|
118
|
-
this[key]._set(opts[key]);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function parseOpts(opts, parsers) {
|
|
127
|
-
let result = {...opts};
|
|
128
|
-
for (let key of keys(parsers)) {
|
|
129
|
-
if (key in result) {
|
|
130
|
-
result[key] = parsers[key](result[key]);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (opts.views) {
|
|
134
|
-
result.views = {};
|
|
135
|
-
for (let view of keys(opts.views)) {
|
|
136
|
-
result.views[view] = parseOpts(opts.views[view], parsers);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return result;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function mergeOpts(...args) {
|
|
143
|
-
let result = {};
|
|
144
|
-
for (let opts of args) {
|
|
145
|
-
let override = {};
|
|
146
|
-
for (let key of specialOptions) {
|
|
147
|
-
if (isFunction(opts[key])) {
|
|
148
|
-
override[key] = opts[key](result[key]);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
result = {
|
|
152
|
-
...result,
|
|
153
|
-
...opts,
|
|
154
|
-
...override
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
return result;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function filterOpts(opts, state) {
|
|
161
|
-
keys(opts)
|
|
162
|
-
.filter(key => !validKey(key, state) || key === 'view')
|
|
163
|
-
.forEach(key => delete opts[key]);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function validKey(key, state) {
|
|
167
|
-
return state.hasOwnProperty(key) && key[0] !== '_';
|
|
168
|
-
}
|
package/src/storage/stores.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import {derived, get, readable, writable} from 'svelte/store';
|
|
2
|
-
import {
|
|
3
|
-
addDay, addDuration, assign, cloneDate, createDate, createEvents, createView, datesEqual, DAY_IN_SECONDS, debounce,
|
|
4
|
-
isFunction, nextClosestDay, prevClosestDay, setMidnight, subtractDay, toEventWithLocalDates, toISOString,
|
|
5
|
-
toLocalDate
|
|
6
|
-
} from '#lib';
|
|
7
|
-
|
|
8
|
-
export function dayGrid(state) {
|
|
9
|
-
return derived(state.view, $view => $view?.startsWith('dayGrid'));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function activeRange(state) {
|
|
13
|
-
return derived(
|
|
14
|
-
[state._currentRange, state._activeRangeExt],
|
|
15
|
-
([$_currentRange, $_activeRangeExt]) => {
|
|
16
|
-
return $_activeRangeExt({start: cloneDate($_currentRange.start), end: cloneDate($_currentRange.end)});
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function currentRange(state) {
|
|
22
|
-
return derived(
|
|
23
|
-
[state.date, state.duration, state.firstDay],
|
|
24
|
-
([$date, $duration, $firstDay]) => {
|
|
25
|
-
let start = cloneDate($date), end;
|
|
26
|
-
if ($duration.months) {
|
|
27
|
-
start.setUTCDate(1);
|
|
28
|
-
} else if ($duration.inWeeks) {
|
|
29
|
-
// First day of week
|
|
30
|
-
prevClosestDay(start, $firstDay);
|
|
31
|
-
}
|
|
32
|
-
end = addDuration(cloneDate(start), $duration);
|
|
33
|
-
|
|
34
|
-
return {start, end};
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function viewDates(state) {
|
|
40
|
-
return derived([state._activeRange, state.hiddenDays], ([$_activeRange, $hiddenDays]) => {
|
|
41
|
-
let dates = [];
|
|
42
|
-
let date = setMidnight(cloneDate($_activeRange.start));
|
|
43
|
-
let end = setMidnight(cloneDate($_activeRange.end));
|
|
44
|
-
while (date < end) {
|
|
45
|
-
if (!$hiddenDays.includes(date.getUTCDay())) {
|
|
46
|
-
dates.push(cloneDate(date));
|
|
47
|
-
}
|
|
48
|
-
addDay(date);
|
|
49
|
-
}
|
|
50
|
-
if (!dates.length && $hiddenDays.length && $hiddenDays.length < 7) {
|
|
51
|
-
// Try to move the date
|
|
52
|
-
state.date.update(date => {
|
|
53
|
-
while ($hiddenDays.includes(date.getUTCDay())) {
|
|
54
|
-
addDay(date);
|
|
55
|
-
}
|
|
56
|
-
return date;
|
|
57
|
-
});
|
|
58
|
-
dates = get(state._viewDates);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return dates;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function viewTitle(state) {
|
|
66
|
-
return derived(
|
|
67
|
-
[state.date, state._activeRange, state._intlTitle, state._dayGrid],
|
|
68
|
-
([$date, $_activeRange, $_intlTitle, $_dayGrid]) => {
|
|
69
|
-
return $_dayGrid
|
|
70
|
-
? $_intlTitle.formatRange($date, $date)
|
|
71
|
-
: $_intlTitle.formatRange($_activeRange.start, subtractDay(cloneDate($_activeRange.end)));
|
|
72
|
-
}
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function view(state) {
|
|
77
|
-
return derived([state.view, state._viewTitle, state._currentRange, state._activeRange], args => createView(...args));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function events(state) {
|
|
81
|
-
let _events = writable([]);
|
|
82
|
-
let abortController;
|
|
83
|
-
let fetching = 0;
|
|
84
|
-
let debounceHandle = {};
|
|
85
|
-
derived(
|
|
86
|
-
[state.events, state.eventSources, state._activeRange, state._fetchedRange, state.lazyFetching, state.loading],
|
|
87
|
-
(values, set) => debounce(() => {
|
|
88
|
-
let [$events, $eventSources, $_activeRange, $_fetchedRange, $lazyFetching, $loading] = values;
|
|
89
|
-
if (!$eventSources.length) {
|
|
90
|
-
set($events);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
// Do not fetch if new range is within the previous one
|
|
94
|
-
if (!$_fetchedRange.start || $_fetchedRange.start > $_activeRange.start || $_fetchedRange.end < $_activeRange.end || !$lazyFetching) {
|
|
95
|
-
if (abortController) {
|
|
96
|
-
// Abort previous request
|
|
97
|
-
abortController.abort();
|
|
98
|
-
}
|
|
99
|
-
// Create new abort controller
|
|
100
|
-
abortController = new AbortController();
|
|
101
|
-
// Call loading hook
|
|
102
|
-
if (isFunction($loading) && !fetching) {
|
|
103
|
-
$loading(true);
|
|
104
|
-
}
|
|
105
|
-
let stopLoading = () => {
|
|
106
|
-
if (--fetching === 0 && isFunction($loading)) {
|
|
107
|
-
$loading(false);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
let events = [];
|
|
111
|
-
// Prepare handlers
|
|
112
|
-
let failure = e => stopLoading();
|
|
113
|
-
let success = data => {
|
|
114
|
-
events = events.concat(createEvents(data));
|
|
115
|
-
set(events);
|
|
116
|
-
stopLoading();
|
|
117
|
-
};
|
|
118
|
-
// Prepare other stuff
|
|
119
|
-
let startStr = toISOString($_activeRange.start)
|
|
120
|
-
let endStr = toISOString($_activeRange.end);
|
|
121
|
-
// Loop over event sources
|
|
122
|
-
for (let source of $eventSources) {
|
|
123
|
-
if (isFunction(source.events)) {
|
|
124
|
-
// Events as a function
|
|
125
|
-
let result = source.events({
|
|
126
|
-
start: toLocalDate($_activeRange.start),
|
|
127
|
-
end: toLocalDate($_activeRange.end),
|
|
128
|
-
startStr,
|
|
129
|
-
endStr
|
|
130
|
-
}, success, failure);
|
|
131
|
-
if (result !== undefined) {
|
|
132
|
-
Promise.resolve(result).then(success, failure);
|
|
133
|
-
}
|
|
134
|
-
} else {
|
|
135
|
-
// Events as a JSON feed
|
|
136
|
-
// Prepare params
|
|
137
|
-
let params = isFunction(source.extraParams) ? source.extraParams() : assign({}, source.extraParams);
|
|
138
|
-
params.start = startStr;
|
|
139
|
-
params.end = endStr;
|
|
140
|
-
params = new URLSearchParams(params);
|
|
141
|
-
// Prepare fetch
|
|
142
|
-
let url = source.url, headers = {}, body;
|
|
143
|
-
if (['GET', 'HEAD'].includes(source.method)) {
|
|
144
|
-
url += (url.includes('?') ? '&' : '?') + params;
|
|
145
|
-
} else {
|
|
146
|
-
headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
|
|
147
|
-
body = String(params); // Safari 10.1 doesn't convert to string automatically
|
|
148
|
-
}
|
|
149
|
-
// Do the fetch
|
|
150
|
-
fetch(url, {method: source.method, headers, body, signal: abortController.signal, credentials: 'same-origin'})
|
|
151
|
-
.then(response => response.json())
|
|
152
|
-
.then(success)
|
|
153
|
-
.catch(failure);
|
|
154
|
-
}
|
|
155
|
-
++fetching;
|
|
156
|
-
}
|
|
157
|
-
// Save current range for future requests
|
|
158
|
-
$_fetchedRange.start = $_activeRange.start;
|
|
159
|
-
$_fetchedRange.end = $_activeRange.end;
|
|
160
|
-
}
|
|
161
|
-
}, debounceHandle, state._queue),
|
|
162
|
-
[]
|
|
163
|
-
).subscribe(_events.set);
|
|
164
|
-
|
|
165
|
-
return _events;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function filteredEvents(state){
|
|
169
|
-
let view;
|
|
170
|
-
state._view.subscribe($_view => view = $_view);
|
|
171
|
-
let debounceHandle = {};
|
|
172
|
-
return derived(
|
|
173
|
-
[state._events, state.eventFilter, state.eventOrder, state.filterEventsWithResources, state.resources],
|
|
174
|
-
(values, set) => debounce(() => {
|
|
175
|
-
let [$_events, $eventFilter, $eventOrder, $filterEventsWithResources, $resources] = values;
|
|
176
|
-
|
|
177
|
-
let result = [...$_events];
|
|
178
|
-
|
|
179
|
-
// Filter events
|
|
180
|
-
if (isFunction($eventFilter)) {
|
|
181
|
-
let events = $_events.map(toEventWithLocalDates);
|
|
182
|
-
result = result
|
|
183
|
-
.filter((event, index) => $eventFilter({
|
|
184
|
-
event: toEventWithLocalDates(event),
|
|
185
|
-
index,
|
|
186
|
-
events,
|
|
187
|
-
view
|
|
188
|
-
}));
|
|
189
|
-
}
|
|
190
|
-
if ($filterEventsWithResources) {
|
|
191
|
-
result = result.filter(event => $resources.some(resource => event.resourceIds.includes(resource.id)));
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Sort events
|
|
195
|
-
if (isFunction($eventOrder)) {
|
|
196
|
-
result.sort((a, b) => $eventOrder(
|
|
197
|
-
toEventWithLocalDates(a),
|
|
198
|
-
toEventWithLocalDates(b)
|
|
199
|
-
));
|
|
200
|
-
} else {
|
|
201
|
-
// Sort by start date (all-day events always on top)
|
|
202
|
-
result.sort((a, b) => a.start - b.start || b.allDay - a.allDay);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
set(result);
|
|
206
|
-
|
|
207
|
-
}, debounceHandle, state._queue),
|
|
208
|
-
[]
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export function now() {
|
|
213
|
-
return readable(createDate(), set => {
|
|
214
|
-
let interval = setInterval(() => {
|
|
215
|
-
set(createDate());
|
|
216
|
-
}, 1000);
|
|
217
|
-
|
|
218
|
-
return () => clearInterval(interval);
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export function today(state) {
|
|
223
|
-
let $today = setMidnight(createDate());
|
|
224
|
-
let today = writable($today);
|
|
225
|
-
state._now.subscribe($_now => {
|
|
226
|
-
let newToday = setMidnight(cloneDate($_now));
|
|
227
|
-
if (!datesEqual($today, newToday)) {
|
|
228
|
-
$today = newToday;
|
|
229
|
-
today.set(newToday);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
return today;
|
|
234
|
-
}
|