@sprucelabs/spruce-people-utils 0.9.3 → 1.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.
@@ -1,4 +1,14 @@
1
- export { default as PersonSelectInput } from './viewControllers/PersonSelectInput.vc';
1
+ import PersonSelectInputViewController from './viewControllers/PersonSelectInput.vc';
2
+ export { default as PersonSelectInputViewController } from './viewControllers/PersonSelectInput.vc';
2
3
  export * from './viewControllers/PersonSelectInput.vc';
3
4
  export { default as SpyPersonSelectInput } from './__tests__/behavioral/searching/SpyPersonSelectInput';
4
5
  export { default as SpyPersonInviteViewController } from './__tests__/behavioral/inviting/SpyPersonInviteViewController';
6
+ export { default as InvitePersonCardViewController } from './inviting/InvitePersonCard.vc';
7
+ declare module '@sprucelabs/heartwood-view-controllers/build/types/heartwood.types' {
8
+ interface ViewControllerMap {
9
+ 'people.person-select-input': PersonSelectInputViewController;
10
+ }
11
+ interface ViewControllerOptionsMap {
12
+ 'people.person-select-input': ConstructorParameters<typeof PersonSelectInputViewController>[0];
13
+ }
14
+ }
@@ -1,4 +1,5 @@
1
- export { default as PersonSelectInput } from './viewControllers/PersonSelectInput.vc.js';
1
+ export { default as PersonSelectInputViewController } from './viewControllers/PersonSelectInput.vc.js';
2
2
  export * from './viewControllers/PersonSelectInput.vc.js';
3
3
  export { default as SpyPersonSelectInput } from './__tests__/behavioral/searching/SpyPersonSelectInput.js';
4
4
  export { default as SpyPersonInviteViewController } from './__tests__/behavioral/inviting/SpyPersonInviteViewController.js';
