@sprucelabs/spruce-calendar-components 20.11.1 → 21.0.4

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 (75) hide show
  1. package/build/.spruce/errors/errors.types.d.ts +122 -0
  2. package/build/.spruce/errors/errors.types.js +4 -0
  3. package/build/.spruce/errors/options.types.d.ts +28 -0
  4. package/build/.spruce/errors/options.types.js +2 -0
  5. package/build/constants.d.ts +5 -0
  6. package/build/constants.js +9 -0
  7. package/build/errors/SpruceError.d.ts +5 -0
  8. package/build/errors/SpruceError.js +45 -0
  9. package/build/esm/.spruce/errors/errors.types.d.ts +122 -0
  10. package/build/esm/.spruce/errors/errors.types.js +3 -0
  11. package/build/esm/.spruce/errors/options.types.d.ts +28 -0
  12. package/build/esm/.spruce/errors/options.types.js +1 -0
  13. package/build/esm/constants.d.ts +5 -0
  14. package/build/esm/constants.js +6 -0
  15. package/build/esm/errors/SpruceError.d.ts +5 -0
  16. package/build/esm/errors/SpruceError.js +39 -0
  17. package/build/esm/index-module.d.ts +30 -0
  18. package/build/esm/index-module.js +7 -0
  19. package/build/esm/skillViewControllers/Root.svc.d.ts +73 -0
  20. package/build/esm/skillViewControllers/Root.svc.js +404 -0
  21. package/build/esm/stores/RemotePreferencesStore.d.ts +26 -0
  22. package/build/esm/stores/RemotePreferencesStore.js +85 -0
  23. package/build/esm/toolBelt/CalendarToolTestFactory.d.ts +5 -0
  24. package/build/esm/toolBelt/CalendarToolTestFactory.js +28 -0
  25. package/build/esm/toolBelt/states/PrerequisitesToolBeltState.d.ts +37 -0
  26. package/build/esm/toolBelt/states/PrerequisitesToolBeltState.js +190 -0
  27. package/build/esm/toolBelt/states/RootToolBeltState.d.ts +37 -0
  28. package/build/esm/toolBelt/states/RootToolBeltState.js +122 -0
  29. package/build/esm/toolBelt/states/makeEventTyped.d.ts +2 -0
  30. package/build/esm/toolBelt/states/makeEventTyped.js +8 -0
  31. package/build/esm/types/calendar.types.d.ts +10 -0
  32. package/build/esm/utilities/CalendarEventManager.d.ts +72 -0
  33. package/build/esm/utilities/CalendarEventManager.js +321 -0
  34. package/build/esm/utilities/CalendarPeopleManager.d.ts +56 -0
  35. package/build/esm/utilities/CalendarPeopleManager.js +182 -0
  36. package/build/esm/utilities/calendarShiftGenerator.d.ts +8 -0
  37. package/build/esm/utilities/calendarShiftGenerator.js +24 -0
  38. package/build/esm/viewControllers/CalendarSelectTool.vc.d.ts +28 -0
  39. package/build/esm/viewControllers/CalendarSelectTool.vc.js +103 -0
  40. package/build/esm/viewControllers/DateSelectCard.vc.d.ts +29 -0
  41. package/build/esm/viewControllers/DateSelectCard.vc.js +77 -0
  42. package/build/esm/viewControllers/PersonSelectTool.vc.d.ts +36 -0
  43. package/build/esm/viewControllers/PersonSelectTool.vc.js +156 -0
  44. package/build/esm/viewControllers/SelectUpdateRepeatingStrategyCard.vc.d.ts +18 -0
  45. package/build/esm/viewControllers/SelectUpdateRepeatingStrategyCard.vc.js +85 -0
  46. package/build/index-module.d.ts +30 -0
  47. package/build/index-module.js +32 -0
  48. package/build/skillViewControllers/Root.svc.d.ts +73 -0
  49. package/build/skillViewControllers/Root.svc.js +359 -0
  50. package/build/stores/RemotePreferencesStore.d.ts +26 -0
  51. package/build/stores/RemotePreferencesStore.js +67 -0
  52. package/build/toolBelt/CalendarToolTestFactory.d.ts +5 -0
  53. package/build/toolBelt/CalendarToolTestFactory.js +34 -0
  54. package/build/toolBelt/states/PrerequisitesToolBeltState.d.ts +37 -0
  55. package/build/toolBelt/states/PrerequisitesToolBeltState.js +172 -0
  56. package/build/toolBelt/states/RootToolBeltState.d.ts +37 -0
  57. package/build/toolBelt/states/RootToolBeltState.js +113 -0
  58. package/build/toolBelt/states/makeEventTyped.d.ts +2 -0
  59. package/build/toolBelt/states/makeEventTyped.js +14 -0
  60. package/build/types/calendar.types.d.ts +10 -0
  61. package/build/utilities/CalendarEventManager.d.ts +72 -0
  62. package/build/utilities/CalendarEventManager.js +279 -0
  63. package/build/utilities/CalendarPeopleManager.d.ts +56 -0
  64. package/build/utilities/CalendarPeopleManager.js +163 -0
  65. package/build/utilities/calendarShiftGenerator.d.ts +8 -0
  66. package/build/utilities/calendarShiftGenerator.js +26 -0
  67. package/build/viewControllers/CalendarSelectTool.vc.d.ts +28 -0
  68. package/build/viewControllers/CalendarSelectTool.vc.js +93 -0
  69. package/build/viewControllers/DateSelectCard.vc.d.ts +29 -0
  70. package/build/viewControllers/DateSelectCard.vc.js +69 -0
  71. package/build/viewControllers/PersonSelectTool.vc.d.ts +36 -0
  72. package/build/viewControllers/PersonSelectTool.vc.js +140 -0
  73. package/build/viewControllers/SelectUpdateRepeatingStrategyCard.vc.d.ts +18 -0
  74. package/build/viewControllers/SelectUpdateRepeatingStrategyCard.vc.js +88 -0
  75. package/package.json +99 -26
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CalendarEventManager = void 0;
7
+ const heartwood_view_controllers_1 = require("@sprucelabs/heartwood-view-controllers");
8
+ const schema_1 = require("@sprucelabs/schema");
9
+ const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
10
+ const calendarShiftGenerator_1 = __importDefault(require("./calendarShiftGenerator"));
11
+ const draftGenerator_1 = __importDefault(require("./draftGenerator"));
12
+ class CalendarEventManager {
13
+ constructor(options) {
14
+ this.allEvents = [];
15
+ this.inclusiveCalendarIds = [];
16
+ this.hasVcForEventTypeBeenLoaded = {};
17
+ this.shouldIgnoreNextContextUpdate = false;
18
+ this.calendars = [];
19
+ this.shouldUpdateContextOnNextSave = true;
20
+ const { calendarVc, events, remoteVc, sm, askForUpdateStrategy, dates, preferences, } = (0, schema_1.assertOptions)(options, [
21
+ 'calendarVc',
22
+ 'events',
23
+ 'remoteVc',
24
+ 'sm',
25
+ 'askForUpdateStrategy',
26
+ 'dates',
27
+ 'preferences',
28
+ ]);
29
+ this.calendarVc = calendarVc;
30
+ this.events = events;
31
+ this.remoteVc = remoteVc;
32
+ this.sm = sm;
33
+ this.prefs = preferences;
34
+ this.dates = dates;
35
+ this.askForUpdateStrategy = askForUpdateStrategy;
36
+ this.calendarVc.setRemoteStore(this.events);
37
+ }
38
+ get calendarIds() {
39
+ return this.calendars.map((c) => c.id);
40
+ }
41
+ get visibleCalendarIds() {
42
+ var _a;
43
+ return (_a = this.prefs.getVisibleCalendarIds()) !== null && _a !== void 0 ? _a : this.calendars.map((c) => c.id);
44
+ }
45
+ replaceEventsInRange(events, startMs, endMs) {
46
+ this.calendarVc.replaceEventsInRange(events.filter((e) => this.isCalendarSelected(e.calendarId)), startMs, endMs);
47
+ this.allEvents = this.allEvents.filter((e) => events.findIndex((event) => event.id === e.id) === -1 &&
48
+ !(e.startDateTimeMs >= startMs && e.startDateTimeMs <= endMs));
49
+ this.allEvents.push(...events);
50
+ this.refreshShifts();
51
+ }
52
+ refreshShifts() {
53
+ const inclusiveEvents = this.allEvents.filter((e) => this.inclusiveCalendarIds.indexOf(e.calendarId) > -1);
54
+ const shifts = calendarShiftGenerator_1.default.generateFromEvents(inclusiveEvents);
55
+ this.calendarVc.setShifts([...shifts]);
56
+ }
57
+ isCalendarSelected(calendarId) {
58
+ return this.visibleCalendarIds.indexOf(calendarId) > -1;
59
+ }
60
+ doesCalenderExist(calendarId) {
61
+ return this.calendars.findIndex((c) => c.id === calendarId) > -1;
62
+ }
63
+ getAllEvents() {
64
+ return this.allEvents;
65
+ }
66
+ getCalendars() {
67
+ return this.calendars;
68
+ }
69
+ async addDraftEvent(event) {
70
+ this.calendarVc.selectEvent(event.id);
71
+ this.allEvents.push(event);
72
+ await this.updateEventInContext(event);
73
+ }
74
+ async silentlySwapEvent(oldId, event) {
75
+ const events = this.getAllEvents().filter((e) => e.id !== oldId);
76
+ this.allEvents = [...events, event];
77
+ await this.updateEventInContext(event);
78
+ }
79
+ async handleDropEvent(id, updates) {
80
+ const event = Object.assign(Object.assign({}, this.calendarVc.getEvent(id)), updates);
81
+ const pass = await this.optionallyAskForUpdateRepeatingStrategy(event);
82
+ if (pass) {
83
+ await this.saveEvent(event);
84
+ }
85
+ return pass;
86
+ }
87
+ async reset() {
88
+ var _a;
89
+ void this.setEventInContext(undefined);
90
+ (_a = this.events) === null || _a === void 0 ? void 0 : _a.clearCalendarId();
91
+ }
92
+ async restoreEventToDraftOnStateLoadError() {
93
+ const updated = await this.updateEventInContext({
94
+ timeBlocks: draftGenerator_1.default.generateTimeBlocks(),
95
+ calendarId: undefined,
96
+ eventTypeSlug: undefined,
97
+ });
98
+ this.updateEvent(updated.id, updated);
99
+ }
100
+ getVisibleCalendarIds() {
101
+ return this.visibleCalendarIds;
102
+ }
103
+ async removeEvent(id) {
104
+ var _a;
105
+ this.allEvents = this.allEvents.filter((e) => e.id !== id);
106
+ const event = this.calendarVc.getEvent(id);
107
+ this.calendarVc.removeEvent(id);
108
+ try {
109
+ await this.events.cancelEvent(event.id);
110
+ }
111
+ catch (err) {
112
+ console.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message);
113
+ this.calendarVc.addEvent(Object.assign(Object.assign({}, event), { error: err }));
114
+ }
115
+ }
116
+ async makeCalendarVisible(calendarId) {
117
+ this.assertValidCalendarId(calendarId);
118
+ this.calendarVc.mixinEvents(this.allEvents.filter((e) => e.calendarId === calendarId));
119
+ const visibleCalendarIds = [...this.visibleCalendarIds];
120
+ visibleCalendarIds.push(calendarId);
121
+ await this.prefs.setVisibleCalendarIds(visibleCalendarIds);
122
+ }
123
+ async makeCalendarHidden(calendarId) {
124
+ this.assertValidCalendarId(calendarId);
125
+ const visibleCalendarIds = this.visibleCalendarIds.filter((id) => id !== calendarId);
126
+ for (const event of this.allEvents) {
127
+ if (event.calendarId === calendarId &&
128
+ this.calendarVc.hasEvent(event.id)) {
129
+ this.calendarVc.removeEvent(event.id);
130
+ }
131
+ }
132
+ await this.prefs.setVisibleCalendarIds(visibleCalendarIds);
133
+ }
134
+ updateEvent(id, updates) {
135
+ var _a;
136
+ this.calendarVc.updateEvent(id, updates);
137
+ const idx = this.allEvents.findIndex((e) => e.id === id);
138
+ this.allEvents[idx] = Object.assign(Object.assign({}, this.allEvents[idx]), updates);
139
+ this.refreshShifts();
140
+ if (this.shouldUpdateContextOnNextSave &&
141
+ ((_a = this.sm.getContext().event) === null || _a === void 0 ? void 0 : _a.id) === id) {
142
+ this.shouldIgnoreNextContextUpdate = true;
143
+ void this.updateEventInContext(updates);
144
+ }
145
+ this.shouldUpdateContextOnNextSave = true;
146
+ }
147
+ async loadEvents(startDate, endDate, peopleIds) {
148
+ const events = await this.events.getSchedules({
149
+ calendarIds: this.calendarIds,
150
+ startDate,
151
+ endDate,
152
+ peopleIds,
153
+ });
154
+ this.replaceEventsInRange(events, startDate, endDate);
155
+ if (!this.eventTypes) {
156
+ this.eventTypes = await this.events.loadEventTypes();
157
+ }
158
+ await Promise.all(events.map(async (e) => {
159
+ var _a;
160
+ const type = (_a = this.eventTypes) === null || _a === void 0 ? void 0 : _a.find((t) => t.slug === e.eventTypeSlug);
161
+ if (type === null || type === void 0 ? void 0 : type.viewControllerId) {
162
+ await this.setupVcForEventType(type.viewControllerId, type.slug);
163
+ }
164
+ }));
165
+ }
166
+ async setCalendarVisibility(calendarId, shouldBeVisible) {
167
+ if (shouldBeVisible) {
168
+ await this.makeCalendarVisible(calendarId);
169
+ }
170
+ else {
171
+ await this.makeCalendarHidden(calendarId);
172
+ }
173
+ }
174
+ async setupVcForEventType(vcId, typeSlug) {
175
+ if (this.hasVcForEventTypeBeenLoaded[vcId]) {
176
+ return;
177
+ }
178
+ this.hasVcForEventTypeBeenLoaded[vcId] = true;
179
+ await this.remoteVc.fetchRemoteController(vcId);
180
+ this.calendarVc.setControllerForEventType(typeSlug, vcId);
181
+ }
182
+ assertValidCalendarId(calendarId) {
183
+ if (!this.doesCalenderExist(calendarId)) {
184
+ throw new SpruceError_1.default({
185
+ code: 'CALENDAR_NOT_FOUND',
186
+ calendarIds: [calendarId],
187
+ });
188
+ }
189
+ }
190
+ async updateEventInContext(updates) {
191
+ const { event } = this.sm.getContext();
192
+ const updated = Object.assign(Object.assign(Object.assign({}, event), updates), { isBusy: false });
193
+ await this.setEventInContext(updated);
194
+ return updated;
195
+ }
196
+ async setEventInContext(newEvent, options) {
197
+ this.shouldIgnoreNextContextUpdate =
198
+ (options === null || options === void 0 ? void 0 : options.shouldHandleDidUpdateContext) !== false;
199
+ await this.sm.updateContext({
200
+ event: newEvent,
201
+ });
202
+ }
203
+ async selectEvent(eventId) {
204
+ const lastSelected = this.calendarVc.getSelectedEvent();
205
+ const event = this.calendarVc.getEvent(eventId);
206
+ this.calendarVc.selectEvent(event.id);
207
+ if ((lastSelected === null || lastSelected === void 0 ? void 0 : lastSelected.id) !== event.id) {
208
+ await this.setEventInContext(event);
209
+ }
210
+ }
211
+ async load() {
212
+ await this.sm.on('will-update-context', this.handleWillUpdateContext.bind(this));
213
+ await this.sm.on('did-update-context', this.handleDidUpdateContext.bind(this));
214
+ await this.loadCalendars();
215
+ this.inclusiveCalendarIds = this.calendars
216
+ .filter((c) => c.availableTimeSlotBehavior === 'include')
217
+ .map((c) => c.id);
218
+ }
219
+ async loadCalendars() {
220
+ this.calendars = await this.events.loadCalendars();
221
+ }
222
+ async handleWillUpdateContext(options) {
223
+ const { event: originalEvent } = options.current;
224
+ const { event } = options.updates;
225
+ let pass = true;
226
+ if ((event === null || event === void 0 ? void 0 : event.id) &&
227
+ (originalEvent === null || originalEvent === void 0 ? void 0 : originalEvent.id) === (event === null || event === void 0 ? void 0 : event.id) &&
228
+ !this.shouldIgnoreNextContextUpdate) {
229
+ pass = await this.optionallyAskForUpdateRepeatingStrategy(event);
230
+ }
231
+ return {
232
+ shouldAllowUpdates: pass,
233
+ };
234
+ }
235
+ async handleDidUpdateContext() {
236
+ if (this.shouldIgnoreNextContextUpdate) {
237
+ this.shouldIgnoreNextContextUpdate = false;
238
+ return;
239
+ }
240
+ const { event } = this.sm.getContext();
241
+ if (event === null || event === void 0 ? void 0 : event.id) {
242
+ this.shouldUpdateContextOnNextSave = false;
243
+ await this.saveEvent(event);
244
+ }
245
+ }
246
+ async saveEvent(event) {
247
+ try {
248
+ const cleaned = (0, schema_1.normalizeSchemaValues)(heartwood_view_controllers_1.calendarEventSchema, Object.assign({}, event), {});
249
+ this.updateEvent(event.id, Object.assign(Object.assign({}, cleaned), { dateToUpdate: this.dateToUpdate, shouldUpdateAllEventsGoingForward: this.shouldUpdateAllEventsGoingForward }));
250
+ }
251
+ catch (err) {
252
+ console.error('Updating event in context from root failed because:\n\n', err);
253
+ }
254
+ }
255
+ async optionallyAskForUpdateRepeatingStrategy(event) {
256
+ var _a;
257
+ const cleaned = (0, schema_1.normalizeSchemaValues)(heartwood_view_controllers_1.calendarEventSchema, event, {});
258
+ if (((_a = cleaned.totalInRepeating) !== null && _a !== void 0 ? _a : 0) > 1) {
259
+ let strategy = await this.askForUpdateStrategy(cleaned);
260
+ if (strategy === 'cancel') {
261
+ return false;
262
+ }
263
+ else if (strategy === 'only-this-one') {
264
+ this.dateToUpdate = this.dates.getStartOfDay(event.startDateTimeMs);
265
+ this.shouldUpdateAllEventsGoingForward = false;
266
+ }
267
+ else if (strategy === 'all-going-forward') {
268
+ this.dateToUpdate = this.dates.getStartOfDay(event.startDateTimeMs);
269
+ this.shouldUpdateAllEventsGoingForward = true;
270
+ }
271
+ else {
272
+ this.dateToUpdate = undefined;
273
+ this.shouldUpdateAllEventsGoingForward = false;
274
+ }
275
+ }
276
+ return true;
277
+ }
278
+ }
279
+ exports.CalendarEventManager = CalendarEventManager;
@@ -0,0 +1,56 @@
1
+ import { MercuryClient } from '@sprucelabs/mercury-client';
2
+ import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
3
+ import { CalendarPerson } from '../skillViewControllers/Root.svc';
4
+ import RemotePreferencesStore from '../stores/RemotePreferencesStore';
5
+ import { CalendarEvent } from '../types/calendar.types';
6
+ import CalendarViewController from '../viewControllers/Calendar.vc';
7
+ import { PersonMode } from '../viewControllers/PersonSelectTool.vc';
8
+ export default class CalendarPeopleManager extends AbstractEventEmitter<PeopleContract> {
9
+ private connectToApi;
10
+ private prefs;
11
+ private client;
12
+ private loggedInPerson?;
13
+ private locationId;
14
+ private organizationId;
15
+ private team;
16
+ private getVisibleEvents;
17
+ constructor(options: PeopleManagerOptions);
18
+ load(options: {
19
+ loggedInPerson?: CalendarPerson | null;
20
+ locationId: string;
21
+ organizationId: string;
22
+ }): Promise<void>;
23
+ private loadTeam;
24
+ getVisiblePeople(): CalendarPerson[];
25
+ private teammateById;
26
+ getTeam(): import("@sprucelabs/mercury-types").SpruceSchemas.Spruce.v2020_07_22.Person[];
27
+ getLoggedInPerson(): import("@sprucelabs/mercury-types").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarPerson | undefined;
28
+ protected getVisiblePeopleIds(): string[];
29
+ private getSavedVisiblePeopleIds;
30
+ getVisibilityMode(): PersonMode;
31
+ setVisibilityMode(mode: PersonMode): Promise<void>;
32
+ private setVisibilityToMe;
33
+ private setVisibleToWorking;
34
+ private getWorkingPeopleIds;
35
+ private getWorkingPeople;
36
+ protected setVisiblePeopleIds(visible: string[], options?: SetVisiblePeolpeOptions): Promise<void>;
37
+ setPersonVisibility(id: string, shouldBeVisible: boolean): Promise<void>;
38
+ private emitDidUpdate;
39
+ }
40
+ export interface PeopleManagerOptions {
41
+ connectToApi: () => Promise<MercuryClient>;
42
+ preferences: RemotePreferencesStore;
43
+ calendarVc: PeopleManagerCalendarVc;
44
+ getVisibleEvents: () => CalendarEvent[];
45
+ }
46
+ export declare type PeopleManagerCalendarVc = Pick<CalendarViewController, 'addPerson' | 'getPeople' | 'removePerson' | 'setPeople'>;
47
+ declare const peopleContract: {
48
+ eventSignatures: {
49
+ 'did-update': {};
50
+ };
51
+ };
52
+ declare type PeopleContract = typeof peopleContract;
53
+ export interface SetVisiblePeolpeOptions {
54
+ shouldForceEmitDidChange?: boolean;
55
+ }
56
+ export {};
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mercury_event_emitter_1 = require("@sprucelabs/mercury-event-emitter");
7
+ const mercury_types_1 = require("@sprucelabs/mercury-types");
8
+ const schema_1 = require("@sprucelabs/schema");
9
+ const spruce_core_schemas_1 = require("@sprucelabs/spruce-core-schemas");
10
+ const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
11
+ class CalendarPeopleManager extends mercury_event_emitter_1.AbstractEventEmitter {
12
+ constructor(options) {
13
+ super(peopleContract);
14
+ this.team = [];
15
+ const { connectToApi, preferences, getVisibleEvents } = (0, schema_1.assertOptions)(options, ['connectToApi', 'preferences', 'calendarVc', 'getVisibleEvents']);
16
+ this.connectToApi = connectToApi;
17
+ this.prefs = preferences;
18
+ this.getVisibleEvents = getVisibleEvents;
19
+ }
20
+ async load(options) {
21
+ const { loggedInPerson, organizationId, locationId } = options !== null && options !== void 0 ? options : {};
22
+ this.client = await this.connectToApi();
23
+ this.loggedInPerson = loggedInPerson !== null && loggedInPerson !== void 0 ? loggedInPerson : undefined;
24
+ this.organizationId = organizationId;
25
+ this.locationId = locationId;
26
+ await this.loadTeam();
27
+ if (this.getVisiblePeople().length === 0 && this.loggedInPerson) {
28
+ await this.setVisiblePeopleIds([this.loggedInPerson.id]);
29
+ }
30
+ }
31
+ async loadTeam() {
32
+ const [{ people }] = await this.client.emitAndFlattenResponses('list-people::v2020_12_25', {
33
+ target: {
34
+ locationId: this.locationId,
35
+ organizationId: this.organizationId,
36
+ },
37
+ payload: {
38
+ roleBases: spruce_core_schemas_1.EMPLOYED_BASE_ROLES.map((r) => r.slug),
39
+ },
40
+ });
41
+ this.team = people;
42
+ }
43
+ getVisiblePeople() {
44
+ return this.getVisiblePeopleIds()
45
+ .map((i) => {
46
+ try {
47
+ return this.teammateById(i);
48
+ // eslint-disable-next-line no-empty
49
+ }
50
+ catch (_a) { }
51
+ return null;
52
+ })
53
+ .filter((t) => !!t);
54
+ }
55
+ teammateById(id) {
56
+ var _a;
57
+ const teammate = (_a = this.team) === null || _a === void 0 ? void 0 : _a.find((t) => t.id === id);
58
+ if (!teammate) {
59
+ throw new SpruceError_1.default({
60
+ code: 'PERSON_NOT_FOUND',
61
+ personId: id,
62
+ });
63
+ }
64
+ return teammate;
65
+ }
66
+ getTeam() {
67
+ return this.team;
68
+ }
69
+ getLoggedInPerson() {
70
+ return this.loggedInPerson;
71
+ }
72
+ getVisiblePeopleIds() {
73
+ var _a;
74
+ if (this.getVisibilityMode() === 'working') {
75
+ return this.getWorkingPeopleIds();
76
+ }
77
+ return (_a = this.getSavedVisiblePeopleIds()) !== null && _a !== void 0 ? _a : [];
78
+ }
79
+ getSavedVisiblePeopleIds() {
80
+ return this.prefs.getVisiblePeopleIds();
81
+ }
82
+ getVisibilityMode() {
83
+ var _a;
84
+ return (_a = this.prefs.getVisiblePeopleMode()) !== null && _a !== void 0 ? _a : 'me';
85
+ }
86
+ async setVisibilityMode(mode) {
87
+ if (this.getVisibilityMode() === mode) {
88
+ return;
89
+ }
90
+ await this.prefs.setVisiblePeopleMode(mode);
91
+ if (mode === 'me' && this.loggedInPerson) {
92
+ await this.setVisibilityToMe();
93
+ }
94
+ else if (mode === 'working') {
95
+ await this.setVisibleToWorking();
96
+ }
97
+ }
98
+ async setVisibilityToMe() {
99
+ if (this.loggedInPerson) {
100
+ await this.setVisiblePeopleIds([this.loggedInPerson.id], {
101
+ shouldForceEmitDidChange: true,
102
+ });
103
+ }
104
+ }
105
+ async setVisibleToWorking() {
106
+ const ids = this.getWorkingPeopleIds();
107
+ await this.setVisiblePeopleIds(ids);
108
+ }
109
+ getWorkingPeopleIds() {
110
+ return this.getWorkingPeople().map((i) => i.id);
111
+ }
112
+ getWorkingPeople() {
113
+ const events = this.getVisibleEvents();
114
+ let ids = events.map((e) => e.target.personId);
115
+ ids = ids.filter((id, idx) => ids.indexOf(id) === idx);
116
+ return ids
117
+ .map((id) => {
118
+ try {
119
+ return this.teammateById(id);
120
+ // eslint-disable-next-line no-empty
121
+ }
122
+ catch (_a) { }
123
+ return false;
124
+ })
125
+ .filter((p) => !!p);
126
+ }
127
+ async setVisiblePeopleIds(visible, options) {
128
+ var _a;
129
+ const { shouldForceEmitDidChange } = options !== null && options !== void 0 ? options : {};
130
+ const newVisibile = visible.filter((id, idx) => visible.indexOf(id) === idx);
131
+ const oldVisible = (_a = this.getSavedVisiblePeopleIds()) !== null && _a !== void 0 ? _a : [];
132
+ const newKey = newVisibile.join('');
133
+ const oldKey = oldVisible.join('');
134
+ const didChange = newKey !== oldKey;
135
+ if (didChange) {
136
+ await this.prefs.setVisiblePeopleIds(newVisibile);
137
+ }
138
+ if (didChange || shouldForceEmitDidChange) {
139
+ await this.emitDidUpdate();
140
+ }
141
+ }
142
+ async setPersonVisibility(id, shouldBeVisible) {
143
+ const person = this.teammateById(id);
144
+ let selected = [...this.getVisiblePeopleIds()];
145
+ if (shouldBeVisible) {
146
+ selected.push(person.id);
147
+ }
148
+ else {
149
+ selected = selected.filter((i) => i !== id);
150
+ }
151
+ await this.setVisibilityMode('custom');
152
+ await this.setVisiblePeopleIds(selected);
153
+ }
154
+ async emitDidUpdate() {
155
+ await this.emit('did-update');
156
+ }
157
+ }
158
+ exports.default = CalendarPeopleManager;
159
+ const peopleContract = (0, mercury_types_1.buildEventContract)({
160
+ eventSignatures: {
161
+ 'did-update': {},
162
+ },
163
+ });
@@ -0,0 +1,8 @@
1
+ import { SpruceSchemas } from '@sprucelabs/heartwood-view-controllers';
2
+ export declare type CalendarShift = SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarShift;
3
+ import { EventForShift } from '../types/calendar.types';
4
+ declare const calendarShiftGenerator: {
5
+ generateFromEvent(event: EventForShift): CalendarShift[];
6
+ generateFromEvents(events: EventForShift[]): CalendarShift[];
7
+ };
8
+ export default calendarShiftGenerator;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const calendarShiftGenerator = {
4
+ generateFromEvent(event) {
5
+ let time = event.startDateTimeMs;
6
+ return event.timeBlocks.map((timeBlock, idx) => {
7
+ const end = time + timeBlock.durationMinutes * 60 * 1000;
8
+ const shift = {
9
+ id: event.id + '-' + idx,
10
+ startDateTimeMs: time,
11
+ endDateTimeMs: end,
12
+ personId: event.target.personId,
13
+ };
14
+ time = end;
15
+ return shift;
16
+ });
17
+ },
18
+ generateFromEvents(events) {
19
+ const shifts = events.reduce((shifts, event) => {
20
+ shifts.push(...this.generateFromEvent(event));
21
+ return shifts;
22
+ }, []);
23
+ return shifts;
24
+ },
25
+ };
26
+ exports.default = calendarShiftGenerator;
@@ -0,0 +1,28 @@
1
+ import { AbstractViewController, ActiveRecordCardViewController, Scope, SpruceSchemas, ViewControllerOptions } from '@sprucelabs/heartwood-view-controllers';
2
+ import { CalendarEventManager } from '../utilities/CalendarEventManager';
3
+ export default class CalendarSelectCardViewController extends AbstractViewController<Card> {
4
+ static id: string;
5
+ private isLoaded;
6
+ private activeVc;
7
+ private events;
8
+ private selectedCalendarIds;
9
+ private changePromise?;
10
+ constructor(options: ViewControllerOptions & CalendarSelectCardOptions);
11
+ private CalendarListVc;
12
+ private renderCalendarRow;
13
+ waitForChanges(): Promise<void>;
14
+ getActiveRecordCardVc(): ActiveRecordCardViewController;
15
+ getListVc(): import("@sprucelabs/heartwood-view-controllers").ListViewController;
16
+ getIsLoaded(): boolean;
17
+ getSelectedCalendarIds(): string[];
18
+ load(options: {
19
+ scope: Scope;
20
+ }): Promise<void>;
21
+ render(): SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
22
+ }
23
+ declare type Card = SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
24
+ export declare type CalendarVisibilityToggleHandler = (calendarId: string, isVisible: boolean) => any;
25
+ export interface CalendarSelectCardOptions {
26
+ events: CalendarEventManager;
27
+ }
28
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const heartwood_view_controllers_1 = require("@sprucelabs/heartwood-view-controllers");
4
+ const schema_1 = require("@sprucelabs/schema");
5
+ class CalendarSelectCardViewController extends heartwood_view_controllers_1.AbstractViewController {
6
+ constructor(options) {
7
+ super(options);
8
+ this.isLoaded = false;
9
+ this.selectedCalendarIds = [];
10
+ const { events } = (0, schema_1.assertOptions)(options, ['events']);
11
+ this.events = events;
12
+ this.selectedCalendarIds = this.events.getVisibleCalendarIds();
13
+ this.activeVc = this.CalendarListVc();
14
+ }
15
+ CalendarListVc() {
16
+ return this.Controller('activeRecordCard', (0, heartwood_view_controllers_1.buildActiveRecordCard)({
17
+ shouldRenderRowDividers: true,
18
+ columnWidths: ['fill'],
19
+ header: {
20
+ title: 'Calendars',
21
+ },
22
+ noResultsRow: {
23
+ cells: [
24
+ {
25
+ text: { content: "You don't have any calendars yet!" },
26
+ },
27
+ ],
28
+ },
29
+ eventName: 'calendar.list-calendars::v2021_05_19',
30
+ rowTransformer: this.renderCalendarRow.bind(this),
31
+ responseKey: 'calendars',
32
+ }));
33
+ }
34
+ renderCalendarRow(calendar) {
35
+ return {
36
+ id: calendar.id,
37
+ cells: [
38
+ {
39
+ text: { content: calendar.title },
40
+ },
41
+ {
42
+ toggleInput: {
43
+ name: 'isVisible',
44
+ value: this.selectedCalendarIds.indexOf(calendar.id) > -1,
45
+ onChange: async (isVisible) => {
46
+ this.changePromise = this.events.setCalendarVisibility(calendar.id, isVisible);
47
+ return this.changePromise;
48
+ },
49
+ },
50
+ },
51
+ ],
52
+ };
53
+ }
54
+ async waitForChanges() {
55
+ await this.changePromise;
56
+ }
57
+ getActiveRecordCardVc() {
58
+ return this.activeVc;
59
+ }
60
+ getListVc() {
61
+ return this.activeVc.getListVc();
62
+ }
63
+ getIsLoaded() {
64
+ return this.isLoaded;
65
+ }
66
+ getSelectedCalendarIds() {
67
+ const records = this.activeVc.getRecords();
68
+ const ids = [];
69
+ for (const calendar of records) {
70
+ if (this.getListVc().getRowVc(calendar.id).getValue('isVisible')) {
71
+ ids.push(calendar.id);
72
+ }
73
+ }
74
+ return ids;
75
+ }
76
+ async load(options) {
77
+ (0, schema_1.assertOptions)(options, ['scope']);
78
+ const { scope } = options;
79
+ const org = await scope.getCurrentOrganization();
80
+ if (org) {
81
+ this.activeVc.setTarget({
82
+ organizationId: org === null || org === void 0 ? void 0 : org.id,
83
+ });
84
+ }
85
+ await this.activeVc.load();
86
+ this.isLoaded = true;
87
+ }
88
+ render() {
89
+ return this.activeVc.render();
90
+ }
91
+ }
92
+ exports.default = CalendarSelectCardViewController;
93
+ CalendarSelectCardViewController.id = 'calendar-select-tool';
@@ -0,0 +1,29 @@
1
+ import { AbstractViewController, CalendarViewController, SpruceSchemas, ViewControllerOptions } from '@sprucelabs/heartwood-view-controllers';
2
+ declare type Card = SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
3
+ declare type DateSelectHandler = (dateTimeMs: number) => void | Promise<void>;
4
+ export interface DateSelectOptions {
5
+ onSelectDate: DateSelectHandler;
6
+ startDate: number;
7
+ selectedDate?: {
8
+ year: number;
9
+ month: number;
10
+ day: number;
11
+ };
12
+ }
13
+ export default class DateSelectCardViewController extends AbstractViewController<Card> {
14
+ static id: string;
15
+ private cardVc;
16
+ private calendarVc;
17
+ private dateSelectHandler;
18
+ constructor(options: ViewControllerOptions & DateSelectOptions);
19
+ getStartDate(): number | null | undefined;
20
+ setStartDate(startDate: number): void;
21
+ private CalendarVc;
22
+ private handleDateSelect;
23
+ private CardVc;
24
+ setSelectedDate(year: number, month: number, day: number): void;
25
+ getSelectedDate(): SpruceSchemas.HeartwoodViewControllers.v2021_02_11.CalendarSelectedDate;
26
+ getCalendarVc(): CalendarViewController;
27
+ render(): SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
28
+ }
29
+ export {};