@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.
Files changed (31) hide show
  1. package/build/.spruce/schemas/schemas.types.d.ts +781 -541
  2. package/build/__tests__/support/CalendarToolBeltStateMachineTestFactory.d.ts +3 -1
  3. package/build/__tests__/support/CalendarToolBeltStateMachineTestFactory.js +4 -0
  4. package/build/__tests__/support/SpyEventManager.d.ts +5 -5
  5. package/build/calendar/CalendarEventManager.d.ts +9 -1
  6. package/build/calendar/CalendarEventManager.js +45 -3
  7. package/build/calendar/CalendarPeopleManager.d.ts +1 -1
  8. package/build/calendar/CalendarPersister.d.ts +1 -1
  9. package/build/esm/.spruce/schemas/schemas.types.d.ts +781 -541
  10. package/build/esm/__tests__/support/CalendarToolBeltStateMachineTestFactory.d.ts +3 -1
  11. package/build/esm/__tests__/support/CalendarToolBeltStateMachineTestFactory.js +6 -0
  12. package/build/esm/__tests__/support/SpyEventManager.d.ts +5 -5
  13. package/build/esm/calendar/CalendarEventManager.d.ts +9 -1
  14. package/build/esm/calendar/CalendarEventManager.js +51 -4
  15. package/build/esm/calendar/CalendarPeopleManager.d.ts +1 -1
  16. package/build/esm/calendar/CalendarPersister.d.ts +1 -1
  17. package/build/esm/{skillViewControllers → root}/Root.svc.js +7 -4
  18. package/build/esm/stores/RemoteEventStore.d.ts +13 -2
  19. package/build/esm/stores/RemoteEventStore.js +33 -12
  20. package/build/esm/toolBelt/CalendarToolRegistrar.js +1 -1
  21. package/build/esm/tools/EventDateTimeTool.vc.js +2 -2
  22. package/build/esm/types/calendar.types.d.ts +3 -0
  23. package/build/{skillViewControllers → root}/Root.svc.js +6 -3
  24. package/build/stores/RemoteEventStore.d.ts +13 -2
  25. package/build/stores/RemoteEventStore.js +20 -3
  26. package/build/toolBelt/CalendarToolRegistrar.js +1 -1
  27. package/build/tools/EventDateTimeTool.vc.js +2 -2
  28. package/build/types/calendar.types.d.ts +3 -0
  29. package/package.json +5 -5
  30. /package/build/esm/{skillViewControllers → root}/Root.svc.d.ts +0 -0
  31. /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/spruce-core-schemas").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarShift[];
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/spruce-core-schemas").SpruceSchemas.CalendarUtils.v2021_05_19.CalendarEventTarget;
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/spruce-core-schemas").SpruceSchemas.CalendarUtils.v2021_05_19.EventTimeBlock[];
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/spruce-core-schemas").SpruceSchemas.CalendarUtils.v2021_05_19.EventExclusionDate[] | null | undefined;
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/spruce-core-schemas").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEventColorOverride | null | undefined;
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
- loadEvents(startDate: number, endDate: number, peopleIds: string[]): Promise<import("@sprucelabs/calendar-utils").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEvent[]>;
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
- export default class CalendarEventManager {
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
- const events = yield this.events.getSchedules({
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 '../skillViewControllers/Root.svc';
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/spruce-core-schemas").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarEvent | UpdateEvent | undefined>;
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 { RemoteViewControllerFactory } from '@sprucelabs/spruce-heartwood-utils';
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 = RemoteViewControllerFactory.Factory({
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
- const isForceRefresh = this.lastStartDate && this.lastStartDate === startDate;
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 type GetScheduleOptions = {
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 { calendarIds, peopleIds: personIds, startDate, endDate } = options;
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 = new CardRegistrar({
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 dlg.hide();
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.RemoteViewControllerFactory.Factory({
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
- const isForceRefresh = this.lastStartDate && this.lastStartDate === startDate;
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 type GetScheduleOptions = {
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 [{ events }] = await this.client.emitAndFlattenResponses('calendar.get-schedules::v2021_05_19', {
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 events;
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 = new spruce_heartwood_utils_1.CardRegistrar({
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 dlg.hide();
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
  /**