@sprucelabs/spruce-calendar-components 28.1.49 → 28.2.26
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/build/.spruce/schemas/schemas.types.d.ts +781 -541
- package/build/__tests__/support/CalendarToolBeltStateMachineTestFactory.d.ts +3 -1
- package/build/__tests__/support/CalendarToolBeltStateMachineTestFactory.js +4 -0
- package/build/__tests__/support/SpyEventManager.d.ts +5 -5
- package/build/calendar/CalendarEventManager.d.ts +9 -1
- package/build/calendar/CalendarEventManager.js +45 -3
- package/build/calendar/CalendarPeopleManager.d.ts +1 -1
- package/build/calendar/CalendarPersister.d.ts +1 -1
- package/build/esm/.spruce/schemas/schemas.types.d.ts +781 -541
- package/build/esm/__tests__/support/CalendarToolBeltStateMachineTestFactory.d.ts +3 -1
- package/build/esm/__tests__/support/CalendarToolBeltStateMachineTestFactory.js +6 -0
- package/build/esm/__tests__/support/SpyEventManager.d.ts +5 -5
- package/build/esm/calendar/CalendarEventManager.d.ts +9 -1
- package/build/esm/calendar/CalendarEventManager.js +51 -4
- package/build/esm/calendar/CalendarPeopleManager.d.ts +1 -1
- package/build/esm/calendar/CalendarPersister.d.ts +1 -1
- package/build/esm/{skillViewControllers → root}/Root.svc.js +7 -4
- package/build/esm/stores/RemoteEventStore.d.ts +13 -2
- package/build/esm/stores/RemoteEventStore.js +33 -12
- package/build/esm/toolBelt/CalendarToolRegistrar.js +1 -1
- package/build/esm/tools/EventDateTimeTool.vc.js +2 -2
- package/build/esm/types/calendar.types.d.ts +3 -0
- package/build/{skillViewControllers → root}/Root.svc.js +6 -3
- package/build/stores/RemoteEventStore.d.ts +13 -2
- package/build/stores/RemoteEventStore.js +20 -3
- package/build/toolBelt/CalendarToolRegistrar.js +1 -1
- package/build/tools/EventDateTimeTool.vc.js +2 -2
- package/build/types/calendar.types.d.ts +3 -0
- package/package.json +5 -5
- /package/build/esm/{skillViewControllers → root}/Root.svc.d.ts +0 -0
- /package/build/{skillViewControllers → root}/Root.svc.d.ts +0 -0
|
@@ -4,7 +4,7 @@ import { ViewFixture } from '@sprucelabs/spruce-test-fixtures';
|
|
|
4
4
|
import CalendarViewController from '../../calendar/Calendar.vc';
|
|
5
5
|
import CalendarEventManager, { CalendarEventManagerOptions, EventManagerCalendarVc } from '../../calendar/CalendarEventManager';
|
|
6
6
|
import { PeopleManagerCalendarVc } from '../../calendar/CalendarPeopleManager';
|
|
7
|
-
import { GetScheduleOptions, RemoteEventStore } from '../../stores/RemoteEventStore';
|
|
7
|
+
import { GetScheduleOptions, RemoteEventStore, SendScheduleOptions, StreamHandler } from '../../stores/RemoteEventStore';
|
|
8
8
|
import { Calendar, CalendarToolBeltStateMachine, UpdateEvent } from '../../types/calendar.types';
|
|
9
9
|
import SpyEventManager from './SpyEventManager';
|
|
10
10
|
export default class CalendarToolBeltStateMachineTestFactory {
|
|
@@ -35,6 +35,8 @@ export declare class FakeRemoteEventStore implements RemoteEventStore {
|
|
|
35
35
|
getSchedules(_options: GetScheduleOptions): Promise<SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEvent[]>;
|
|
36
36
|
getEventTypes(): Promise<SpruceSchemas.Calendar.v2021_05_19.CalendarEventType[]>;
|
|
37
37
|
getCalendars(): Promise<SpruceSchemas.Calendar.v2021_05_19.Calendar[]>;
|
|
38
|
+
sendSchedules(options: SendScheduleOptions): Promise<void>;
|
|
39
|
+
setStreamHandler(_cb: StreamHandler): void;
|
|
38
40
|
}
|
|
39
41
|
declare module '@sprucelabs/heartwood-view-controllers/build/types/heartwood.types' {
|
|
40
42
|
interface ViewControllerMap {
|
|
@@ -122,5 +122,11 @@ export class FakeRemoteEventStore {
|
|
|
122
122
|
return FakeRemoteEventStore.calendars;
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
+
sendSchedules(options) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
console.log(options);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
setStreamHandler(_cb) { }
|
|
125
131
|
}
|
|
126
132
|
FakeRemoteEventStore.calendars = [];
|
|
@@ -8,7 +8,7 @@ export default class SpyEventManager extends CalendarEventManager {
|
|
|
8
8
|
getShouldIgnoreNextContextUpdate(): boolean;
|
|
9
9
|
constructor(options: SpyEventManagerOptions);
|
|
10
10
|
refreshShifts(): void;
|
|
11
|
-
generateShifts(): import("@sprucelabs/
|
|
11
|
+
generateShifts(): import("@sprucelabs/mercury-types").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarShift[];
|
|
12
12
|
getRemoteEventsStore(): SpyRemoteEventStore;
|
|
13
13
|
getStateMachine(): import("../../types/calendar.types").CalendarToolBeltStateMachine<CalendarToolBeltContext>;
|
|
14
14
|
getPreferences(): SpyRemotePreferencesStore;
|
|
@@ -28,14 +28,14 @@ export default class SpyEventManager extends CalendarEventManager {
|
|
|
28
28
|
updateEventInContext(updates: Partial<CalendarEvent>): Promise<{
|
|
29
29
|
isBusy: boolean;
|
|
30
30
|
id: string;
|
|
31
|
-
target: import("@sprucelabs/
|
|
31
|
+
target: import("@sprucelabs/mercury-types").SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventTarget;
|
|
32
32
|
calendarId: string;
|
|
33
33
|
eventTypeSlug?: string | null | undefined;
|
|
34
34
|
startDateTimeMs: number;
|
|
35
35
|
isResizeable?: boolean | null | undefined;
|
|
36
36
|
style?: "draft" | "tentative" | "upcoming" | "unavailable" | "blocked" | "active" | "past" | "warn" | "critical" | null | undefined;
|
|
37
37
|
groupId?: string | null | undefined;
|
|
38
|
-
timeBlocks: import("@sprucelabs/
|
|
38
|
+
timeBlocks: import("@sprucelabs/mercury-types").SpruceSchemas.CalendarUtils.v2021_05_19.EventTimeBlock[];
|
|
39
39
|
repeats?: "weekly" | "monthly" | "daily" | null | undefined;
|
|
40
40
|
daysOfWeek?: ("sun" | "mon" | "tue" | "wed" | "thur" | "fri" | "sat")[] | null | undefined;
|
|
41
41
|
daysOfMonth?: ("1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | "22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31")[] | null | undefined;
|
|
@@ -44,13 +44,13 @@ export default class SpyEventManager extends CalendarEventManager {
|
|
|
44
44
|
interval?: number | null | undefined;
|
|
45
45
|
nthOccurrences?: number[] | null | undefined;
|
|
46
46
|
activeUntilDate?: number | null | undefined;
|
|
47
|
-
exclusionDates?: import("@sprucelabs/
|
|
47
|
+
exclusionDates?: import("@sprucelabs/mercury-types").SpruceSchemas.CalendarUtils.v2021_05_19.EventExclusionDate[] | null | undefined;
|
|
48
48
|
nthInRepeating?: number | null | undefined;
|
|
49
49
|
totalInRepeating?: number | null | undefined;
|
|
50
50
|
meta?: Record<string, any> | null | undefined;
|
|
51
51
|
error?: Error | null | undefined;
|
|
52
52
|
isSelected?: boolean | null | undefined;
|
|
53
|
-
colors?: import("@sprucelabs/
|
|
53
|
+
colors?: import("@sprucelabs/mercury-types").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEventColorOverride | null | undefined;
|
|
54
54
|
controller?: import("@sprucelabs/heartwood-view-controllers").CalendarEventViewController | null | undefined;
|
|
55
55
|
}>;
|
|
56
56
|
}
|
|
@@ -6,6 +6,7 @@ import RemotePreferencesStore from '../stores/RemotePreferencesStore';
|
|
|
6
6
|
import { CalendarToolBeltContext, CalendarToolBeltStateMachine, UpdateCalendarToolBeltContextHandler, UpdateEvent, UpdateRepeatingStrategyWithCancel } from '../types/calendar.types';
|
|
7
7
|
import CalendarViewController from './Calendar.vc';
|
|
8
8
|
export default class CalendarEventManager {
|
|
9
|
+
static shouldBatchEvents: boolean;
|
|
9
10
|
private calendarVc;
|
|
10
11
|
protected allEvents: CalendarEvent[];
|
|
11
12
|
private inclusiveCalendarIds;
|
|
@@ -27,9 +28,12 @@ export default class CalendarEventManager {
|
|
|
27
28
|
private updateQueuePromise?;
|
|
28
29
|
private persister;
|
|
29
30
|
private hasPendingContextChanges;
|
|
31
|
+
private loadEventsStartTimeMs;
|
|
32
|
+
private activeChunk?;
|
|
30
33
|
constructor(options: CalendarEventManagerOptions);
|
|
31
34
|
protected get calendarIds(): string[];
|
|
32
35
|
protected get visibleCalendarIds(): string[];
|
|
36
|
+
private handleStreamEvents;
|
|
33
37
|
replaceEventsInRange(events: CalendarEvent[], startMs: number, endMs: number): void;
|
|
34
38
|
protected refreshShifts(): void;
|
|
35
39
|
private doShiftsMatchWhatIsInCalendar;
|
|
@@ -58,7 +62,10 @@ export default class CalendarEventManager {
|
|
|
58
62
|
private runUpdateQueue;
|
|
59
63
|
private _updateEvent;
|
|
60
64
|
private calculateDifferences;
|
|
61
|
-
|
|
65
|
+
private get shouldBatchEvents();
|
|
66
|
+
loadEvents(startDate: number, endDate: number, peopleIds: string[]): Promise<import("@sprucelabs/calendar-utils").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEvent[] | undefined>;
|
|
67
|
+
private mixinEventsAndLoadTheirVcs;
|
|
68
|
+
private logStep;
|
|
62
69
|
setCalendarVisibility(calendarId: string, shouldBeVisible: boolean): Promise<void>;
|
|
63
70
|
setupVcForEventType(vcId: string, typeSlug: string): Promise<void>;
|
|
64
71
|
private assertValidCalendarId;
|
|
@@ -108,6 +115,7 @@ export default class CalendarEventManager {
|
|
|
108
115
|
private clearRepeatingStrategyOptions;
|
|
109
116
|
getIsLoaded(): boolean;
|
|
110
117
|
hasEvent(id: string): boolean;
|
|
118
|
+
getLastChunkingId(): string | undefined;
|
|
111
119
|
optionallyAskForUpdateRepeatingStrategy(event: UpdateEvent, action?: RepeatingUpdateAction): Promise<{
|
|
112
120
|
pass: boolean;
|
|
113
121
|
dateToUpdate?: number;
|
|
@@ -25,7 +25,7 @@ import calendarShiftGenerator from '../utilities/calendarShiftGenerator.js';
|
|
|
25
25
|
import draftEventGenerator from '../utilities/draftGenerator.js';
|
|
26
26
|
import calculateCalendarEventDifferences from './calculateCalendarEventDifferences.js';
|
|
27
27
|
import CalendarPersister from './CalendarPersister.js';
|
|
28
|
-
|
|
28
|
+
class CalendarEventManager {
|
|
29
29
|
constructor(options) {
|
|
30
30
|
this.allEvents = [];
|
|
31
31
|
this.inclusiveCalendarIds = [];
|
|
@@ -55,6 +55,8 @@ export default class CalendarEventManager {
|
|
|
55
55
|
events,
|
|
56
56
|
onEventSwapped: this.handleEventsSwappedInPersister.bind(this),
|
|
57
57
|
});
|
|
58
|
+
this.loadEventsStartTimeMs = new Date().getTime();
|
|
59
|
+
this.events.setStreamHandler(this.handleStreamEvents.bind(this));
|
|
58
60
|
}
|
|
59
61
|
get calendarIds() {
|
|
60
62
|
return this.calendars.map((c) => c.id);
|
|
@@ -63,6 +65,17 @@ export default class CalendarEventManager {
|
|
|
63
65
|
var _a;
|
|
64
66
|
return (_a = this.prefs.getVisibleCalendarIds()) !== null && _a !== void 0 ? _a : this.calendars.map((c) => c.id);
|
|
65
67
|
}
|
|
68
|
+
handleStreamEvents(options) {
|
|
69
|
+
var _a;
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
const { events, chunkingId } = options;
|
|
72
|
+
const { id, startDate, endDate } = (_a = this.activeChunk) !== null && _a !== void 0 ? _a : {};
|
|
73
|
+
if (id !== chunkingId || !startDate || !endDate) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.replaceEventsInRange(events, startDate, endDate);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
66
79
|
replaceEventsInRange(events, startMs, endMs) {
|
|
67
80
|
this.calendarVc.replaceEventsInRange(events.filter((e) => this.isCalendarSelected(e.calendarId)), startMs, endMs);
|
|
68
81
|
this.allEvents = this.allEvents.filter((e) => events.findIndex((event) => event.id === e.id) === -1 &&
|
|
@@ -320,14 +333,37 @@ export default class CalendarEventManager {
|
|
|
320
333
|
const { isTheSame, isTheSameWithoutBusy } = calculateCalendarEventDifferences(match, updates);
|
|
321
334
|
return { isTheSame, isTheSameWithoutBusy, match };
|
|
322
335
|
}
|
|
336
|
+
get shouldBatchEvents() {
|
|
337
|
+
return CalendarEventManager.shouldBatchEvents;
|
|
338
|
+
}
|
|
323
339
|
loadEvents(startDate, endDate, peopleIds) {
|
|
324
340
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
|
|
341
|
+
this.loadEventsStartTimeMs = new Date().getTime();
|
|
342
|
+
this.logStep('starting to load events');
|
|
343
|
+
const scheduleOptions = {
|
|
326
344
|
calendarIds: this.calendarIds,
|
|
327
345
|
startDate,
|
|
328
346
|
endDate,
|
|
329
347
|
peopleIds,
|
|
330
|
-
}
|
|
348
|
+
};
|
|
349
|
+
if (this.shouldBatchEvents) {
|
|
350
|
+
this.activeChunk = {
|
|
351
|
+
id: new Date().getTime().toString(),
|
|
352
|
+
startDate,
|
|
353
|
+
endDate,
|
|
354
|
+
};
|
|
355
|
+
yield this.events.sendSchedules(Object.assign(Object.assign({}, scheduleOptions), { chunkingId: this.activeChunk.id }));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const events = yield this.events.getSchedules(scheduleOptions);
|
|
359
|
+
this.logStep('Loaded events');
|
|
360
|
+
yield this.mixinEventsAndLoadTheirVcs(events, startDate, endDate);
|
|
361
|
+
this.logStep('Finished replacing events');
|
|
362
|
+
return events;
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
mixinEventsAndLoadTheirVcs(events, startDate, endDate) {
|
|
366
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
331
367
|
yield this.calendarVc.renderOnce(() => __awaiter(this, void 0, void 0, function* () {
|
|
332
368
|
if (!this.eventTypes) {
|
|
333
369
|
this.eventTypes = yield this.events.getEventTypes();
|
|
@@ -339,11 +375,16 @@ export default class CalendarEventManager {
|
|
|
339
375
|
yield this.setupVcForEventType(type.viewControllerId, type.slug);
|
|
340
376
|
}
|
|
341
377
|
})));
|
|
378
|
+
this.logStep('Loaded view controllers');
|
|
342
379
|
this.replaceEventsInRange(events, startDate, endDate);
|
|
343
380
|
}));
|
|
344
|
-
return events;
|
|
345
381
|
});
|
|
346
382
|
}
|
|
383
|
+
logStep(_label) {
|
|
384
|
+
// let currentTimeMs = new Date().getTime()
|
|
385
|
+
// const diff = currentTimeMs - this.loadEventsStartTimeMs
|
|
386
|
+
// console.log(label, diff)
|
|
387
|
+
}
|
|
347
388
|
setCalendarVisibility(calendarId, shouldBeVisible) {
|
|
348
389
|
return __awaiter(this, void 0, void 0, function* () {
|
|
349
390
|
if (shouldBeVisible) {
|
|
@@ -508,6 +549,10 @@ export default class CalendarEventManager {
|
|
|
508
549
|
hasEvent(id) {
|
|
509
550
|
return !!this.allEvents.find((e) => e.id === id);
|
|
510
551
|
}
|
|
552
|
+
getLastChunkingId() {
|
|
553
|
+
var _a;
|
|
554
|
+
return (_a = this.activeChunk) === null || _a === void 0 ? void 0 : _a.id;
|
|
555
|
+
}
|
|
511
556
|
optionallyAskForUpdateRepeatingStrategy(event, action = 'update') {
|
|
512
557
|
var _a;
|
|
513
558
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -543,6 +588,8 @@ export default class CalendarEventManager {
|
|
|
543
588
|
});
|
|
544
589
|
}
|
|
545
590
|
}
|
|
591
|
+
CalendarEventManager.shouldBatchEvents = false;
|
|
592
|
+
export default CalendarEventManager;
|
|
546
593
|
class UpdateOperation {
|
|
547
594
|
constructor(options) {
|
|
548
595
|
const { id, updates, onComplete } = options;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MercuryClient } from '@sprucelabs/mercury-client';
|
|
2
2
|
import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
|
|
3
|
-
import { CalendarPerson } from '../
|
|
3
|
+
import { CalendarPerson } from '../root/Root.svc';
|
|
4
4
|
import RemotePreferencesStore from '../stores/RemotePreferencesStore';
|
|
5
5
|
import { PersonMode } from '../tools/PersonSelectTool.vc';
|
|
6
6
|
import { CalendarEvent } from '../types/calendar.types';
|
|
@@ -11,7 +11,7 @@ export default class CalendarPersister {
|
|
|
11
11
|
protected eventSwappedHandler?: EventSwappedHandler;
|
|
12
12
|
protected constructor(options: CalendarPersisterOptions);
|
|
13
13
|
static Persister(options: CalendarPersisterOptions): CalendarPersister;
|
|
14
|
-
persist(event: UpdateEvent): Promise<import("@sprucelabs/
|
|
14
|
+
persist(event: UpdateEvent): Promise<import("@sprucelabs/mercury-types").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEvent | UpdateEvent | undefined>;
|
|
15
15
|
waitForPendingSaves(): Promise<void>;
|
|
16
16
|
setRemoteStore(events: RemoteEventStore): void;
|
|
17
17
|
getRemoteStore(): RemoteEventStore | undefined;
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { AbstractSkillViewController, ToolBeltStateMachine, } from '@sprucelabs/heartwood-view-controllers';
|
|
11
|
-
import {
|
|
11
|
+
import { RemoteViewControllerFactoryImpl, } from '@sprucelabs/spruce-heartwood-utils';
|
|
12
12
|
import CalendarEventManager from '../calendar/CalendarEventManager.js';
|
|
13
13
|
import CalendarPeopleManager from '../calendar/CalendarPeopleManager.js';
|
|
14
14
|
import RemoteEventStoreImpl from '../stores/RemoteEventStore.js';
|
|
@@ -23,7 +23,7 @@ class RootSkillViewController extends AbstractSkillViewController {
|
|
|
23
23
|
this.toolBeltVc = this.ToolBeltVc();
|
|
24
24
|
this.calendarVc = this.CalendarVc();
|
|
25
25
|
this.sm = this.ToolBeltStateMachine();
|
|
26
|
-
this.remoteVc =
|
|
26
|
+
this.remoteVc = RemoteViewControllerFactoryImpl.Factory({
|
|
27
27
|
connectToApi: this.connectToApi.bind(this),
|
|
28
28
|
vcFactory: this.getVcFactory(),
|
|
29
29
|
});
|
|
@@ -205,7 +205,10 @@ class RootSkillViewController extends AbstractSkillViewController {
|
|
|
205
205
|
handleChangeStartDate() {
|
|
206
206
|
return __awaiter(this, void 0, void 0, function* () {
|
|
207
207
|
const startDate = this.calendarVc.getStartDate();
|
|
208
|
-
|
|
208
|
+
let isForceRefresh = false;
|
|
209
|
+
if (this.lastStartDate && startDate) {
|
|
210
|
+
isForceRefresh = this.dates.isSameDay(this.lastStartDate, startDate);
|
|
211
|
+
}
|
|
209
212
|
if (isForceRefresh) {
|
|
210
213
|
yield this.alert({
|
|
211
214
|
message: `Forcing refresh now!`,
|
|
@@ -522,7 +525,7 @@ class RootSkillViewController extends AbstractSkillViewController {
|
|
|
522
525
|
const endDate = this.dates.getEndOfDay(date);
|
|
523
526
|
const events = yield this.events.loadEvents(startDate, endDate, this.people.getTeam().map((t) => t.id));
|
|
524
527
|
yield this.people.emitDidUpdate();
|
|
525
|
-
this.cacheEvents(events);
|
|
528
|
+
events && this.cacheEvents(events);
|
|
526
529
|
}
|
|
527
530
|
}
|
|
528
531
|
catch (err) {
|
|
@@ -15,11 +15,13 @@ export default class RemoteEventStoreImpl implements RemoteEventStore {
|
|
|
15
15
|
private lastSavedById;
|
|
16
16
|
private calendarEventTypes?;
|
|
17
17
|
protected calendars?: Calendar[];
|
|
18
|
+
private streamHandler?;
|
|
18
19
|
constructor(options: RemoteEventStoreOptions);
|
|
19
20
|
load(options: {
|
|
20
21
|
organizationId: string;
|
|
21
22
|
locationId: string;
|
|
22
23
|
}): Promise<void>;
|
|
24
|
+
setStreamHandler(cb: StreamHandler): Promise<void>;
|
|
23
25
|
persist(event: UpdateEvent): Promise<FullEvent>;
|
|
24
26
|
private startQueueForEvent;
|
|
25
27
|
private getId;
|
|
@@ -35,7 +37,9 @@ export default class RemoteEventStoreImpl implements RemoteEventStore {
|
|
|
35
37
|
getCalendarId(): string | undefined;
|
|
36
38
|
waitForPendingSaves(): Promise<void>;
|
|
37
39
|
cancelEvent(id: string, options: CancelEventRecurringOptions): Promise<void>;
|
|
40
|
+
sendSchedules(options: SendScheduleOptions): Promise<void>;
|
|
38
41
|
getSchedules(options: GetScheduleOptions): Promise<Pick<import("@sprucelabs/schema").SchemaStaticValues<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema, false, import("@sprucelabs/schema").SchemaOptionalFieldNames<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema>, import("@sprucelabs/schema").StaticSchemaAllValues<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema, false>>, "id" | "startDateTimeMs" | "style" | "calendarId" | "target" | "timeBlocks" | "isBusy" | "source" | "eventTypeSlug" | "isResizeable" | "groupId" | "repeats" | "daysOfWeek" | "daysOfMonth" | "repeatsUntil" | "occurrences" | "interval" | "nthOccurrences" | "activeUntilDate" | "exclusionDates" | "dateDeleted" | "dateCreated" | "nthInRepeating" | "totalInRepeating" | "meta">[]>;
|
|
42
|
+
private buildTargetAndPayload;
|
|
39
43
|
getEventTypes(): Promise<SpruceSchemas.Calendar.v2021_05_19.CalendarEventType[]>;
|
|
40
44
|
getCalendars(): Promise<SpruceSchemas.Calendar.v2021_05_19.Calendar[]>;
|
|
41
45
|
}
|
|
@@ -45,6 +49,7 @@ export interface RemoteEventStoreOptions {
|
|
|
45
49
|
}
|
|
46
50
|
type FullEvent = SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEvent;
|
|
47
51
|
export interface RemoteEventStore {
|
|
52
|
+
sendSchedules(options: SendScheduleOptions): Promise<void>;
|
|
48
53
|
load(options: {
|
|
49
54
|
organizationId: string;
|
|
50
55
|
locationId: string;
|
|
@@ -58,12 +63,18 @@ export interface RemoteEventStore {
|
|
|
58
63
|
getSchedules(options: GetScheduleOptions): Promise<CalendarEvent[]>;
|
|
59
64
|
getEventTypes(): Promise<CalendarEventType[]>;
|
|
60
65
|
getCalendars(): Promise<Calendar[]>;
|
|
66
|
+
setStreamHandler(cb: StreamHandler): void;
|
|
61
67
|
}
|
|
62
68
|
export type RemoteEventStoreConstructor = new (options: any) => RemoteEventStore;
|
|
63
|
-
export
|
|
69
|
+
export interface GetScheduleOptions {
|
|
64
70
|
calendarIds: string[];
|
|
65
71
|
peopleIds: string[];
|
|
66
72
|
startDate: number;
|
|
67
73
|
endDate: number;
|
|
68
|
-
}
|
|
74
|
+
}
|
|
75
|
+
export interface SendScheduleOptions extends GetScheduleOptions {
|
|
76
|
+
chunkingId: string;
|
|
77
|
+
}
|
|
78
|
+
export type StreamScheduleHandlerOptions = SpruceSchemas.Calendar.v2021_05_19.StreamSchedulesEmitPayload;
|
|
79
|
+
export type StreamHandler = (options: StreamScheduleHandlerOptions) => void;
|
|
69
80
|
export {};
|
|
@@ -45,6 +45,15 @@ export default class RemoteEventStoreImpl {
|
|
|
45
45
|
this.locationId = locationId;
|
|
46
46
|
this.organizationId = organizationId;
|
|
47
47
|
this.client = yield this.connectToApi();
|
|
48
|
+
yield this.client.on('calendar.stream-schedules::v2021_05_19', ({ payload }) => {
|
|
49
|
+
var _a;
|
|
50
|
+
(_a = this.streamHandler) === null || _a === void 0 ? void 0 : _a.call(this, payload);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
setStreamHandler(cb) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
this.streamHandler = cb;
|
|
48
57
|
});
|
|
49
58
|
}
|
|
50
59
|
persist(event) {
|
|
@@ -233,23 +242,35 @@ export default class RemoteEventStoreImpl {
|
|
|
233
242
|
}
|
|
234
243
|
});
|
|
235
244
|
}
|
|
245
|
+
sendSchedules(options) {
|
|
246
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
+
const { chunkingId } = options, rest = __rest(options, ["chunkingId"]);
|
|
248
|
+
const getSchedulesTargetAndPayload = this.buildTargetAndPayload(rest);
|
|
249
|
+
yield this.client.emitAndFlattenResponses('calendar.send-schedules::v2021_05_19', Object.assign(Object.assign({}, getSchedulesTargetAndPayload), { payload: Object.assign(Object.assign({}, getSchedulesTargetAndPayload.payload), { chunkingId, sendToFqen: 'calendar.stream-schedules::v2021_05_19' }) }));
|
|
250
|
+
});
|
|
251
|
+
}
|
|
236
252
|
getSchedules(options) {
|
|
237
253
|
return __awaiter(this, void 0, void 0, function* () {
|
|
238
|
-
const
|
|
239
|
-
const [{ events }] = yield this.client.emitAndFlattenResponses('calendar.get-schedules::v2021_05_19',
|
|
240
|
-
target: {
|
|
241
|
-
calendarIds,
|
|
242
|
-
locationId: this.locationId,
|
|
243
|
-
},
|
|
244
|
-
payload: {
|
|
245
|
-
startDateTimeMs: startDate,
|
|
246
|
-
endDateTimeMs: endDate,
|
|
247
|
-
personIds,
|
|
248
|
-
},
|
|
249
|
-
});
|
|
254
|
+
const targetAndPayload = this.buildTargetAndPayload(options);
|
|
255
|
+
const [{ events }] = yield this.client.emitAndFlattenResponses('calendar.get-schedules::v2021_05_19', targetAndPayload);
|
|
250
256
|
return events;
|
|
251
257
|
});
|
|
252
258
|
}
|
|
259
|
+
buildTargetAndPayload(options) {
|
|
260
|
+
const { calendarIds, peopleIds: personIds, startDate, endDate } = options;
|
|
261
|
+
const targetAndPayload = {
|
|
262
|
+
target: {
|
|
263
|
+
calendarIds,
|
|
264
|
+
locationId: this.locationId,
|
|
265
|
+
},
|
|
266
|
+
payload: {
|
|
267
|
+
startDateTimeMs: startDate,
|
|
268
|
+
endDateTimeMs: endDate,
|
|
269
|
+
personIds,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
return targetAndPayload;
|
|
273
|
+
}
|
|
253
274
|
getEventTypes() {
|
|
254
275
|
return __awaiter(this, void 0, void 0, function* () {
|
|
255
276
|
if (this.calendarEventTypes) {
|
|
@@ -45,7 +45,7 @@ class CalendarToolRegistrar {
|
|
|
45
45
|
scope.getCurrentLocation(),
|
|
46
46
|
]);
|
|
47
47
|
const client = yield this.sm.connectToApi();
|
|
48
|
-
const registrar =
|
|
48
|
+
const registrar = CardRegistrar.Registrar({
|
|
49
49
|
client,
|
|
50
50
|
vcFactory: this.views,
|
|
51
51
|
vcIdsTransformer: (response) => response.vcIds,
|
|
@@ -67,10 +67,10 @@ class EventDateTimeToolViewController extends AbstractViewController {
|
|
|
67
67
|
label: `I'm done! Let's navigate to ${formattedDestination}.`,
|
|
68
68
|
onClick: () => __awaiter(this, void 0, void 0, function* () {
|
|
69
69
|
shouldBail = true;
|
|
70
|
+
yield dlg.hide();
|
|
70
71
|
const { events } = this.getContext();
|
|
71
|
-
yield events.setCurrentDate(dateTimeMs);
|
|
72
72
|
yield events.deselectEvent();
|
|
73
|
-
yield
|
|
73
|
+
yield events.setCurrentDate(dateTimeMs);
|
|
74
74
|
}),
|
|
75
75
|
},
|
|
76
76
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BatchCursor } from '@sprucelabs/data-stores';
|
|
1
2
|
import { AbstractViewController, CriticalError, LineIcon, SkillViewControllerLoadOptions, ToolBeltState, ToolBeltStateMachine } from '@sprucelabs/heartwood-view-controllers';
|
|
2
3
|
import { SpruceSchemas } from '@sprucelabs/mercury-types';
|
|
3
4
|
import { EventTarget } from '@sprucelabs/spruce-event-utils';
|
|
@@ -8,6 +9,7 @@ import { UpdateRepeatingStrategy } from '../constants';
|
|
|
8
9
|
export interface Schedule {
|
|
9
10
|
target: EventTarget;
|
|
10
11
|
events: CalendarEventRecord[];
|
|
12
|
+
cursor?: BatchCursor<CalendarEventRecord>;
|
|
11
13
|
}
|
|
12
14
|
export type EventForShift = Pick<CalendarEvent, 'id' | 'timeBlocks' | 'startDateTimeMs' | 'target'>;
|
|
13
15
|
export type DraftEvent = Pick<CalendarEvent, 'id' | 'startDateTimeMs' | 'style' | 'calendarId' | 'target' | 'timeBlocks' | 'isBusy'>;
|
|
@@ -24,6 +26,7 @@ export type CalendarEventType = SpruceSchemas.Calendar.v2021_05_19.CalendarEvent
|
|
|
24
26
|
export type SimpleCalendar = Pick<Calendar, 'id' | 'availableTimeSlotBehavior'>;
|
|
25
27
|
type Card = SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
|
|
26
28
|
export type PersonWithoutSchedule = SpruceSchemas.Calendar.v2021_05_19.PersonWithoutSchedule;
|
|
29
|
+
export type SavedCalendarEvent = SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEvent;
|
|
27
30
|
type ICalendarToolBeltContext = SkillViewControllerLoadOptions & {
|
|
28
31
|
event: CalendarEvent;
|
|
29
32
|
/**
|
|
@@ -19,7 +19,7 @@ class RootSkillViewController extends heartwood_view_controllers_1.AbstractSkill
|
|
|
19
19
|
this.toolBeltVc = this.ToolBeltVc();
|
|
20
20
|
this.calendarVc = this.CalendarVc();
|
|
21
21
|
this.sm = this.ToolBeltStateMachine();
|
|
22
|
-
this.remoteVc = spruce_heartwood_utils_1.
|
|
22
|
+
this.remoteVc = spruce_heartwood_utils_1.RemoteViewControllerFactoryImpl.Factory({
|
|
23
23
|
connectToApi: this.connectToApi.bind(this),
|
|
24
24
|
vcFactory: this.getVcFactory(),
|
|
25
25
|
});
|
|
@@ -182,7 +182,10 @@ class RootSkillViewController extends heartwood_view_controllers_1.AbstractSkill
|
|
|
182
182
|
}
|
|
183
183
|
async handleChangeStartDate() {
|
|
184
184
|
const startDate = this.calendarVc.getStartDate();
|
|
185
|
-
|
|
185
|
+
let isForceRefresh = false;
|
|
186
|
+
if (this.lastStartDate && startDate) {
|
|
187
|
+
isForceRefresh = this.dates.isSameDay(this.lastStartDate, startDate);
|
|
188
|
+
}
|
|
186
189
|
if (isForceRefresh) {
|
|
187
190
|
await this.alert({
|
|
188
191
|
message: `Forcing refresh now!`,
|
|
@@ -461,7 +464,7 @@ class RootSkillViewController extends heartwood_view_controllers_1.AbstractSkill
|
|
|
461
464
|
const endDate = this.dates.getEndOfDay(date);
|
|
462
465
|
const events = await this.events.loadEvents(startDate, endDate, this.people.getTeam().map((t) => t.id));
|
|
463
466
|
await this.people.emitDidUpdate();
|
|
464
|
-
this.cacheEvents(events);
|
|
467
|
+
events && this.cacheEvents(events);
|
|
465
468
|
}
|
|
466
469
|
}
|
|
467
470
|
catch (err) {
|
|
@@ -15,11 +15,13 @@ export default class RemoteEventStoreImpl implements RemoteEventStore {
|
|
|
15
15
|
private lastSavedById;
|
|
16
16
|
private calendarEventTypes?;
|
|
17
17
|
protected calendars?: Calendar[];
|
|
18
|
+
private streamHandler?;
|
|
18
19
|
constructor(options: RemoteEventStoreOptions);
|
|
19
20
|
load(options: {
|
|
20
21
|
organizationId: string;
|
|
21
22
|
locationId: string;
|
|
22
23
|
}): Promise<void>;
|
|
24
|
+
setStreamHandler(cb: StreamHandler): Promise<void>;
|
|
23
25
|
persist(event: UpdateEvent): Promise<FullEvent>;
|
|
24
26
|
private startQueueForEvent;
|
|
25
27
|
private getId;
|
|
@@ -35,7 +37,9 @@ export default class RemoteEventStoreImpl implements RemoteEventStore {
|
|
|
35
37
|
getCalendarId(): string | undefined;
|
|
36
38
|
waitForPendingSaves(): Promise<void>;
|
|
37
39
|
cancelEvent(id: string, options: CancelEventRecurringOptions): Promise<void>;
|
|
40
|
+
sendSchedules(options: SendScheduleOptions): Promise<void>;
|
|
38
41
|
getSchedules(options: GetScheduleOptions): Promise<Pick<import("@sprucelabs/schema").SchemaStaticValues<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema, false, import("@sprucelabs/schema").SchemaOptionalFieldNames<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema>, import("@sprucelabs/schema").StaticSchemaAllValues<SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventSchema, false>>, "id" | "startDateTimeMs" | "style" | "calendarId" | "target" | "timeBlocks" | "isBusy" | "source" | "eventTypeSlug" | "isResizeable" | "groupId" | "repeats" | "daysOfWeek" | "daysOfMonth" | "repeatsUntil" | "occurrences" | "interval" | "nthOccurrences" | "activeUntilDate" | "exclusionDates" | "dateDeleted" | "dateCreated" | "nthInRepeating" | "totalInRepeating" | "meta">[]>;
|
|
42
|
+
private buildTargetAndPayload;
|
|
39
43
|
getEventTypes(): Promise<SpruceSchemas.Calendar.v2021_05_19.CalendarEventType[]>;
|
|
40
44
|
getCalendars(): Promise<SpruceSchemas.Calendar.v2021_05_19.Calendar[]>;
|
|
41
45
|
}
|
|
@@ -45,6 +49,7 @@ export interface RemoteEventStoreOptions {
|
|
|
45
49
|
}
|
|
46
50
|
type FullEvent = SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEvent;
|
|
47
51
|
export interface RemoteEventStore {
|
|
52
|
+
sendSchedules(options: SendScheduleOptions): Promise<void>;
|
|
48
53
|
load(options: {
|
|
49
54
|
organizationId: string;
|
|
50
55
|
locationId: string;
|
|
@@ -58,12 +63,18 @@ export interface RemoteEventStore {
|
|
|
58
63
|
getSchedules(options: GetScheduleOptions): Promise<CalendarEvent[]>;
|
|
59
64
|
getEventTypes(): Promise<CalendarEventType[]>;
|
|
60
65
|
getCalendars(): Promise<Calendar[]>;
|
|
66
|
+
setStreamHandler(cb: StreamHandler): void;
|
|
61
67
|
}
|
|
62
68
|
export type RemoteEventStoreConstructor = new (options: any) => RemoteEventStore;
|
|
63
|
-
export
|
|
69
|
+
export interface GetScheduleOptions {
|
|
64
70
|
calendarIds: string[];
|
|
65
71
|
peopleIds: string[];
|
|
66
72
|
startDate: number;
|
|
67
73
|
endDate: number;
|
|
68
|
-
}
|
|
74
|
+
}
|
|
75
|
+
export interface SendScheduleOptions extends GetScheduleOptions {
|
|
76
|
+
chunkingId: string;
|
|
77
|
+
}
|
|
78
|
+
export type StreamScheduleHandlerOptions = SpruceSchemas.Calendar.v2021_05_19.StreamSchedulesEmitPayload;
|
|
79
|
+
export type StreamHandler = (options: StreamScheduleHandlerOptions) => void;
|
|
69
80
|
export {};
|
|
@@ -40,6 +40,13 @@ class RemoteEventStoreImpl {
|
|
|
40
40
|
this.locationId = locationId;
|
|
41
41
|
this.organizationId = organizationId;
|
|
42
42
|
this.client = await this.connectToApi();
|
|
43
|
+
await this.client.on('calendar.stream-schedules::v2021_05_19', ({ payload }) => {
|
|
44
|
+
var _a;
|
|
45
|
+
(_a = this.streamHandler) === null || _a === void 0 ? void 0 : _a.call(this, payload);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async setStreamHandler(cb) {
|
|
49
|
+
this.streamHandler = cb;
|
|
43
50
|
}
|
|
44
51
|
async persist(event) {
|
|
45
52
|
if (!this.resolveCalendarId(event)) {
|
|
@@ -213,9 +220,19 @@ class RemoteEventStoreImpl {
|
|
|
213
220
|
});
|
|
214
221
|
}
|
|
215
222
|
}
|
|
223
|
+
async sendSchedules(options) {
|
|
224
|
+
const { chunkingId } = options, rest = __rest(options, ["chunkingId"]);
|
|
225
|
+
const getSchedulesTargetAndPayload = this.buildTargetAndPayload(rest);
|
|
226
|
+
await this.client.emitAndFlattenResponses('calendar.send-schedules::v2021_05_19', Object.assign(Object.assign({}, getSchedulesTargetAndPayload), { payload: Object.assign(Object.assign({}, getSchedulesTargetAndPayload.payload), { chunkingId, sendToFqen: 'calendar.stream-schedules::v2021_05_19' }) }));
|
|
227
|
+
}
|
|
216
228
|
async getSchedules(options) {
|
|
229
|
+
const targetAndPayload = this.buildTargetAndPayload(options);
|
|
230
|
+
const [{ events }] = await this.client.emitAndFlattenResponses('calendar.get-schedules::v2021_05_19', targetAndPayload);
|
|
231
|
+
return events;
|
|
232
|
+
}
|
|
233
|
+
buildTargetAndPayload(options) {
|
|
217
234
|
const { calendarIds, peopleIds: personIds, startDate, endDate } = options;
|
|
218
|
-
const
|
|
235
|
+
const targetAndPayload = {
|
|
219
236
|
target: {
|
|
220
237
|
calendarIds,
|
|
221
238
|
locationId: this.locationId,
|
|
@@ -225,8 +242,8 @@ class RemoteEventStoreImpl {
|
|
|
225
242
|
endDateTimeMs: endDate,
|
|
226
243
|
personIds,
|
|
227
244
|
},
|
|
228
|
-
}
|
|
229
|
-
return
|
|
245
|
+
};
|
|
246
|
+
return targetAndPayload;
|
|
230
247
|
}
|
|
231
248
|
async getEventTypes() {
|
|
232
249
|
if (this.calendarEventTypes) {
|
|
@@ -35,7 +35,7 @@ class CalendarToolRegistrar {
|
|
|
35
35
|
scope.getCurrentLocation(),
|
|
36
36
|
]);
|
|
37
37
|
const client = await this.sm.connectToApi();
|
|
38
|
-
const registrar =
|
|
38
|
+
const registrar = spruce_heartwood_utils_1.CardRegistrar.Registrar({
|
|
39
39
|
client,
|
|
40
40
|
vcFactory: this.views,
|
|
41
41
|
vcIdsTransformer: (response) => response.vcIds,
|
|
@@ -57,10 +57,10 @@ class EventDateTimeToolViewController extends heartwood_view_controllers_1.Abstr
|
|
|
57
57
|
label: `I'm done! Let's navigate to ${formattedDestination}.`,
|
|
58
58
|
onClick: async () => {
|
|
59
59
|
shouldBail = true;
|
|
60
|
+
await dlg.hide();
|
|
60
61
|
const { events } = this.getContext();
|
|
61
|
-
await events.setCurrentDate(dateTimeMs);
|
|
62
62
|
await events.deselectEvent();
|
|
63
|
-
await
|
|
63
|
+
await events.setCurrentDate(dateTimeMs);
|
|
64
64
|
},
|
|
65
65
|
},
|
|
66
66
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BatchCursor } from '@sprucelabs/data-stores';
|
|
1
2
|
import { AbstractViewController, CriticalError, LineIcon, SkillViewControllerLoadOptions, ToolBeltState, ToolBeltStateMachine } from '@sprucelabs/heartwood-view-controllers';
|
|
2
3
|
import { SpruceSchemas } from '@sprucelabs/mercury-types';
|
|
3
4
|
import { EventTarget } from '@sprucelabs/spruce-event-utils';
|
|
@@ -8,6 +9,7 @@ import { UpdateRepeatingStrategy } from '../constants';
|
|
|
8
9
|
export interface Schedule {
|
|
9
10
|
target: EventTarget;
|
|
10
11
|
events: CalendarEventRecord[];
|
|
12
|
+
cursor?: BatchCursor<CalendarEventRecord>;
|
|
11
13
|
}
|
|
12
14
|
export type EventForShift = Pick<CalendarEvent, 'id' | 'timeBlocks' | 'startDateTimeMs' | 'target'>;
|
|
13
15
|
export type DraftEvent = Pick<CalendarEvent, 'id' | 'startDateTimeMs' | 'style' | 'calendarId' | 'target' | 'timeBlocks' | 'isBusy'>;
|
|
@@ -24,6 +26,7 @@ export type CalendarEventType = SpruceSchemas.Calendar.v2021_05_19.CalendarEvent
|
|
|
24
26
|
export type SimpleCalendar = Pick<Calendar, 'id' | 'availableTimeSlotBehavior'>;
|
|
25
27
|
type Card = SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
|
|
26
28
|
export type PersonWithoutSchedule = SpruceSchemas.Calendar.v2021_05_19.PersonWithoutSchedule;
|
|
29
|
+
export type SavedCalendarEvent = SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEvent;
|
|
27
30
|
type ICalendarToolBeltContext = SkillViewControllerLoadOptions & {
|
|
28
31
|
event: CalendarEvent;
|
|
29
32
|
/**
|