@meetelise/chat 1.20.57 → 1.20.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/dist/index.js +147 -147
- package/src/MEChat.ts +2 -2
- package/src/WebComponent/Scheduler/tour-scheduler.ts +5 -5
- package/src/WebComponent/actions/email-us-window.ts +2 -2
- package/src/WebComponent/actions/formatPhoneNumber.ts +15 -1
- package/src/WebComponent/actions/text-us-window.ts +2 -2
- package/src/WebComponent/launcherStyles.ts +1 -0
- package/src/WebComponent/me-chat.ts +76 -49
- package/src/fetchPhoneNumberFromSource.ts +31 -0
package/src/MEChat.ts
CHANGED
|
@@ -43,8 +43,8 @@ export default class MEChat {
|
|
|
43
43
|
this.handleBuildingslug(meChat, opts.building);
|
|
44
44
|
meChat.setAttribute("class", "meetelise-chat");
|
|
45
45
|
meChat.setAttribute("role", "dialog");
|
|
46
|
-
meChat.setAttribute("aria-
|
|
47
|
-
meChat.setAttribute("aria-describedby", "aria-describe");
|
|
46
|
+
meChat.setAttribute("aria-label", "EliseAI Widget");
|
|
47
|
+
meChat.setAttribute("aria-describedby", "aria-describe-info");
|
|
48
48
|
meChat.setAttribute("aria-modal", "true");
|
|
49
49
|
if (opts.themeId) {
|
|
50
50
|
meChat.setAttribute("themeId", opts.themeId);
|
|
@@ -2,7 +2,7 @@ import { css, html, LitElement, PropertyValueMap, TemplateResult } from "lit";
|
|
|
2
2
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
3
3
|
import {
|
|
4
4
|
shortcutKeyIsPressed,
|
|
5
|
-
|
|
5
|
+
formatToPhoneInput,
|
|
6
6
|
isPrintableCharacter,
|
|
7
7
|
} from "../actions/formatPhoneNumber";
|
|
8
8
|
import "./tour-type-option.ts";
|
|
@@ -180,7 +180,7 @@ export class TourScheduler extends LitElement {
|
|
|
180
180
|
this.phoneNumber.slice(0, cursorPosition) +
|
|
181
181
|
e.key +
|
|
182
182
|
this.phoneNumber.slice(cursorPosition);
|
|
183
|
-
this.phoneNumber =
|
|
183
|
+
this.phoneNumber = formatToPhoneInput(updated.replace(/\D/g, ""));
|
|
184
184
|
this.phoneInput.value = this.phoneNumber;
|
|
185
185
|
} else if (e.key === "Backspace") {
|
|
186
186
|
/*
|
|
@@ -216,7 +216,7 @@ export class TourScheduler extends LitElement {
|
|
|
216
216
|
0,
|
|
217
217
|
-1
|
|
218
218
|
)}${digitsAfterCursor}`;
|
|
219
|
-
this.phoneNumber =
|
|
219
|
+
this.phoneNumber = formatToPhoneInput(updatedDigits);
|
|
220
220
|
this.phoneInput.value = this.phoneNumber;
|
|
221
221
|
const numOfCharactersDeleted =
|
|
222
222
|
originalCharacterCount - this.phoneNumber.length;
|
|
@@ -287,7 +287,7 @@ export class TourScheduler extends LitElement {
|
|
|
287
287
|
const numbersAfterCursor = cursorPosition
|
|
288
288
|
? this.phoneInput.value.slice(cursorPosition).replace(/\D/g, "")
|
|
289
289
|
: "";
|
|
290
|
-
this.phoneNumber =
|
|
290
|
+
this.phoneNumber = formatToPhoneInput(this.phoneInput.value);
|
|
291
291
|
|
|
292
292
|
// EXAMPLES: (123)| 4 numbersAfterCursor will be '4'.
|
|
293
293
|
let cursorNegativeIndex = 0;
|
|
@@ -1109,7 +1109,7 @@ export class TourScheduler extends LitElement {
|
|
|
1109
1109
|
if (!e.target) {
|
|
1110
1110
|
return;
|
|
1111
1111
|
}
|
|
1112
|
-
this.phoneNumber =
|
|
1112
|
+
this.phoneNumber = formatToPhoneInput(
|
|
1113
1113
|
(e.target as HTMLInputElement).value
|
|
1114
1114
|
);
|
|
1115
1115
|
}}
|
|
@@ -8,7 +8,7 @@ import postLeadSources from "../../postLeadSources";
|
|
|
8
8
|
import "../me-select.ts";
|
|
9
9
|
import { MESelect } from "../me-select";
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
formatToPhoneInput,
|
|
12
12
|
isModifierKey,
|
|
13
13
|
isNumericInput,
|
|
14
14
|
} from "./formatPhoneNumber";
|
|
@@ -177,7 +177,7 @@ export class EmailUsWindow extends LitElement {
|
|
|
177
177
|
}
|
|
178
178
|
const inputElement = e.target as HTMLInputElement;
|
|
179
179
|
|
|
180
|
-
this.phoneNumber =
|
|
180
|
+
this.phoneNumber = formatToPhoneInput(inputElement.value);
|
|
181
181
|
|
|
182
182
|
this.phoneNumberInputRef.value.value = this.phoneNumber;
|
|
183
183
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* For now, only handles the US phone number case.....
|
|
3
|
+
* Formats into phone number as you type
|
|
3
4
|
*/
|
|
4
|
-
export const
|
|
5
|
+
export const formatToPhoneInput = (phoneNumber: string): string => {
|
|
5
6
|
const input = phoneNumber.replace(/\D/g, "").substring(0, 10);
|
|
6
7
|
const areaCode = input.substring(0, 3);
|
|
7
8
|
const middle = input.substring(3, 6);
|
|
@@ -19,6 +20,19 @@ export const formatToPhone = (phoneNumber: string): string => {
|
|
|
19
20
|
return "";
|
|
20
21
|
};
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Formats a phone number into a human-readable format.
|
|
25
|
+
*/
|
|
26
|
+
export const formatPhoneNumber = (phoneNumberString: string): string => {
|
|
27
|
+
const cleaned = ("" + phoneNumberString).replace(/\D/g, "");
|
|
28
|
+
const match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/);
|
|
29
|
+
if (match) {
|
|
30
|
+
const intlCode = match[1] ? "+1 " : "";
|
|
31
|
+
return [intlCode, "(", match[2], ") ", match[3], "-", match[4]].join("");
|
|
32
|
+
}
|
|
33
|
+
return phoneNumberString;
|
|
34
|
+
};
|
|
35
|
+
|
|
22
36
|
export const isNumericInput = (event: KeyboardEvent): boolean => {
|
|
23
37
|
const key = event.keyCode;
|
|
24
38
|
return (key >= 48 && key <= 57) || (key >= 96 && key <= 105);
|
|
@@ -4,7 +4,7 @@ import { createRef, ref, Ref } from "lit/directives/ref.js";
|
|
|
4
4
|
import { installActionConfirmButton } from "./action-confirm-button";
|
|
5
5
|
import { installDetailsWindow } from "./details-window";
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
formatToPhoneInput,
|
|
8
8
|
isModifierKey,
|
|
9
9
|
isNumericInput,
|
|
10
10
|
} from "./formatPhoneNumber";
|
|
@@ -95,7 +95,7 @@ export class TextUsWindow extends LitElement {
|
|
|
95
95
|
}
|
|
96
96
|
const inputElement = e.target as HTMLInputElement;
|
|
97
97
|
|
|
98
|
-
this.phoneNumber =
|
|
98
|
+
this.phoneNumber = formatToPhoneInput(inputElement.value);
|
|
99
99
|
|
|
100
100
|
this.phoneNumberInputRef.value.value = this.phoneNumber;
|
|
101
101
|
};
|
|
@@ -16,6 +16,9 @@ import fetchBuildingABTestType, {
|
|
|
16
16
|
abTestTypes,
|
|
17
17
|
} from "../fetchBuildingABTestType";
|
|
18
18
|
import fetchCurrentParsedLeadSource from "../fetchCurrentParsedLeadSource";
|
|
19
|
+
import fetchPhoneNumberFromSource, {
|
|
20
|
+
NumberForSelectedSource,
|
|
21
|
+
} from "../fetchPhoneNumberFromSource";
|
|
19
22
|
import { getTheme, Theme, ThemeIdString } from "../themes";
|
|
20
23
|
import { isMobile } from "../utils";
|
|
21
24
|
import { installLauncher } from "./Launcher";
|
|
@@ -33,6 +36,7 @@ import {
|
|
|
33
36
|
TabletWhiteStrokeIcon,
|
|
34
37
|
WhiteStrokeTourIcon,
|
|
35
38
|
} from "../svgIcons";
|
|
39
|
+
import { formatPhoneNumber } from "./actions/formatPhoneNumber";
|
|
36
40
|
|
|
37
41
|
export interface Options {
|
|
38
42
|
building: string;
|
|
@@ -150,6 +154,8 @@ export class MEChat extends LitElement {
|
|
|
150
154
|
private featureFlagShowDropdown: FeatureFlagsShowDropdown =
|
|
151
155
|
FeatureFlagsShowDropdown.always;
|
|
152
156
|
@state()
|
|
157
|
+
private phoneNumberForSource: NumberForSelectedSource | null = null;
|
|
158
|
+
@state()
|
|
153
159
|
private hasMounted = false;
|
|
154
160
|
@state()
|
|
155
161
|
private hideLauncher = false;
|
|
@@ -186,12 +192,29 @@ export class MEChat extends LitElement {
|
|
|
186
192
|
fetchCurrentParsedLeadSource(this.buildingSlug, document.referrer),
|
|
187
193
|
]);
|
|
188
194
|
|
|
195
|
+
building.phoneNumber = formatPhoneNumber(building.phoneNumber);
|
|
189
196
|
this.building = building;
|
|
190
197
|
this.buildingABTestType = buildingABTest?.abTestType ?? "";
|
|
191
198
|
this.leadSources = leadSources;
|
|
192
199
|
this.featureFlagShowDropdown = featureFlagShowDropdown;
|
|
193
200
|
this.currentLeadSource = currentLeadSource;
|
|
194
201
|
|
|
202
|
+
const phoneNumberForSource = await fetchPhoneNumberFromSource(
|
|
203
|
+
this.buildingSlug,
|
|
204
|
+
this.currentLeadSource
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// if the building does NOT have IVR setup, we want to use the building's phone number
|
|
208
|
+
if (!phoneNumberForSource) {
|
|
209
|
+
this.phoneNumberForSource = {
|
|
210
|
+
number: this.building.phoneNumber,
|
|
211
|
+
isMatch: false,
|
|
212
|
+
isPropertyWebsiteCatchall: true,
|
|
213
|
+
};
|
|
214
|
+
} else {
|
|
215
|
+
this.phoneNumberForSource = phoneNumberForSource;
|
|
216
|
+
}
|
|
217
|
+
|
|
195
218
|
if (this.currentLeadSource) {
|
|
196
219
|
if (!this.leadSources.includes(this.currentLeadSource)) {
|
|
197
220
|
this.leadSources.push(this.currentLeadSource);
|
|
@@ -434,9 +457,8 @@ export class MEChat extends LitElement {
|
|
|
434
457
|
this.isMobile;
|
|
435
458
|
|
|
436
459
|
return html`
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
<div id="aria-describe" style="display: none;">
|
|
460
|
+
<meta name="viewport" content="width=device-width, initial-scale=1 user-scalable=1">
|
|
461
|
+
<div id="aria-describe-info" style="display: none;">
|
|
440
462
|
EliseAI widget that allows you to chat with a virtual assistant, book
|
|
441
463
|
a tour, contact the leasing office, and more.
|
|
442
464
|
</div>
|
|
@@ -469,53 +491,58 @@ export class MEChat extends LitElement {
|
|
|
469
491
|
["hideTab"]: this.isLoading,
|
|
470
492
|
})}
|
|
471
493
|
>
|
|
472
|
-
${
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
?
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
?
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
?
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
?
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
494
|
+
${
|
|
495
|
+
this.building
|
|
496
|
+
? html`<meetelise-launcher
|
|
497
|
+
${ref(this.launcherRef)}
|
|
498
|
+
.isMobile=${this.isMobile}
|
|
499
|
+
.isFirstMount=${!this.hasMounted}
|
|
500
|
+
.isMini=${this.useMiniWidget}
|
|
501
|
+
.buildingId=${this.building?.id ?? 0}
|
|
502
|
+
.layoutOptions=${this.building?.layoutOptionsV2 ?? []}
|
|
503
|
+
.unitOptions=${this.building?.unitOptionsV2 ?? []}
|
|
504
|
+
.tourTypeOptions=${this.building?.tourTypeOptions ?? []}
|
|
505
|
+
.launcherStyles=${this.launcherStyles}
|
|
506
|
+
.autoOpenChatWidget=${this.building.autoOpenChatWidget ??
|
|
507
|
+
false}
|
|
508
|
+
chatCallUsHeader=${this.building?.chatCallUsHeader ?? ""}
|
|
509
|
+
chatId="${this.chatId}"
|
|
510
|
+
phoneNumber="${this.phoneNumberForSource?.number ??
|
|
511
|
+
this.building?.phoneNumber ??
|
|
512
|
+
""}"
|
|
513
|
+
textColor="${this.theme.chatHeader.textColor}"
|
|
514
|
+
backgroundColor="${this.theme.chatPaneBackgroundColor}"
|
|
515
|
+
orgSlug="${this.orgSlug}"
|
|
516
|
+
buildingSlug="${this.buildingSlug}"
|
|
517
|
+
sgtUrl="${this.building?.sgtUrl ?? ""}"
|
|
518
|
+
buildingABTestType="${this.buildingABTestType ?? ""}"
|
|
519
|
+
currentLeadSource="${this.currentLeadSource ?? ""}"
|
|
520
|
+
featureFlagShowDropdown="${this.featureFlagShowDropdown}"
|
|
521
|
+
.leadSources="${this.leadSources ?? []}"
|
|
522
|
+
escortedToursLink="${this.building?.escortedToursLink ?? ""}"
|
|
523
|
+
virtualToursLink="${this.building?.virtualToursLink ?? ""}"
|
|
524
|
+
?hidden=${this.hideLauncher}
|
|
525
|
+
?hasCallUsEnabled=${!this.building?.chatWidgets
|
|
526
|
+
? true
|
|
527
|
+
: this.building?.chatWidgets.includes("CALL")}
|
|
528
|
+
?hasChatEnabled=${!this.building?.chatWidgets
|
|
529
|
+
? true
|
|
530
|
+
: this.building?.chatWidgets.includes("CHAT")}
|
|
531
|
+
?hasEmailEnabled=${!this.building?.chatWidgets
|
|
532
|
+
? true
|
|
533
|
+
: this.building?.chatWidgets.includes("EMAIL")}
|
|
534
|
+
?hasTextUsEnabled=${!this.building?.chatWidgets
|
|
535
|
+
? true
|
|
536
|
+
: this.building?.chatWidgets.includes("SMS")}
|
|
537
|
+
?hasSSTEnabled=${!this.building?.chatWidgets
|
|
538
|
+
? true
|
|
539
|
+
: this.building?.chatWidgets.includes("SST")}
|
|
540
|
+
>
|
|
541
|
+
</meetelise-launcher>`
|
|
542
|
+
: ""
|
|
543
|
+
}
|
|
517
544
|
</div>
|
|
518
|
-
</
|
|
545
|
+
</meta>
|
|
519
546
|
`;
|
|
520
547
|
}
|
|
521
548
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { formatPhoneNumber } from "./WebComponent/actions/formatPhoneNumber";
|
|
3
|
+
|
|
4
|
+
export interface NumberForSelectedSource {
|
|
5
|
+
number: string;
|
|
6
|
+
isMatch: boolean;
|
|
7
|
+
isPropertyWebsiteCatchall: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default async function fetchPhoneNumberFromSource(
|
|
11
|
+
buildingSlug: string,
|
|
12
|
+
source: string | null
|
|
13
|
+
): Promise<NumberForSelectedSource | null> {
|
|
14
|
+
const host = "https://app.meetelise.com";
|
|
15
|
+
try {
|
|
16
|
+
const phoneNumberResponse = await axios.get(
|
|
17
|
+
`${host}/platformApi/webchat/${buildingSlug}/phone-number-by-source?source=${source}`
|
|
18
|
+
);
|
|
19
|
+
if (phoneNumberResponse.data) {
|
|
20
|
+
return {
|
|
21
|
+
number: formatPhoneNumber(phoneNumberResponse.data.number),
|
|
22
|
+
isMatch: phoneNumberResponse.data.isMatch,
|
|
23
|
+
isPropertyWebsiteCatchall:
|
|
24
|
+
phoneNumberResponse.data.isPropertyWebsiteCatchall,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
} catch (_) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|