5
+ export { default as InvitePersonCardViewController } from './inviting/InvitePersonCard.vc.js';
@@ -0,0 +1,56 @@
1
+ import { AbstractViewController, FormViewController, ViewControllerOptions, SwipeCardViewController, TalkingSprucebotViewController, SpruceSchemas, Card } from '@sprucelabs/heartwood-view-controllers';
2
+ import { SendInvite } from '../types/people-module.types';
3
+ export default class InvitePersonCardViewController extends AbstractViewController<Card> {
4
+ static id: string;
5
+ protected cardVc: SwipeCardViewController;
6
+ protected organizationId: string;
7
+ protected locationId?: string;
8
+ protected formVc: FormViewController<InviteFormSchema>;
9
+ protected talkingVc: TalkingSprucebotViewController;
10
+ protected pendingInvite?: SendInvite;
11
+ private isLoaded;
12
+ private doneHandler?;
13
+ private client;
14
+ private invitedPersonId?;
15
+ constructor(options: ViewControllerOptions & InvitePersonOptions);
16
+ private TalkingVc;
17
+ private CardVc;
18
+ private handleSlideChange;
19
+ private updateTalkingSprucebot;
20
+ private updateFooter;
21
+ private handleClickDone;
22
+ private handleClickBack;
23
+ private updateHeader;
24
+ private get slideIdx();
25
+ private FormVc;
26
+ destroy(): Promise<void>;
27
+ private handleSubmitNamePhoneForm;
28
+ getIsLoaded(): boolean;
29
+ load(): Promise<void>;
30
+ private _handleDidAcceptInvite;
31
+ private handleDidAcceptInvite;
32
+ render(): SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
33
+ }
34
+ export declare type DoneHandler = (personId: string) => void | Promise<void>;
35
+ export interface InvitePersonOptions {
36
+ organizationId?: string;
37
+ locationId?: string;
38
+ onDone?: DoneHandler;
39
+ }
40
+ declare const inviteFormSchema: {
41
+ id: string;
42
+ fields: {
43
+ firstName: {
44
+ type: "text";
45
+ };
46
+ lastName: {
47
+ type: "text";
48
+ };
49
+ phone: {
50
+ type: "phone";
51
+ isRequired: true;
52
+ };
53
+ };
54
+ };
55
+ declare type InviteFormSchema = typeof inviteFormSchema;
56
+ export {};
@@ -0,0 +1,222 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { AbstractViewController, buildForm, } from '@sprucelabs/heartwood-view-controllers';
11
+ import { assertOptions, buildSchema } from '@sprucelabs/schema';
12
+ import { inviteCardHeaders } from './inviteCardHeaders.js';
13
+ export default class InvitePersonCardViewController extends AbstractViewController {
14
+ constructor(options) {
15
+ super(options);
16
+ this.isLoaded = false;
17
+ const required = [];
18
+ if (!options.locationId) {
19
+ required.push('organizationId');
20
+ }
21
+ if (!options.organizationId) {
22
+ required.push('locationId');
23
+ }
24
+ const { organizationId, locationId, onDone } = assertOptions(options, required);
25
+ this.organizationId = organizationId;
26
+ this.locationId = locationId;
27
+ this.talkingVc = this.TalkingVc();
28
+ this.formVc = this.FormVc();
29
+ this.cardVc = this.CardVc();
30
+ this.doneHandler = onDone;
31
+ this._handleDidAcceptInvite = this._handleDidAcceptInvite.bind(this);
32
+ }
33
+ TalkingVc() {
34
+ return this.Controller('talkingSprucebot', {
35
+ id: 'wait',
36
+ avatar: {
37
+ size: 'medium',
38
+ stateOfMind: 'chill',
39
+ },
40
+ isPlaying: false,
41
+ sentences: [
42
+ {
43
+ words: 'Ready when you are!',
44
+ },
45
+ ],
46
+ });
47
+ }
48
+ CardVc() {
49
+ return this.Controller('swipeCard', {
50
+ header: {
51
+ title: 'Invite a person!',
52
+ },
53
+ isBusy: true,
54
+ onSlideChange: this.handleSlideChange.bind(this),
55
+ slides: [
56
+ {
57
+ form: this.formVc.render(),
58
+ },
59
+ {
60
+ talkingSprucebot: this.talkingVc.render(),
61
+ },
62
+ ],
63
+ });
64
+ }
65
+ handleSlideChange() {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ this.updateHeader();
68
+ this.updateFooter();
69
+ yield this.updateTalkingSprucebot();
70
+ });
71
+ }
72
+ updateTalkingSprucebot() {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const name = this.formVc.getValue('firstName');
75
+ switch (this.slideIdx) {
76
+ case 1:
77
+ this.talkingVc.setSentences([
78
+ {
79
+ words: `Tell ${name} to check their phone and to click the link I just sent!`,
80
+ },
81
+ ]);
82
+ yield this.talkingVc.play();
83
+ break;
84
+ default:
85
+ this.talkingVc.pause();
86
+ }
87
+ });
88
+ }
89
+ updateFooter() {
90
+ if (this.slideIdx > 0) {
91
+ this.cardVc.setFooter({
92
+ buttons: [
93
+ {
94
+ id: this.slideIdx === 2 ? 'done' : 'back',
95
+ label: this.slideIdx === 2 ? 'Done' : 'Back',
96
+ onClick: this.slideIdx === 2
97
+ ? this.handleClickDone.bind(this)
98
+ : this.handleClickBack.bind(this),
99
+ },
100
+ ],
101
+ });
102
+ }
103
+ else {
104
+ this.cardVc.setFooter(null);
105
+ }
106
+ }
107
+ handleClickDone() {
108
+ var _a;
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ yield ((_a = this.doneHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.invitedPersonId));
111
+ });
112
+ }
113
+ handleClickBack() {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ this.pendingInvite = undefined;
116
+ yield this.cardVc.jumpToSlide(0);
117
+ });
118
+ }
119
+ updateHeader() {
120
+ var _a, _b;
121
+ const header = inviteCardHeaders[this.slideIdx];
122
+ this.cardVc.setHeaderTitle((_a = header.title) !== null && _a !== void 0 ? _a : null);
123
+ this.cardVc.setHeaderSubtitle((_b = header.subtitle) !== null && _b !== void 0 ? _b : null);
124
+ }
125
+ get slideIdx() {
126
+ return this.cardVc.getPresentSlide();
127
+ }
128
+ FormVc() {
129
+ return this.Controller('form', buildForm({
130
+ schema: inviteFormSchema,
131
+ shouldShowCancelButton: false,
132
+ onSubmit: this.handleSubmitNamePhoneForm.bind(this),
133
+ sections: [
134
+ {
135
+ fields: ['firstName', 'lastName', 'phone'],
136
+ },
137
+ ],
138
+ }));
139
+ }
140
+ destroy() {
141
+ const _super = Object.create(null, {
142
+ destroy: { get: () => super.destroy }
143
+ });
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ yield this.client.off('invite.did-accept::v2021_12_16', this._handleDidAcceptInvite);
146
+ return _super.destroy.call(this);
147
+ });
148
+ }
149
+ handleSubmitNamePhoneForm() {
150
+ return __awaiter(this, void 0, void 0, function* () {
151
+ this.cardVc.setIsBusy(true);
152
+ yield this.cardVc.jumpToSlide(1);
153
+ try {
154
+ const client = yield this.connectToApi();
155
+ const [{ invite }] = yield client.emitAndFlattenResponses('invite.send::v2021_12_16', {
156
+ target: {
157
+ phone: this.formVc.getValue('phone'),
158
+ inviteOrganizationId: this.organizationId,
159
+ inviteLocationId: this.locationId,
160
+ },
161
+ payload: {
162
+ firstName: this.formVc.getValue('firstName'),
163
+ destination: {
164
+ id: 'heartwood.root',
165
+ },
166
+ message: 'approve your account',
167
+ },
168
+ });
169
+ this.pendingInvite = invite;
170
+ }
171
+ catch (err) {
172
+ yield this.alert({ title: 'Invite failed!', message: err.message });
173
+ yield this.cardVc.jumpToSlide(0);
174
+ }
175
+ this.cardVc.setIsBusy(false);
176
+ });
177
+ }
178
+ getIsLoaded() {
179
+ return this.isLoaded;
180
+ }
181
+ load() {
182
+ return __awaiter(this, void 0, void 0, function* () {
183
+ this.isLoaded = true;
184
+ this.cardVc.setIsBusy(false);
185
+ this.client = yield this.connectToApi();
186
+ yield this.client.on('invite.did-accept::v2021_12_16', this._handleDidAcceptInvite);
187
+ });
188
+ }
189
+ _handleDidAcceptInvite({ payload, }) {
190
+ return __awaiter(this, void 0, void 0, function* () {
191
+ return this.handleDidAcceptInvite(payload.inviteId, payload.personId);
192
+ });
193
+ }
194
+ handleDidAcceptInvite(inviteId, personId) {
195
+ var _a;
196
+ return __awaiter(this, void 0, void 0, function* () {
197
+ if (((_a = this.pendingInvite) === null || _a === void 0 ? void 0 : _a.id) === inviteId) {
198
+ yield this.cardVc.jumpToSlide(2);
199
+ this.invitedPersonId = personId;
200
+ }
201
+ });
202
+ }
203
+ render() {
204
+ return this.cardVc.render();
205
+ }
206
+ }
207
+ InvitePersonCardViewController.id = 'invite-person-card';
208
+ const inviteFormSchema = buildSchema({
209
+ id: 'inviteForm',
210
+ fields: {
211
+ firstName: {
212
+ type: 'text',
213
+ },
214
+ lastName: {
215
+ type: 'text',
216
+ },
217
+ phone: {
218
+ type: 'phone',
219
+ isRequired: true,
220
+ },
221
+ },
222
+ });
@@ -0,0 +1,2 @@
1
+ import { CardHeader } from '@sprucelabs/heartwood-view-controllers';
2
+ export declare const inviteCardHeaders: CardHeader[];
@@ -0,0 +1,13 @@
1
+ export const inviteCardHeaders = [
2
+ {
3
+ title: 'Invite a person!',
4
+ },
5
+ {
6
+ title: 'Invite sent',
7
+ subtitle: 'Hang tight until the invite is accepted!',
8
+ },
9
+ {
10
+ title: 'All done!',
11
+ subtitle: 'You are good to go!',
12
+ },
13
+ ];
@@ -0,0 +1,22 @@
1
+ export interface SearchPerson {
2
+ id: string;
3
+ fullName: string;
4
+ phone: string;
5
+ }
6
+ export interface SendInvite {
7
+ id: string;
8
+ dateCreated: number;
9
+ status: 'pending' | 'accepted';
10
+ firstName?: string | undefined | null;
11
+ destination: Destination;
12
+ viewContext: ViewContext;
13
+ message: string;
14
+ introduction?: string | undefined | null;
15
+ }
16
+ export interface Destination {
17
+ id: string;
18
+ args?: Record<string, any> | undefined | null;
19
+ }
20
+ export interface ViewContext {
21
+ roleName?: string | undefined | null;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -11,7 +11,7 @@ export default class PersonSelectInputViewController extends AbstractInputViewCo
11
11
  private populateSuggestions;
12
12
  private handleClickInviteAnonymous;
13
13
  private handleClickInvitePerson;
14
- protected InvitePersonVc(): import("../inviting/InvitePersonCard.vc").default;
14
+ protected InvitePersonVc(): import("../index-module").InvitePersonCardViewController;
15
15
  private search;
16
16
  private handleClickSuggestion;
17
17
  setOrganizationId(orgId: string): void;
@@ -0,0 +1,4 @@
1
+ import { AutocompleteSuggestion } from '@sprucelabs/heartwood-view-controllers';
2
+ import { SearchPerson } from '../types/people-module.types';
3
+ export default function searchPeopleToSuggestions(people: SearchPerson[], cb?: (person: SearchPerson) => Promise<void> | void): AutocompleteSuggestion[];
4
+ export declare function renderLabel(p: SearchPerson): string;
@@ -0,0 +1,10 @@
1
+ export default function searchPeopleToSuggestions(people, cb) {
2
+ return people.map((p) => ({
3
+ id: p.id,
4
+ label: renderLabel(p),
5
+ onClick: () => cb === null || cb === void 0 ? void 0 : cb(p),
6
+ }));
7
+ }
8
+ export function renderLabel(p) {
9
+ return `${p.fullName} (${p.phone})`;
10
+ }
@@ -1,4 +1,14 @@
1
- export { default as PersonSelectInput } from './viewControllers/PersonSelectInput.vc';
1
+ import PersonSelectInputViewController from './viewControllers/PersonSelectInput.vc';
2
+ export { default as PersonSelectInputViewController } from './viewControllers/PersonSelectInput.vc';
2
3
  export * from './viewControllers/PersonSelectInput.vc';
3
4
  export { default as SpyPersonSelectInput } from './__tests__/behavioral/searching/SpyPersonSelectInput';
4
5
  export { default as SpyPersonInviteViewController } from './__tests__/behavioral/inviting/SpyPersonInviteViewController';
6
+ export { default as InvitePersonCardViewController } from './inviting/InvitePersonCard.vc';
7
+ declare module '@sprucelabs/heartwood-view-controllers/build/types/heartwood.types' {
8
+ interface ViewControllerMap {
9
+ 'people.person-select-input': PersonSelectInputViewController;
10
+ }
11
+ interface ViewControllerOptionsMap {
12
+ 'people.person-select-input': ConstructorParameters<typeof PersonSelectInputViewController>[0];
13
+ }
14
+ }
@@ -17,11 +17,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.SpyPersonInviteViewController = exports.SpyPersonSelectInput = exports.PersonSelectInput = void 0;
20
+ exports.InvitePersonCardViewController = exports.SpyPersonInviteViewController = exports.SpyPersonSelectInput = exports.PersonSelectInputViewController = void 0;
21
21
  var PersonSelectInput_vc_1 = require("./viewControllers/PersonSelectInput.vc");
22
- Object.defineProperty(exports, "PersonSelectInput", { enumerable: true, get: function () { return __importDefault(PersonSelectInput_vc_1).default; } });
22
+ Object.defineProperty(exports, "PersonSelectInputViewController", { enumerable: true, get: function () { return __importDefault(PersonSelectInput_vc_1).default; } });
23
23
  __exportStar(require("./viewControllers/PersonSelectInput.vc"), exports);
24
24
  var SpyPersonSelectInput_1 = require("./__tests__/behavioral/searching/SpyPersonSelectInput");
25
25
  Object.defineProperty(exports, "SpyPersonSelectInput", { enumerable: true, get: function () { return __importDefault(SpyPersonSelectInput_1).default; } });
26
26
  var SpyPersonInviteViewController_1 = require("./__tests__/behavioral/inviting/SpyPersonInviteViewController");
27
27
  Object.defineProperty(exports, "SpyPersonInviteViewController", { enumerable: true, get: function () { return __importDefault(SpyPersonInviteViewController_1).default; } });
28
+ var InvitePersonCard_vc_1 = require("./inviting/InvitePersonCard.vc");
29
+ Object.defineProperty(exports, "InvitePersonCardViewController", { enumerable: true, get: function () { return __importDefault(InvitePersonCard_vc_1).default; } });
@@ -0,0 +1,56 @@
1
+ import { AbstractViewController, FormViewController, ViewControllerOptions, SwipeCardViewController, TalkingSprucebotViewController, SpruceSchemas, Card } from '@sprucelabs/heartwood-view-controllers';
2
+ import { SendInvite } from '../types/people-module.types';
3
+ export default class InvitePersonCardViewController extends AbstractViewController<Card> {
4
+ static id: string;
5
+ protected cardVc: SwipeCardViewController;
6
+ protected organizationId: string;
7
+ protected locationId?: string;
8
+ protected formVc: FormViewController<InviteFormSchema>;
9
+ protected talkingVc: TalkingSprucebotViewController;
10
+ protected pendingInvite?: SendInvite;
11
+ private isLoaded;
12
+ private doneHandler?;
13
+ private client;
14
+ private invitedPersonId?;
15
+ constructor(options: ViewControllerOptions & InvitePersonOptions);
16
+ private TalkingVc;
17
+ private CardVc;
18
+ private handleSlideChange;
19
+ private updateTalkingSprucebot;
20
+ private updateFooter;
21
+ private handleClickDone;
22
+ private handleClickBack;
23
+ private updateHeader;
24
+ private get slideIdx();
25
+ private FormVc;
26
+ destroy(): Promise<void>;
27
+ private handleSubmitNamePhoneForm;
28
+ getIsLoaded(): boolean;
29
+ load(): Promise<void>;
30
+ private _handleDidAcceptInvite;
31
+ private handleDidAcceptInvite;
32
+ render(): SpruceSchemas.HeartwoodViewControllers.v2021_02_11.Card;
33
+ }
34
+ export declare type DoneHandler = (personId: string) => void | Promise<void>;
35
+ export interface InvitePersonOptions {
36
+ organizationId?: string;
37
+ locationId?: string;
38
+ onDone?: DoneHandler;
39
+ }
40
+ declare const inviteFormSchema: {
41
+ id: string;
42
+ fields: {
43
+ firstName: {
44
+ type: "text";
45
+ };
46
+ lastName: {
47
+ type: "text";
48
+ };
49
+ phone: {
50
+ type: "phone";
51
+ isRequired: true;
52
+ };
53
+ };
54
+ };
55
+ declare type InviteFormSchema = typeof inviteFormSchema;
56
+ export {};
@@ -0,0 +1,195 @@
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
+ const inviteCardHeaders_1 = require("./inviteCardHeaders");
6
+ class InvitePersonCardViewController extends heartwood_view_controllers_1.AbstractViewController {
7
+ constructor(options) {
8
+ super(options);
9
+ this.isLoaded = false;
10
+ const required = [];
11
+ if (!options.locationId) {
12
+ required.push('organizationId');
13
+ }
14
+ if (!options.organizationId) {
15
+ required.push('locationId');
16
+ }
17
+ const { organizationId, locationId, onDone } = (0, schema_1.assertOptions)(options, required);
18
+ this.organizationId = organizationId;
19
+ this.locationId = locationId;
20
+ this.talkingVc = this.TalkingVc();
21
+ this.formVc = this.FormVc();
22
+ this.cardVc = this.CardVc();
23
+ this.doneHandler = onDone;
24
+ this._handleDidAcceptInvite = this._handleDidAcceptInvite.bind(this);
25
+ }
26
+ TalkingVc() {
27
+ return this.Controller('talkingSprucebot', {
28
+ id: 'wait',
29
+ avatar: {
30
+ size: 'medium',
31
+ stateOfMind: 'chill',
32
+ },
33
+ isPlaying: false,
34
+ sentences: [
35
+ {
36
+ words: 'Ready when you are!',
37
+ },
38
+ ],
39
+ });
40
+ }
41
+ CardVc() {
42
+ return this.Controller('swipeCard', {
43
+ header: {
44
+ title: 'Invite a person!',
45
+ },
46
+ isBusy: true,
47
+ onSlideChange: this.handleSlideChange.bind(this),
48
+ slides: [
49
+ {
50
+ form: this.formVc.render(),
51
+ },
52
+ {
53
+ talkingSprucebot: this.talkingVc.render(),
54
+ },
55
+ ],
56
+ });
57
+ }
58
+ async handleSlideChange() {
59
+ this.updateHeader();
60
+ this.updateFooter();
61
+ await this.updateTalkingSprucebot();
62
+ }
63
+ async updateTalkingSprucebot() {
64
+ const name = this.formVc.getValue('firstName');
65
+ switch (this.slideIdx) {
66
+ case 1:
67
+ this.talkingVc.setSentences([
68
+ {
69
+ words: `Tell ${name} to check their phone and to click the link I just sent!`,
70
+ },
71
+ ]);
72
+ await this.talkingVc.play();
73
+ break;
74
+ default:
75
+ this.talkingVc.pause();
76
+ }
77
+ }
78
+ updateFooter() {
79
+ if (this.slideIdx > 0) {
80
+ this.cardVc.setFooter({
81
+ buttons: [
82
+ {
83
+ id: this.slideIdx === 2 ? 'done' : 'back',
84
+ label: this.slideIdx === 2 ? 'Done' : 'Back',
85
+ onClick: this.slideIdx === 2
86
+ ? this.handleClickDone.bind(this)
87
+ : this.handleClickBack.bind(this),
88
+ },
89
+ ],
90
+ });
91
+ }
92
+ else {
93
+ this.cardVc.setFooter(null);
94
+ }
95
+ }
96
+ async handleClickDone() {
97
+ var _a;
98
+ await ((_a = this.doneHandler) === null || _a === void 0 ? void 0 : _a.call(this, this.invitedPersonId));
99
+ }
100
+ async handleClickBack() {
101
+ this.pendingInvite = undefined;
102
+ await this.cardVc.jumpToSlide(0);
103
+ }
104
+ updateHeader() {
105
+ var _a, _b;
106
+ const header = inviteCardHeaders_1.inviteCardHeaders[this.slideIdx];
107
+ this.cardVc.setHeaderTitle((_a = header.title) !== null && _a !== void 0 ? _a : null);
108
+ this.cardVc.setHeaderSubtitle((_b = header.subtitle) !== null && _b !== void 0 ? _b : null);
109
+ }
110
+ get slideIdx() {
111
+ return this.cardVc.getPresentSlide();
112
+ }
113
+ FormVc() {
114
+ return this.Controller('form', (0, heartwood_view_controllers_1.buildForm)({
115
+ schema: inviteFormSchema,
116
+ shouldShowCancelButton: false,
117
+ onSubmit: this.handleSubmitNamePhoneForm.bind(this),
118
+ sections: [
119
+ {
120
+ fields: ['firstName', 'lastName', 'phone'],
121
+ },
122
+ ],
123
+ }));
124
+ }
125
+ async destroy() {
126
+ await this.client.off('invite.did-accept::v2021_12_16', this._handleDidAcceptInvite);
127
+ return super.destroy();
128
+ }
129
+ async handleSubmitNamePhoneForm() {
130
+ this.cardVc.setIsBusy(true);
131
+ await this.cardVc.jumpToSlide(1);
132
+ try {
133
+ const client = await this.connectToApi();
134
+ const [{ invite }] = await client.emitAndFlattenResponses('invite.send::v2021_12_16', {
135
+ target: {
136
+ phone: this.formVc.getValue('phone'),
137
+ inviteOrganizationId: this.organizationId,
138
+ inviteLocationId: this.locationId,
139
+ },
140
+ payload: {
141
+ firstName: this.formVc.getValue('firstName'),
142
+ destination: {
143
+ id: 'heartwood.root',
144
+ },
145
+ message: 'approve your account',
146
+ },
147
+ });
148
+ this.pendingInvite = invite;
149
+ }
150
+ catch (err) {
151
+ await this.alert({ title: 'Invite failed!', message: err.message });
152
+ await this.cardVc.jumpToSlide(0);
153
+ }
154
+ this.cardVc.setIsBusy(false);
155
+ }
156
+ getIsLoaded() {
157
+ return this.isLoaded;
158
+ }
159
+ async load() {
160
+ this.isLoaded = true;
161
+ this.cardVc.setIsBusy(false);
162
+ this.client = await this.connectToApi();
163
+ await this.client.on('invite.did-accept::v2021_12_16', this._handleDidAcceptInvite);
164
+ }
165
+ async _handleDidAcceptInvite({ payload, }) {
166
+ return this.handleDidAcceptInvite(payload.inviteId, payload.personId);
167
+ }
168
+ async handleDidAcceptInvite(inviteId, personId) {
169
+ var _a;
170
+ if (((_a = this.pendingInvite) === null || _a === void 0 ? void 0 : _a.id) === inviteId) {
171
+ await this.cardVc.jumpToSlide(2);
172
+ this.invitedPersonId = personId;
173
+ }
174
+ }
175
+ render() {
176
+ return this.cardVc.render();
177
+ }
178
+ }
179
+ exports.default = InvitePersonCardViewController;
180
+ InvitePersonCardViewController.id = 'invite-person-card';
181
+ const inviteFormSchema = (0, schema_1.buildSchema)({
182
+ id: 'inviteForm',
183
+ fields: {
184
+ firstName: {
185
+ type: 'text',
186
+ },
187
+ lastName: {
188
+ type: 'text',
189
+ },
190
+ phone: {
191
+ type: 'phone',
192
+ isRequired: true,
193
+ },
194
+ },
195
+ });
@@ -0,0 +1,2 @@
1
+ import { CardHeader } from '@sprucelabs/heartwood-view-controllers';
2
+ export declare const inviteCardHeaders: CardHeader[];
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inviteCardHeaders = void 0;
4
+ exports.inviteCardHeaders = [
5
+ {
6
+ title: 'Invite a person!',
7
+ },
8
+ {
9
+ title: 'Invite sent',
10
+ subtitle: 'Hang tight until the invite is accepted!',
11
+ },
12
+ {
13
+ title: 'All done!',
14
+ subtitle: 'You are good to go!',
15
+ },
16
+ ];
@@ -0,0 +1,22 @@
1
+ export interface SearchPerson {
2
+ id: string;
3
+ fullName: string;
4
+ phone: string;
5
+ }
6
+ export interface SendInvite {
7
+ id: string;
8
+ dateCreated: number;
9
+ status: 'pending' | 'accepted';
10
+ firstName?: string | undefined | null;
11
+ destination: Destination;
12
+ viewContext: ViewContext;
13
+ message: string;
14
+ introduction?: string | undefined | null;
15
+ }
16
+ export interface Destination {
17
+ id: string;
18
+ args?: Record<string, any> | undefined | null;
19
+ }
20
+ export interface ViewContext {
21
+ roleName?: string | undefined | null;
22
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -11,7 +11,7 @@ export default class PersonSelectInputViewController extends AbstractInputViewCo
11
11
  private populateSuggestions;
12
12
  private handleClickInviteAnonymous;
13
13
  private handleClickInvitePerson;
14
- protected InvitePersonVc(): import("../inviting/InvitePersonCard.vc").default;
14
+ protected InvitePersonVc(): import("../index-module").InvitePersonCardViewController;
15
15
  private search;
16
16
  private handleClickSuggestion;
17
17
  setOrganizationId(orgId: string): void;
@@ -0,0 +1,4 @@
1
+ import { AutocompleteSuggestion } from '@sprucelabs/heartwood-view-controllers';
2
+ import { SearchPerson } from '../types/people-module.types';
3
+ export default function searchPeopleToSuggestions(people: SearchPerson[], cb?: (person: SearchPerson) => Promise<void> | void): AutocompleteSuggestion[];
4
+ export declare function renderLabel(p: SearchPerson): string;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderLabel = void 0;
4
+ function searchPeopleToSuggestions(people, cb) {
5
+ return people.map((p) => ({
6
+ id: p.id,
7
+ label: renderLabel(p),
8
+ onClick: () => cb === null || cb === void 0 ? void 0 : cb(p),
9
+ }));
10
+ }
11
+ exports.default = searchPeopleToSuggestions;
12
+ function renderLabel(p) {
13
+ return `${p.fullName} (${p.phone})`;
14
+ }
15
+ exports.renderLabel = renderLabel;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sprucelabs/spruce-people-utils",
3
3
  "description": "People Utilities",
4
- "version": "0.9.3",
4
+ "version": "1.0.4",
5
5
  "skill": {
6
6
  "namespace": "invite"
7
7
  },
@@ -20,14 +20,30 @@
20
20
  "build/esm/index-module.d.ts",
21
21
  "build/viewControllers/PersonSelectInput.vc.js",
22
22
  "build/viewControllers/PersonSelectInput.vc.d.ts",
23
- "build/__tests__/behavioral/searching/SpyPersonSelectInput.js",
24
- "build/__tests__/behavioral/searching/SpyPersonSelectInput.d.ts",
25
- "build/__tests__/behavioral/inviting/SpyPersonInviteViewController.js",
26
- "build/__tests__/behavioral/inviting/SpyPersonInviteViewController.d.ts",
27
23
  "build/esm/viewControllers/PersonSelectInput.vc.js",
28
24
  "build/esm/viewControllers/PersonSelectInput.vc.d.ts",
25
+ "build/viewControllers/searchPeopleToSuggestions.js",
26
+ "build/viewControllers/searchPeopleToSuggestions.d.ts",
27
+ "build/esm/viewControllers/searchPeopleToSuggestions.js",
28
+ "build/esm/viewControllers/searchPeopleToSuggestions.d.ts",
29
+ "build/inviting/InvitePersonCard.vc.js",
30
+ "build/inviting/InvitePersonCard.vc.d.ts",
31
+ "build/esm/inviting/InvitePersonCard.vc.js",
32
+ "build/esm/inviting/InvitePersonCard.vc.d.ts",
33
+ "build/inviting/inviteCardHeaders.js",
34
+ "build/inviting/inviteCardHeaders.d.ts",
35
+ "build/esm/inviting/inviteCardHeaders.js",
36
+ "build/esm/inviting/inviteCardHeaders.d.ts",
37
+ "build/types/people-module.types.js",
38
+ "build/types/people-module.types.d.ts",
39
+ "build/esm/types/people-module.types.js",
40
+ "build/esm/types/people-module.types.d.ts",
41
+ "build/__tests__/behavioral/searching/SpyPersonSelectInput.js",
42
+ "build/__tests__/behavioral/searching/SpyPersonSelectInput.d.ts",
29
43
  "build/esm/__tests__/behavioral/searching/SpyPersonSelectInput.js",
30
44
  "build/esm/__tests__/behavioral/searching/SpyPersonSelectInput.d.ts",
45
+ "build/__tests__/behavioral/inviting/SpyPersonInviteViewController.js",
46
+ "build/__tests__/behavioral/inviting/SpyPersonInviteViewController.d.ts",
31
47
  "build/esm/__tests__/behavioral/inviting/SpyPersonInviteViewController.js",
32
48
  "build/esm/__tests__/behavioral/inviting/SpyPersonInviteViewController.d.ts"
33
49
  ],