@meetelise/chat 1.25.0 → 1.25.2
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/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +111 -0
- package/coverage/lcov-report/index.js.html +17093 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov.info +9986 -0
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
- package/.eslintignore +0 -2
- package/.eslintrc.cjs +0 -23
- package/.github/pull_request_template.md +0 -61
- package/.github/workflows/pull.yml +0 -46
- package/.github/workflows/release.yml +0 -23
- package/.husky/commit-msg +0 -2
- package/.husky/pre-commit +0 -4
- package/.idea/codeStyles/Project.xml +0 -57
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -67
- package/.prettierignore +0 -2
- package/.prettierrc.json +0 -1
- package/.vscode/settings.json +0 -13
- package/CONTRIBUTING.md +0 -36
- package/public/demo/index.html +0 -347
- package/public/demo/secret.html +0 -63
- package/src/MyPubnub.ts +0 -792
- package/src/WebComponent/FeeCalculator/components/collapsible-fee-section/collapsible-fee-section-styles.ts +0 -86
- package/src/WebComponent/FeeCalculator/components/collapsible-fee-section/collapsible-fee-section.ts +0 -94
- package/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.ts +0 -47
- package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +0 -50
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +0 -46
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +0 -70
- package/src/WebComponent/FeeCalculator/components/index.ts +0 -3
- package/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.ts +0 -39
- package/src/WebComponent/FeeCalculator/components/promo-card/promo-card.ts +0 -39
- package/src/WebComponent/FeeCalculator/fee-calculator-styles.ts +0 -280
- package/src/WebComponent/FeeCalculator/fee-calculator.ts +0 -256
- package/src/WebComponent/FeeCalculator/index.ts +0 -4
- package/src/WebComponent/FeeCalculator/model/building-fee.ts +0 -83
- package/src/WebComponent/FeeCalculator/model/transaction-category.ts +0 -23
- package/src/WebComponent/LeadSourceClient.ts +0 -332
- package/src/WebComponent/MEChat.css +0 -5
- package/src/WebComponent/OfficeHours.ts +0 -73
- package/src/WebComponent/Scheduler/date-picker.ts +0 -405
- package/src/WebComponent/Scheduler/time-picker.ts +0 -190
- package/src/WebComponent/Scheduler/tour-scheduler.ts +0 -1352
- package/src/WebComponent/Scheduler/tour-type-option.ts +0 -112
- package/src/WebComponent/Scheduler/tourSchedulerStyles.ts +0 -418
- package/src/WebComponent/actions/InputStyles.ts +0 -57
- package/src/WebComponent/actions/action-confirm-button.ts +0 -125
- package/src/WebComponent/actions/call-us-window.ts +0 -445
- package/src/WebComponent/actions/collapse-expand-button.ts +0 -65
- package/src/WebComponent/actions/details-window.ts +0 -150
- package/src/WebComponent/actions/email-us-window.ts +0 -555
- package/src/WebComponent/actions/formatPhoneNumber.ts +0 -72
- package/src/WebComponent/actions/minimize-expand-button.ts +0 -93
- package/src/WebComponent/chat-additional-actions.ts +0 -135
- package/src/WebComponent/health-chat.ts +0 -270
- package/src/WebComponent/healthchat-styles.ts +0 -119
- package/src/WebComponent/icons/ApplyOutlineIcon.ts +0 -22
- package/src/WebComponent/icons/BookTourOutlineIcon.ts +0 -13
- package/src/WebComponent/icons/CalculatorOutlineIcon.ts +0 -22
- package/src/WebComponent/icons/ChatOutlineIcon.ts +0 -10
- package/src/WebComponent/icons/ChevronLeftIcon.ts +0 -7
- package/src/WebComponent/icons/ChevronRightIcon.ts +0 -7
- package/src/WebComponent/icons/ContactResidentIcon.ts +0 -9
- package/src/WebComponent/icons/DollarOutlineIcon.ts +0 -18
- package/src/WebComponent/icons/EmailOutlineIcon.ts +0 -7
- package/src/WebComponent/icons/HeyThereEmojiIcon.ts +0 -12
- package/src/WebComponent/icons/PhoneOutlineIcon.ts +0 -7
- package/src/WebComponent/icons/SendMessageIcon.ts +0 -17
- package/src/WebComponent/icons/TourSelfGuidedIcon.ts +0 -17
- package/src/WebComponent/icons/TourVirtuallyIcon.ts +0 -17
- package/src/WebComponent/icons/TourWithAgentIcon.ts +0 -17
- package/src/WebComponent/icons/XOutlineIcon.ts +0 -8
- package/src/WebComponent/index.ts +0 -2
- package/src/WebComponent/launcher/Launcher.ts +0 -1193
- package/src/WebComponent/launcher/launcherStyles.ts +0 -500
- package/src/WebComponent/launcher/mobile-launcher.ts +0 -159
- package/src/WebComponent/launcher/typeEmojiStyles.ts +0 -161
- package/src/WebComponent/launcher/typeMiniStyles.ts +0 -60
- package/src/WebComponent/launcher/typeMobileStyles.ts +0 -50
- package/src/WebComponent/leasing-chat-styles.ts +0 -114
- package/src/WebComponent/me-chat.ts +0 -1257
- package/src/WebComponent/me-select.ts +0 -322
- package/src/WebComponent/mini-loader.ts +0 -28
- package/src/WebComponent/pubnub-chat-styles.ts +0 -204
- package/src/WebComponent/pubnub-chat.ts +0 -928
- package/src/WebComponent/pubnub-media.ts +0 -208
- package/src/WebComponent/pubnub-message-styles.ts +0 -54
- package/src/WebComponent/pubnub-message.ts +0 -431
- package/src/WebComponent/simple-launcher/simple-launcher-styles.ts +0 -34
- package/src/WebComponent/simple-launcher/simple-launcher.ts +0 -100
- package/src/WebComponent/utilities-chat.ts +0 -270
- package/src/WebComponent/utilities-styles.ts +0 -110
- package/src/WebComponent/utils.ts +0 -82
- package/src/analytics.ts +0 -217
- package/src/assetUrls.ts +0 -6
- package/src/disclaimers.ts +0 -58
- package/src/fetchBuildingABTestType.ts +0 -21
- package/src/fetchBuildingInfo.ts +0 -87
- package/src/fetchBuildingWebchatView.ts +0 -154
- package/src/fetchFeatureFlag.ts +0 -250
- package/src/fetchLeadSources.ts +0 -98
- package/src/fetchPhoneNumberFromSource.ts +0 -31
- package/src/fetchWebchatPreferences.ts +0 -54
- package/src/getAvailabilities.ts +0 -174
- package/src/getBuildingPhoneNumber.ts +0 -26
- package/src/getShouldAllowScheduling.ts +0 -16
- package/src/getShouldShowWebchat.ts +0 -114
- package/src/getTimezoneString.ts +0 -39
- package/src/globals.ts +0 -1
- package/src/gtm.ts +0 -17
- package/src/handleChatId.ts +0 -101
- package/src/insertDNIIntoWebsite.ts +0 -146
- package/src/insertLeadSourceIntoSchedulerLinks.ts +0 -71
- package/src/main/MEChat.test.ts +0 -110
- package/src/main/MEChat.ts +0 -404
- package/src/main/utils.ts +0 -70
- package/src/postLeadSources.ts +0 -44
- package/src/rentgrata.ts +0 -74
- package/src/replaceSelectButtonsWithNewLink.ts +0 -68
- package/src/services/fees/fetchBuildingFees.ts +0 -28
- package/src/svgIcons.ts +0 -14
- package/src/themes.ts +0 -65
- package/src/types/rest-sdk.types.ts +0 -13
- package/src/types/webchat-no-show-reason.ts +0 -6
- package/src/utils.ts +0 -121
- package/tsconfig.json +0 -84
- package/web-test-runner.config.js +0 -10
- package/webpack.config.cjs +0 -48
|
@@ -1,1257 +0,0 @@
|
|
|
1
|
-
import { css, html, LitElement, TemplateResult } from "lit";
|
|
2
|
-
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
4
|
-
import { createRef, ref, Ref } from "lit/directives/ref.js";
|
|
5
|
-
import { Launcher } from "./launcher/Launcher";
|
|
6
|
-
import "./Scheduler/tour-scheduler";
|
|
7
|
-
import fetchBuildingWebchatView, {
|
|
8
|
-
BuildingWebchatView,
|
|
9
|
-
DesignConcepts,
|
|
10
|
-
} from "../fetchBuildingWebchatView";
|
|
11
|
-
import Analytics, { logSignal, LogType, sendLoggingEvent } from "../analytics";
|
|
12
|
-
import {
|
|
13
|
-
FeatureFlagsShowDropdown,
|
|
14
|
-
fetchFeatureFlagInsertDNIWebsite,
|
|
15
|
-
fetchFeatureFlagReplaceScheduleTourCtaWebsite,
|
|
16
|
-
fetchFeatureFlagShowMarketingSourceDropdown,
|
|
17
|
-
fetchFeatureFlagUseApplicationsLinkReplacement,
|
|
18
|
-
fetchFeatureFlagUseOverrideContactUsForm,
|
|
19
|
-
fetchFeatureFlagUsePhoneNumberBySource,
|
|
20
|
-
} from "../fetchFeatureFlag";
|
|
21
|
-
import fetchBuildingABTestType from "../fetchBuildingABTestType";
|
|
22
|
-
import fetchPhoneNumberFromSource, {
|
|
23
|
-
NumberForSelectedSource,
|
|
24
|
-
} from "../fetchPhoneNumberFromSource";
|
|
25
|
-
import { defaultPrimaryColor, defaultBackgroundColor } from "../themes";
|
|
26
|
-
import getShouldShowWebchat from "../getShouldShowWebchat";
|
|
27
|
-
import { isMobile, isTestEnv } from "../utils";
|
|
28
|
-
import { installLauncher } from "./launcher/Launcher";
|
|
29
|
-
import parseISO from "date-fns/parseISO";
|
|
30
|
-
import isPast from "date-fns/isPast";
|
|
31
|
-
|
|
32
|
-
import "./MEChat.css";
|
|
33
|
-
import { getRawAvailabilities } from "../getAvailabilities";
|
|
34
|
-
import { StyleInfo } from "lit/directives/style-map";
|
|
35
|
-
import addMinutes from "date-fns/addMinutes";
|
|
36
|
-
import formatISO from "date-fns/formatISO";
|
|
37
|
-
import fetchLeadSources from "../fetchLeadSources";
|
|
38
|
-
import { formatPhoneNumber } from "./actions/formatPhoneNumber";
|
|
39
|
-
import MyPubnub from "../MyPubnub";
|
|
40
|
-
import { insertDNIIntoWebsite } from "../insertDNIIntoWebsite";
|
|
41
|
-
import {
|
|
42
|
-
insertLeadSourceIntoSchedulerLinks,
|
|
43
|
-
replacePageRedirectElementWithTourWidgetTrigger,
|
|
44
|
-
replaceSSTLinkWithTourWidgetTrigger,
|
|
45
|
-
replaceTourTriggerElementWithTourWidgetTrigger,
|
|
46
|
-
} from "../insertLeadSourceIntoSchedulerLinks";
|
|
47
|
-
|
|
48
|
-
import "./actions/minimize-expand-button";
|
|
49
|
-
import "./launcher/mobile-launcher";
|
|
50
|
-
import "./pubnub-chat";
|
|
51
|
-
import { getBuildingPhoneNumber } from "../getBuildingPhoneNumber";
|
|
52
|
-
import {
|
|
53
|
-
clearChatStorageKey,
|
|
54
|
-
createChatStorageKey,
|
|
55
|
-
getChatStorageKey,
|
|
56
|
-
isChatKeyValid,
|
|
57
|
-
} from "../handleChatId";
|
|
58
|
-
import LeadSourceClient, {
|
|
59
|
-
getDefaultLeadSourceAttribution,
|
|
60
|
-
} from "./LeadSourceClient";
|
|
61
|
-
import noop from "lodash/noop";
|
|
62
|
-
import { updateRentgrataToken } from "../rentgrata";
|
|
63
|
-
import { WidgetType } from "../main/MEChat";
|
|
64
|
-
import { replaceSelectButtonsWithNewLink } from "../replaceSelectButtonsWithNewLink";
|
|
65
|
-
import "./chat-additional-actions";
|
|
66
|
-
|
|
67
|
-
@customElement("me-chat")
|
|
68
|
-
export class MEChat extends LitElement {
|
|
69
|
-
static styles = css`
|
|
70
|
-
:host {
|
|
71
|
-
all: initial;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
#__talkjs_launcher:not(.shouldBeVisible) {
|
|
75
|
-
display: none;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.launcherContainer.launcher__mobile {
|
|
79
|
-
width: 100%;
|
|
80
|
-
height: 100px;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.hideTab {
|
|
84
|
-
display: none;
|
|
85
|
-
}
|
|
86
|
-
.showTab {
|
|
87
|
-
display: flex;
|
|
88
|
-
align-items: center;
|
|
89
|
-
justify-content: space-between;
|
|
90
|
-
gap: 32px;
|
|
91
|
-
}
|
|
92
|
-
#chatAdditionalActionsPubnub {
|
|
93
|
-
position: fixed;
|
|
94
|
-
box-sizing: border-box;
|
|
95
|
-
|
|
96
|
-
box-sizing: border-box;
|
|
97
|
-
width: 340px;
|
|
98
|
-
|
|
99
|
-
padding-top: 0px;
|
|
100
|
-
padding-right: 12px;
|
|
101
|
-
|
|
102
|
-
z-index: 1000000000;
|
|
103
|
-
}
|
|
104
|
-
#chatAdditionalActionsPubnub::after {
|
|
105
|
-
content: "";
|
|
106
|
-
position: absolute;
|
|
107
|
-
top: -6px;
|
|
108
|
-
right: 0;
|
|
109
|
-
width: 0;
|
|
110
|
-
height: 0;
|
|
111
|
-
border-bottom: 22px solid transparent;
|
|
112
|
-
border-right: 30px solid black;
|
|
113
|
-
}
|
|
114
|
-
#pubnub-bottom {
|
|
115
|
-
position: fixed;
|
|
116
|
-
bottom: 0;
|
|
117
|
-
}
|
|
118
|
-
`;
|
|
119
|
-
@property({ type: String })
|
|
120
|
-
private buildingSlug = "";
|
|
121
|
-
@property({ type: String })
|
|
122
|
-
private orgSlug = "";
|
|
123
|
-
@property({ type: Object })
|
|
124
|
-
launcherStyles: StyleInfo = {};
|
|
125
|
-
@property()
|
|
126
|
-
mobileStyles: StyleInfo = {};
|
|
127
|
-
|
|
128
|
-
@property({ type: Boolean })
|
|
129
|
-
isMinimized = false;
|
|
130
|
-
|
|
131
|
-
@property({ type: String })
|
|
132
|
-
private primaryColor: string | null = null;
|
|
133
|
-
|
|
134
|
-
@property({ type: String })
|
|
135
|
-
private backgroundColor: string | null = null;
|
|
136
|
-
|
|
137
|
-
@property({ type: String })
|
|
138
|
-
private foregroundColorOnPrimaryBackgroundColor: string | null = null;
|
|
139
|
-
|
|
140
|
-
@property({ type: String })
|
|
141
|
-
private foregroundColorOnSecondaryBackgroundColor: string | null = null;
|
|
142
|
-
|
|
143
|
-
@state()
|
|
144
|
-
private chatId = "";
|
|
145
|
-
@state()
|
|
146
|
-
private analytics: Analytics | null = null;
|
|
147
|
-
@state()
|
|
148
|
-
private launcher: HTMLElement | null = null;
|
|
149
|
-
@state()
|
|
150
|
-
private buildingWebchatView: BuildingWebchatView | null = null;
|
|
151
|
-
@state()
|
|
152
|
-
private designConcept: string | null = null;
|
|
153
|
-
@state()
|
|
154
|
-
private leadSources: string[] | null = null;
|
|
155
|
-
@state()
|
|
156
|
-
private currentLeadSource: string | null = null;
|
|
157
|
-
@state()
|
|
158
|
-
private featureFlagShowDropdown: FeatureFlagsShowDropdown =
|
|
159
|
-
FeatureFlagsShowDropdown.always;
|
|
160
|
-
@state()
|
|
161
|
-
private phoneNumberForSource: NumberForSelectedSource | null = null;
|
|
162
|
-
@state()
|
|
163
|
-
private hasMounted = false;
|
|
164
|
-
@state()
|
|
165
|
-
private hideLauncher = false;
|
|
166
|
-
@state()
|
|
167
|
-
private isLoading = true;
|
|
168
|
-
|
|
169
|
-
@state()
|
|
170
|
-
private showTourNextToChat = false;
|
|
171
|
-
|
|
172
|
-
@state()
|
|
173
|
-
private displayPubnubChat = false;
|
|
174
|
-
|
|
175
|
-
@state()
|
|
176
|
-
private myPubnub: MyPubnub | null = null;
|
|
177
|
-
|
|
178
|
-
@state()
|
|
179
|
-
private LeadSourceClient: LeadSourceClient | null = null;
|
|
180
|
-
|
|
181
|
-
@state()
|
|
182
|
-
private sampleRateToUse = 0.05;
|
|
183
|
-
|
|
184
|
-
@property({ type: Number })
|
|
185
|
-
private right = undefined;
|
|
186
|
-
|
|
187
|
-
@property({ type: Number })
|
|
188
|
-
private bottom = undefined;
|
|
189
|
-
|
|
190
|
-
@property({ type: Number })
|
|
191
|
-
private top = undefined;
|
|
192
|
-
|
|
193
|
-
@property({ type: Number })
|
|
194
|
-
private left = undefined;
|
|
195
|
-
|
|
196
|
-
@property({ attribute: true })
|
|
197
|
-
overrideRentgrata = false;
|
|
198
|
-
|
|
199
|
-
@property({ attribute: true })
|
|
200
|
-
widgetType: WidgetType = WidgetType.Default;
|
|
201
|
-
|
|
202
|
-
@property()
|
|
203
|
-
onWidgetLoaded: () => void = noop;
|
|
204
|
-
|
|
205
|
-
@property({ attribute: true })
|
|
206
|
-
onSstClose: () => void = noop;
|
|
207
|
-
|
|
208
|
-
@state()
|
|
209
|
-
private enabledChatWidgets: {
|
|
210
|
-
callDesktop: boolean;
|
|
211
|
-
callMobile: boolean;
|
|
212
|
-
chatMobile: boolean;
|
|
213
|
-
chatDesktop: boolean;
|
|
214
|
-
emailDesktop: boolean;
|
|
215
|
-
emailMobile: boolean;
|
|
216
|
-
textDesktop: boolean;
|
|
217
|
-
textMobile: boolean;
|
|
218
|
-
sstDesktop: boolean;
|
|
219
|
-
sstMobile: boolean;
|
|
220
|
-
calcDesktop: boolean;
|
|
221
|
-
calcMobile: boolean;
|
|
222
|
-
} = {
|
|
223
|
-
callDesktop: false,
|
|
224
|
-
callMobile: false,
|
|
225
|
-
chatMobile: false,
|
|
226
|
-
chatDesktop: false,
|
|
227
|
-
emailDesktop: false,
|
|
228
|
-
emailMobile: false,
|
|
229
|
-
textDesktop: false,
|
|
230
|
-
textMobile: false,
|
|
231
|
-
sstDesktop: false,
|
|
232
|
-
sstMobile: false,
|
|
233
|
-
calcDesktop: false,
|
|
234
|
-
calcMobile: false,
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
@state()
|
|
238
|
-
private webchatConfigHasAutoOpenChat = false;
|
|
239
|
-
|
|
240
|
-
@state()
|
|
241
|
-
private requiresConsent = false;
|
|
242
|
-
|
|
243
|
-
@state()
|
|
244
|
-
private hideMobileFeatures = false;
|
|
245
|
-
|
|
246
|
-
@state()
|
|
247
|
-
private privacyPolicyUrl = "http://bit.ly/me_privacy_policy";
|
|
248
|
-
|
|
249
|
-
launcherRef: Ref<Launcher> = createRef();
|
|
250
|
-
|
|
251
|
-
firstUpdated = async (): Promise<void> => this.setupWebchat();
|
|
252
|
-
|
|
253
|
-
private setupWebchat = async (): Promise<void> => {
|
|
254
|
-
if (!this.buildingSlug || !this.orgSlug) return;
|
|
255
|
-
const buildingWebchatView = await fetchBuildingWebchatView(
|
|
256
|
-
this.orgSlug,
|
|
257
|
-
this.buildingSlug
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
if (Math.random() < 0.2) {
|
|
261
|
-
try {
|
|
262
|
-
updateRentgrataToken(this.buildingSlug, this.orgSlug);
|
|
263
|
-
} catch (e) {
|
|
264
|
-
// eslint-disable-next-line no-console
|
|
265
|
-
console.warn("Error updating rentgrata token", e);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const shouldShowWebchat = await getShouldShowWebchat(
|
|
270
|
-
buildingWebchatView,
|
|
271
|
-
this.buildingSlug,
|
|
272
|
-
this.orgSlug
|
|
273
|
-
);
|
|
274
|
-
if (!shouldShowWebchat) {
|
|
275
|
-
return;
|
|
276
|
-
} else {
|
|
277
|
-
logSignal({
|
|
278
|
-
params: {
|
|
279
|
-
org_slug: this.orgSlug,
|
|
280
|
-
building_slug: this.buildingSlug,
|
|
281
|
-
is_pixel_on_site: true,
|
|
282
|
-
is_any_webchat_showing: true,
|
|
283
|
-
},
|
|
284
|
-
// We use a lower sample rate if not launched yet because likely still in onboarding process
|
|
285
|
-
sampleRate: buildingWebchatView?.launchedDateTime ? 0.01 : 0.05,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
this.buildingWebchatView = buildingWebchatView;
|
|
289
|
-
|
|
290
|
-
await this.initializeChatVariables();
|
|
291
|
-
await this.handleChatInitializeAnalytics();
|
|
292
|
-
await this.setBuildingDerivedInfo();
|
|
293
|
-
|
|
294
|
-
this.attachOnClickToLauncher();
|
|
295
|
-
|
|
296
|
-
if (this.shouldAutoOpenChat(this.webchatConfigHasAutoOpenChat)) {
|
|
297
|
-
this.displayPubnubChat = true;
|
|
298
|
-
this.hideLauncher = true;
|
|
299
|
-
this.hasMounted = true;
|
|
300
|
-
this.updateAlreadyAutoOpenedTimestamp();
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
this.isLoading = false;
|
|
304
|
-
|
|
305
|
-
if (localStorage.getItem("isChatOpen") === "true") {
|
|
306
|
-
this.hideLauncher = true;
|
|
307
|
-
this.displayPubnubChat = true;
|
|
308
|
-
}
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
// The general info for the buildingg
|
|
312
|
-
setBuildingDerivedInfo = async (): Promise<void> => {
|
|
313
|
-
const buildingDetails = this.buildingWebchatView;
|
|
314
|
-
if (!buildingDetails) return;
|
|
315
|
-
if (buildingDetails && this.orgSlug) {
|
|
316
|
-
overrideContactUsForm(
|
|
317
|
-
this.orgSlug,
|
|
318
|
-
this.LeadSourceClient?.chatId ?? null,
|
|
319
|
-
this.sampleRateToUse,
|
|
320
|
-
this.buildingSlug,
|
|
321
|
-
this.LeadSourceClient?.leadSource ?? null
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const [
|
|
326
|
-
buildingABTest,
|
|
327
|
-
leadSources,
|
|
328
|
-
featureFlagShowDropdown,
|
|
329
|
-
featureFlagUseDNI,
|
|
330
|
-
featureFlagInsertDNIWebsite,
|
|
331
|
-
featureFlagReplaceScheduleTourCtaWebsite,
|
|
332
|
-
featureFlagUseApplicationsLinkReplacement,
|
|
333
|
-
] = await Promise.all([
|
|
334
|
-
fetchBuildingABTestType(this.buildingSlug),
|
|
335
|
-
fetchLeadSources(this.orgSlug, this.buildingSlug),
|
|
336
|
-
fetchFeatureFlagShowMarketingSourceDropdown(this.buildingSlug),
|
|
337
|
-
fetchFeatureFlagUsePhoneNumberBySource(this.buildingSlug),
|
|
338
|
-
fetchFeatureFlagInsertDNIWebsite(this.buildingSlug),
|
|
339
|
-
fetchFeatureFlagReplaceScheduleTourCtaWebsite(this.buildingSlug),
|
|
340
|
-
fetchFeatureFlagUseApplicationsLinkReplacement(this.buildingSlug),
|
|
341
|
-
]);
|
|
342
|
-
|
|
343
|
-
if (this.buildingWebchatView) {
|
|
344
|
-
this.buildingWebchatView.phoneNumber = formatPhoneNumber(
|
|
345
|
-
buildingDetails.phoneNumber
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
this.designConcept = buildingABTest?.abTestType ?? "";
|
|
349
|
-
this.leadSources = leadSources;
|
|
350
|
-
this.featureFlagShowDropdown = featureFlagShowDropdown;
|
|
351
|
-
|
|
352
|
-
// The backend is cached for ~4 hours, so falling back to the existing api request until the cache propagates all the changes
|
|
353
|
-
const buildingPhoneNumber = buildingDetails.textWithUsPhoneNumber
|
|
354
|
-
? buildingDetails.textWithUsPhoneNumber
|
|
355
|
-
: await getBuildingPhoneNumber(this.buildingSlug);
|
|
356
|
-
|
|
357
|
-
const shouldShowCalcDesktop =
|
|
358
|
-
(this.buildingWebchatView?.shouldShowPricingCalculatorDesktop &&
|
|
359
|
-
isTestEnv()) ??
|
|
360
|
-
false;
|
|
361
|
-
const shouldShowCalcMobile =
|
|
362
|
-
(this.buildingWebchatView?.shouldShowPricingCalculatorMobile &&
|
|
363
|
-
isTestEnv()) ??
|
|
364
|
-
false;
|
|
365
|
-
|
|
366
|
-
this.enabledChatWidgets = {
|
|
367
|
-
callDesktop: this.buildingWebchatView?.shouldShowPhoneDesktop ?? false,
|
|
368
|
-
callMobile: this.buildingWebchatView?.shouldShowPhoneMobile ?? false,
|
|
369
|
-
chatDesktop: this.buildingWebchatView?.shouldShowChatDesktop ?? false,
|
|
370
|
-
chatMobile: this.buildingWebchatView?.shouldShowChatMobile ?? false,
|
|
371
|
-
emailDesktop: this.buildingWebchatView?.shouldShowEmailDesktop ?? false,
|
|
372
|
-
emailMobile: this.buildingWebchatView?.shouldShowEmailMobile ?? false,
|
|
373
|
-
textDesktop:
|
|
374
|
-
(this.buildingWebchatView?.shouldShowTextDesktop &&
|
|
375
|
-
!!buildingPhoneNumber) ??
|
|
376
|
-
false,
|
|
377
|
-
textMobile:
|
|
378
|
-
(this.buildingWebchatView?.shouldShowTextMobile &&
|
|
379
|
-
!!buildingPhoneNumber) ??
|
|
380
|
-
false,
|
|
381
|
-
sstDesktop: this.buildingWebchatView?.shouldShowSstDesktop ?? false,
|
|
382
|
-
sstMobile: this.buildingWebchatView?.shouldShowSstMobile ?? false,
|
|
383
|
-
calcDesktop: shouldShowCalcDesktop,
|
|
384
|
-
calcMobile: shouldShowCalcMobile,
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
if (
|
|
388
|
-
this.enabledChatWidgets.sstDesktop ||
|
|
389
|
-
this.enabledChatWidgets.sstMobile ||
|
|
390
|
-
this.orgSlug === "radco"
|
|
391
|
-
) {
|
|
392
|
-
replaceSSTLinkWithTourWidgetTrigger(this.handleTourClicked);
|
|
393
|
-
if (featureFlagReplaceScheduleTourCtaWebsite) {
|
|
394
|
-
replacePageRedirectElementWithTourWidgetTrigger(this.handleTourClicked);
|
|
395
|
-
}
|
|
396
|
-
if (this.orgSlug === "radco") {
|
|
397
|
-
replaceTourTriggerElementWithTourWidgetTrigger(this.handleTourClicked);
|
|
398
|
-
}
|
|
399
|
-
} else {
|
|
400
|
-
if (this.LeadSourceClient?.leadSource) {
|
|
401
|
-
insertLeadSourceIntoSchedulerLinks(
|
|
402
|
-
this.LeadSourceClient?.leadSource ?? null
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (this.buildingWebchatView) {
|
|
408
|
-
this.primaryColor = this.buildingWebchatView.primaryColor ?? null;
|
|
409
|
-
this.backgroundColor = this.buildingWebchatView.secondaryColor ?? null;
|
|
410
|
-
this.foregroundColorOnPrimaryBackgroundColor =
|
|
411
|
-
this.buildingWebchatView.foregroundColorOnPrimaryBackgroundColor ??
|
|
412
|
-
null;
|
|
413
|
-
this.foregroundColorOnSecondaryBackgroundColor =
|
|
414
|
-
this.buildingWebchatView.foregroundColorOnSecondaryBackgroundColor ??
|
|
415
|
-
null;
|
|
416
|
-
this.webchatConfigHasAutoOpenChat =
|
|
417
|
-
this.buildingWebchatView.autoOpenChat ?? false;
|
|
418
|
-
this.requiresConsent =
|
|
419
|
-
this.buildingWebchatView.requiresConsentForChat ?? false;
|
|
420
|
-
this.hideMobileFeatures =
|
|
421
|
-
this.buildingWebchatView.collapseMobileFeatures ?? false;
|
|
422
|
-
this.privacyPolicyUrl =
|
|
423
|
-
this.buildingWebchatView.privacyPolicyUrlForChat ??
|
|
424
|
-
this.privacyPolicyUrl;
|
|
425
|
-
|
|
426
|
-
if (this.buildingWebchatView.displayStyle === DesignConcepts.MINIMIZED) {
|
|
427
|
-
// this.designConcept = DesignConcepts.MINIMIZED; // uncomment this if we want to remove the minimize/expand option
|
|
428
|
-
this.isMinimized = true;
|
|
429
|
-
}
|
|
430
|
-
if (this.buildingWebchatView.displayStyle === DesignConcepts.PILLS) {
|
|
431
|
-
this.designConcept = null; // default design concept is PILLS, no need to specify here
|
|
432
|
-
}
|
|
433
|
-
if (this.buildingWebchatView.displayStyle === DesignConcepts.EMOJI) {
|
|
434
|
-
this.designConcept = DesignConcepts.EMOJI;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
this.onWidgetLoaded();
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
if (this.primaryColor === null) this.primaryColor = defaultPrimaryColor;
|
|
441
|
-
if (this.backgroundColor === null)
|
|
442
|
-
this.backgroundColor = defaultBackgroundColor;
|
|
443
|
-
|
|
444
|
-
const buildingsPhoneNumber = this.buildingWebchatView?.phoneNumber ?? "";
|
|
445
|
-
let phoneNumberForSource = null;
|
|
446
|
-
if (featureFlagUseDNI) {
|
|
447
|
-
phoneNumberForSource = await fetchPhoneNumberFromSource(
|
|
448
|
-
this.buildingSlug,
|
|
449
|
-
this.LeadSourceClient?.leadSource ?? null
|
|
450
|
-
);
|
|
451
|
-
|
|
452
|
-
// By default, we want to use the building's phone number, not the default catchall number
|
|
453
|
-
// https://meetelise.slack.com/archives/C01BT9GB9LZ/p1696437860448009
|
|
454
|
-
if (phoneNumberForSource && !phoneNumberForSource.isMatch) {
|
|
455
|
-
phoneNumberForSource.number = buildingsPhoneNumber;
|
|
456
|
-
}
|
|
457
|
-
if (!this.LeadSourceClient?.leadSource && phoneNumberForSource) {
|
|
458
|
-
phoneNumberForSource.number = buildingsPhoneNumber;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
if (featureFlagInsertDNIWebsite && phoneNumberForSource?.number) {
|
|
462
|
-
const totalReplacements = insertDNIIntoWebsite(
|
|
463
|
-
phoneNumberForSource.number,
|
|
464
|
-
this.orgSlug,
|
|
465
|
-
this.buildingSlug
|
|
466
|
-
);
|
|
467
|
-
if (totalReplacements > 0) {
|
|
468
|
-
logSignal({
|
|
469
|
-
params: {
|
|
470
|
-
org_slug: this.orgSlug,
|
|
471
|
-
building_slug: this.buildingSlug,
|
|
472
|
-
is_dni_insert_override_success: true,
|
|
473
|
-
extra_data: {
|
|
474
|
-
total_replacements: totalReplacements,
|
|
475
|
-
},
|
|
476
|
-
},
|
|
477
|
-
sampleRate: this.sampleRateToUse,
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const devTestPhoneNumber = localStorage.getItem(
|
|
483
|
-
"eliseai_phone_number_devtest"
|
|
484
|
-
);
|
|
485
|
-
if (devTestPhoneNumber) {
|
|
486
|
-
// eslint-disable-next-line no-console
|
|
487
|
-
console.info("Using dev test phone number: ", devTestPhoneNumber);
|
|
488
|
-
insertDNIIntoWebsite(devTestPhoneNumber, this.orgSlug, this.buildingSlug);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// if the building does NOT have IVR setup, we want to use the building's phone number
|
|
492
|
-
if (!phoneNumberForSource) {
|
|
493
|
-
this.phoneNumberForSource = {
|
|
494
|
-
number: buildingsPhoneNumber,
|
|
495
|
-
isMatch: false,
|
|
496
|
-
isPropertyWebsiteCatchall: true,
|
|
497
|
-
};
|
|
498
|
-
} else {
|
|
499
|
-
this.phoneNumberForSource = phoneNumberForSource;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
const currentLeadSource = this.LeadSourceClient?.leadSource ?? null;
|
|
503
|
-
if (currentLeadSource) {
|
|
504
|
-
if (!this.leadSources.includes(currentLeadSource)) {
|
|
505
|
-
this.leadSources.push(currentLeadSource);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
getRawAvailabilities(buildingDetails.id); // we're not using this here, just want to cache the result
|
|
509
|
-
|
|
510
|
-
if (featureFlagUseApplicationsLinkReplacement && this.buildingSlug) {
|
|
511
|
-
const totalReplacements = replaceSelectButtonsWithNewLink(
|
|
512
|
-
`https://applications.eliseai.com/building/${this.buildingSlug}`,
|
|
513
|
-
this.orgSlug,
|
|
514
|
-
this.buildingSlug
|
|
515
|
-
);
|
|
516
|
-
if (totalReplacements > 0) {
|
|
517
|
-
logSignal({
|
|
518
|
-
params: {
|
|
519
|
-
org_slug: this.orgSlug,
|
|
520
|
-
building_slug: this.buildingSlug,
|
|
521
|
-
is_application_link_replacement_success: true,
|
|
522
|
-
extra_data: {
|
|
523
|
-
total_replacements: totalReplacements,
|
|
524
|
-
},
|
|
525
|
-
},
|
|
526
|
-
sampleRate: this.sampleRateToUse,
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
private initializeChatVariables = async (): Promise<void> => {
|
|
533
|
-
if (!this.buildingWebchatView) return;
|
|
534
|
-
|
|
535
|
-
// important to distinguish between a user who has never opened the chat and a user who has opened the chat but closed it
|
|
536
|
-
const currentChatStorageKey = getChatStorageKey(this.buildingSlug);
|
|
537
|
-
const updatedChatStorageKey = isChatKeyValid(
|
|
538
|
-
this.buildingSlug,
|
|
539
|
-
currentChatStorageKey
|
|
540
|
-
)
|
|
541
|
-
? currentChatStorageKey
|
|
542
|
-
: createChatStorageKey(this.buildingSlug, false);
|
|
543
|
-
|
|
544
|
-
if (!updatedChatStorageKey.leadId) {
|
|
545
|
-
throw new Error("Lead ID is null");
|
|
546
|
-
}
|
|
547
|
-
this.LeadSourceClient = new LeadSourceClient();
|
|
548
|
-
this.myPubnub = new MyPubnub(
|
|
549
|
-
this.buildingSlug,
|
|
550
|
-
this.buildingWebchatView,
|
|
551
|
-
this.orgSlug,
|
|
552
|
-
null, // initialize lead source as null initially
|
|
553
|
-
updatedChatStorageKey.leadId,
|
|
554
|
-
this.LeadSourceClient,
|
|
555
|
-
this.widgetType
|
|
556
|
-
);
|
|
557
|
-
this.LeadSourceClient.chatId = this.myPubnub.channel;
|
|
558
|
-
await this.LeadSourceClient?.generateUserLeadSource({
|
|
559
|
-
leadId: this.myPubnub?.leadUserId ?? "",
|
|
560
|
-
orgSlug: this.orgSlug,
|
|
561
|
-
buildingSlug: this.buildingSlug,
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
// eslint-disable-next-line no-console
|
|
565
|
-
console.log(
|
|
566
|
-
"EliseAI Mapped Lead Source source: ",
|
|
567
|
-
this.LeadSourceClient?.leadSource
|
|
568
|
-
);
|
|
569
|
-
|
|
570
|
-
if (getDefaultLeadSourceAttribution(this.orgSlug) !== "property-website") {
|
|
571
|
-
this.myPubnub.leadSource =
|
|
572
|
-
this.LeadSourceClient?.leadSource ??
|
|
573
|
-
getDefaultLeadSourceAttribution(this.orgSlug);
|
|
574
|
-
} else {
|
|
575
|
-
this.myPubnub.leadSource = this.LeadSourceClient?.leadSource ?? null;
|
|
576
|
-
}
|
|
577
|
-
if (updatedChatStorageKey.initiatedChat) {
|
|
578
|
-
await this.myPubnub.initializePubnub(currentChatStorageKey);
|
|
579
|
-
}
|
|
580
|
-
};
|
|
581
|
-
|
|
582
|
-
private shouldAutoOpenChat = (buildingHasAutoOpen: boolean): boolean => {
|
|
583
|
-
const alreadyAutoOpenedTimestamp = sessionStorage.getItem(
|
|
584
|
-
"alreadyAutoOpenedTimestamp"
|
|
585
|
-
); // we dont want to autoopen on EVERY single page load, so we'll only do it once every 15 minutes max
|
|
586
|
-
const shouldAutoOpen =
|
|
587
|
-
!alreadyAutoOpenedTimestamp ||
|
|
588
|
-
!(
|
|
589
|
-
alreadyAutoOpenedTimestamp &&
|
|
590
|
-
!isPast(parseISO(alreadyAutoOpenedTimestamp))
|
|
591
|
-
);
|
|
592
|
-
return !!buildingHasAutoOpen && !!shouldAutoOpen && !isMobile();
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
private async handleChatInitializeAnalytics(): Promise<void> {
|
|
596
|
-
this.analytics = new Analytics(
|
|
597
|
-
this.orgSlug,
|
|
598
|
-
this.buildingSlug,
|
|
599
|
-
this.myPubnub?.channel ?? "", // this will be empty if the user does not have a current chat session.
|
|
600
|
-
this.LeadSourceClient?.leadSource ?? null
|
|
601
|
-
);
|
|
602
|
-
|
|
603
|
-
// Too many logs kills our DB, so we'll only log 5% of the time
|
|
604
|
-
if (Math.random() < 0.05) {
|
|
605
|
-
this.analytics.ping("webchat_heartbeat");
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
public async restartConversation(): Promise<void> {
|
|
610
|
-
this.myPubnub?.handleDisconnect();
|
|
611
|
-
clearChatStorageKey(this.buildingSlug);
|
|
612
|
-
this.myPubnub = null;
|
|
613
|
-
this.displayPubnubChat = false;
|
|
614
|
-
await this.setupWebchat();
|
|
615
|
-
this.hideLauncher = false;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
private updateAlreadyAutoOpenedTimestamp = (): void => {
|
|
619
|
-
sessionStorage.setItem(
|
|
620
|
-
"alreadyAutoOpenedTimestamp",
|
|
621
|
-
formatISO(addMinutes(new Date(), 15))
|
|
622
|
-
);
|
|
623
|
-
};
|
|
624
|
-
|
|
625
|
-
/** Show the chat button on the screen if it was previously hidden. */
|
|
626
|
-
show(): void {
|
|
627
|
-
if (!this.launcher) {
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
this.launcher.style.display = "";
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/** Hide the chat button from the screen (but don't remove from the DOM). */
|
|
634
|
-
hide(): void {
|
|
635
|
-
if (!this.launcher) {
|
|
636
|
-
return;
|
|
637
|
-
}
|
|
638
|
-
this.launcher.style.display = "none";
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
handleContactClicked = (e: MouseEvent): void => {
|
|
642
|
-
this.displayPubnubChat = false;
|
|
643
|
-
this.hideLauncher = false;
|
|
644
|
-
this.showTourNextToChat = false;
|
|
645
|
-
|
|
646
|
-
this.launcherRef.value?.onClickEmailOption(e);
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
handleTourClicked = (e: MouseEvent): void => {
|
|
650
|
-
if (this.showTourNextToChat) {
|
|
651
|
-
this.launcherRef.value?.onClickSSTOption(e);
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
if (!this.hideLauncher) {
|
|
655
|
-
this.displayPubnubChat = false;
|
|
656
|
-
} else {
|
|
657
|
-
this.showTourNextToChat = true;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
this.hideLauncher = false;
|
|
661
|
-
this.launcherRef.value?.onClickSSTOption(e);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
handleContactTabClicked = (e: MouseEvent): void => {
|
|
665
|
-
this.displayPubnubChat = false;
|
|
666
|
-
this.showTourNextToChat = false;
|
|
667
|
-
this.hideLauncher = false;
|
|
668
|
-
this.launcherRef.value?.onClickPhoneOption(e);
|
|
669
|
-
};
|
|
670
|
-
|
|
671
|
-
// Depending on the rendered element of the chat widget, we need to adjust the position of the chat additional actions
|
|
672
|
-
// these will be aligned at the bottom. It is much easier to handle here at the parent of the launchers rather than
|
|
673
|
-
// in pubnub-chat.
|
|
674
|
-
adjustPositionChatAdditionalActions = (): void => {
|
|
675
|
-
const headerRef = this.shadowRoot?.getElementById(
|
|
676
|
-
"chatAdditionalActionsPubnub"
|
|
677
|
-
);
|
|
678
|
-
if (!headerRef) return;
|
|
679
|
-
|
|
680
|
-
const pubnubContainerElement = this.shadowRoot
|
|
681
|
-
?.getElementById("pubnub-chat")
|
|
682
|
-
?.shadowRoot?.getElementById("pubnub-chat-container");
|
|
683
|
-
|
|
684
|
-
const pubnubPopupCoords = pubnubContainerElement?.getBoundingClientRect();
|
|
685
|
-
if (!pubnubPopupCoords) return;
|
|
686
|
-
headerRef.style.left = `${pubnubPopupCoords.left}px`;
|
|
687
|
-
headerRef.style.top = `${pubnubPopupCoords.bottom}px`;
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
connectedCallback(): void {
|
|
691
|
-
super.connectedCallback();
|
|
692
|
-
window.addEventListener("resize", this.adjustPositionChatAdditionalActions);
|
|
693
|
-
window.addEventListener("keydown", this.handleKeydownTab);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
handleKeydownTab = (e: KeyboardEvent): void => {
|
|
697
|
-
if (e.key === "Tab") {
|
|
698
|
-
const pubnubContainerElement = this.displayPubnubChat
|
|
699
|
-
? this.shadowRoot // pubnub chat
|
|
700
|
-
?.getElementById("pubnub-chat")
|
|
701
|
-
?.shadowRoot?.getElementById("pubnub-chat-container")
|
|
702
|
-
: this.shadowRoot // email us form
|
|
703
|
-
?.getElementById("meetelise-launcher")
|
|
704
|
-
?.shadowRoot?.getElementById("email-us-window")
|
|
705
|
-
?.shadowRoot?.getElementById("email-us-form") ??
|
|
706
|
-
this.shadowRoot // tour booking form
|
|
707
|
-
?.getElementById("meetelise-launcher")
|
|
708
|
-
?.shadowRoot?.getElementById("tour-scheduler-window")
|
|
709
|
-
?.shadowRoot?.getElementById("scheduler-container") ??
|
|
710
|
-
this.shadowRoot // text us form
|
|
711
|
-
?.getElementById("meetelise-launcher")
|
|
712
|
-
?.shadowRoot?.getElementById("call-us-window")
|
|
713
|
-
?.shadowRoot?.getElementById("details-window");
|
|
714
|
-
|
|
715
|
-
if (!pubnubContainerElement) return;
|
|
716
|
-
e.preventDefault();
|
|
717
|
-
|
|
718
|
-
const inputsRef = pubnubContainerElement.querySelectorAll(
|
|
719
|
-
"input, me-select, textarea, action-confirm-button, [tabindex]"
|
|
720
|
-
);
|
|
721
|
-
|
|
722
|
-
const inputsArray = Array.from(inputsRef) as HTMLElement[];
|
|
723
|
-
const currentFocusedIndex = inputsArray.findIndex((el) =>
|
|
724
|
-
el.matches(":focus")
|
|
725
|
-
);
|
|
726
|
-
|
|
727
|
-
const nextIndex = (currentFocusedIndex + 1) % inputsArray.length;
|
|
728
|
-
inputsArray[nextIndex].focus();
|
|
729
|
-
}
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
getDeepActiveElement(): Element | null {
|
|
733
|
-
let activeElement = document.activeElement;
|
|
734
|
-
let count = 0;
|
|
735
|
-
while (
|
|
736
|
-
activeElement?.shadowRoot &&
|
|
737
|
-
activeElement?.shadowRoot.activeElement
|
|
738
|
-
) {
|
|
739
|
-
count += 1;
|
|
740
|
-
activeElement = activeElement?.shadowRoot.activeElement;
|
|
741
|
-
if (count > 100) {
|
|
742
|
-
// just incase we get stuck in an infinite loop
|
|
743
|
-
sendLoggingEvent({
|
|
744
|
-
logType: LogType.error,
|
|
745
|
-
buildingSlug: this.buildingSlug,
|
|
746
|
-
logTitle: "[ERROR_GETTING_DEEP_ELEMENT]",
|
|
747
|
-
logData: { message: "error getting deep active element" },
|
|
748
|
-
});
|
|
749
|
-
break;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
return activeElement;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
updated(): void {
|
|
756
|
-
this.adjustPositionChatAdditionalActions();
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
disconnectedCallback(): void {
|
|
760
|
-
this.myPubnub?.handleDisconnect();
|
|
761
|
-
window.removeEventListener(
|
|
762
|
-
"resize",
|
|
763
|
-
this.adjustPositionChatAdditionalActions
|
|
764
|
-
);
|
|
765
|
-
window.removeEventListener("keydown", this.handleKeydownTab);
|
|
766
|
-
|
|
767
|
-
super.disconnectedCallback();
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
onClickMinimize = (e: MouseEvent): void => {
|
|
771
|
-
e.preventDefault();
|
|
772
|
-
e.stopPropagation();
|
|
773
|
-
this.isMinimized = !this.isMinimized;
|
|
774
|
-
this.showTourNextToChat = false;
|
|
775
|
-
};
|
|
776
|
-
|
|
777
|
-
private attachOnClickToLauncher = () => {
|
|
778
|
-
const launcher = this.launcherRef.value;
|
|
779
|
-
if (!launcher) {
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
launcher.onChatTapped = async () => {
|
|
784
|
-
this.displayPubnubChat = true;
|
|
785
|
-
this.hideLauncher = true;
|
|
786
|
-
this.hasMounted = true;
|
|
787
|
-
localStorage.setItem("isChatOpen", "true");
|
|
788
|
-
};
|
|
789
|
-
launcher.onExitChat = this.onExitChat;
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
onExitChat = (): void => {
|
|
793
|
-
this.displayPubnubChat = false;
|
|
794
|
-
this.hideLauncher = false;
|
|
795
|
-
this.showTourNextToChat = false;
|
|
796
|
-
localStorage.setItem("isChatOpen", "false");
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
render(): TemplateResult {
|
|
800
|
-
installLauncher();
|
|
801
|
-
const showChatAdditionalActions =
|
|
802
|
-
this.hideLauncher && !this.isLoading && !isMobile();
|
|
803
|
-
|
|
804
|
-
return html`
|
|
805
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
806
|
-
<div id="aria-describe-info" style="display: none;">
|
|
807
|
-
EliseAI widget that allows you to chat with a virtual assistant, book
|
|
808
|
-
a tour, contact the leasing office, and more.
|
|
809
|
-
</div>
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
${
|
|
813
|
-
this.displayPubnubChat
|
|
814
|
-
? html`
|
|
815
|
-
<pubnub-chat
|
|
816
|
-
id="pubnub-chat"
|
|
817
|
-
.channel=${this.myPubnub?.channel}
|
|
818
|
-
.myPubnub=${this.myPubnub}
|
|
819
|
-
.orgSlug=${this.orgSlug}
|
|
820
|
-
.buildingSlug=${this.buildingSlug}
|
|
821
|
-
.widgetType=${WidgetType.Default}
|
|
822
|
-
.building=${this.buildingWebchatView}
|
|
823
|
-
.primaryColor=${this.primaryColor}
|
|
824
|
-
.backgroundColor=${this.backgroundColor}
|
|
825
|
-
.onClickExit=${this.onExitChat}
|
|
826
|
-
.onMount=${() => {
|
|
827
|
-
this.adjustPositionChatAdditionalActions();
|
|
828
|
-
}}
|
|
829
|
-
.requiresConsent=${this.requiresConsent}
|
|
830
|
-
.hideMobileFeatures=${this.hideMobileFeatures}
|
|
831
|
-
.privacyPolicyUrl=${this.privacyPolicyUrl}
|
|
832
|
-
.top=${this.top}
|
|
833
|
-
.bottom=${this.bottom}
|
|
834
|
-
.left=${this.left}
|
|
835
|
-
.right=${this.right}
|
|
836
|
-
></pubnub-chat>
|
|
837
|
-
<chat-additional-actions
|
|
838
|
-
id="chatAdditionalActionsPubnub"
|
|
839
|
-
.showChatAdditionalActions=${showChatAdditionalActions ||
|
|
840
|
-
this.showTourNextToChat}
|
|
841
|
-
.buildingWebchatView=${this.buildingWebchatView}
|
|
842
|
-
.primaryColor=${this.primaryColor}
|
|
843
|
-
.backgroundColor=${this.backgroundColor}
|
|
844
|
-
.enabledChatWidgets=${this.enabledChatWidgets}
|
|
845
|
-
.onClickMinimize=${this.onClickMinimize}
|
|
846
|
-
.onClickEmailOption=${this.handleContactClicked}
|
|
847
|
-
.onClickPhoneOption=${this.handleContactTabClicked}
|
|
848
|
-
.onClickSSTOption=${this.handleTourClicked}
|
|
849
|
-
.onClose=${() => {
|
|
850
|
-
this.displayPubnubChat = false;
|
|
851
|
-
this.showTourNextToChat = false;
|
|
852
|
-
this.hideLauncher = false;
|
|
853
|
-
localStorage.setItem("isChatOpen", "false");
|
|
854
|
-
}}
|
|
855
|
-
></chat-additional-actions>
|
|
856
|
-
`
|
|
857
|
-
: ""
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
<div
|
|
861
|
-
id='meetelise-chat-launcher-container'
|
|
862
|
-
class=${classMap({
|
|
863
|
-
launcherContainer: true,
|
|
864
|
-
["launcher__mobile"]: isMobile(),
|
|
865
|
-
["launcher__desktop"]: !isMobile(),
|
|
866
|
-
["meetelise-chat"]: true,
|
|
867
|
-
launcher: true,
|
|
868
|
-
shouldBeVisible: true,
|
|
869
|
-
["hideTab"]: this.isLoading,
|
|
870
|
-
})}
|
|
871
|
-
>
|
|
872
|
-
${
|
|
873
|
-
this.buildingWebchatView
|
|
874
|
-
? html`<meetelise-launcher
|
|
875
|
-
id="meetelise-launcher"
|
|
876
|
-
${ref(this.launcherRef)}
|
|
877
|
-
.isFirstMount=${!this.hasMounted}
|
|
878
|
-
.buildingId=${this.buildingWebchatView?.id ?? 0}
|
|
879
|
-
.hasDynamicSchedulingEnabled=${this.buildingWebchatView
|
|
880
|
-
?.usesDynamicScheduling ?? false}
|
|
881
|
-
.orgLegalName=${this.buildingWebchatView?.orgLegalName ?? ""}
|
|
882
|
-
.tourTypeOptions=${this.buildingWebchatView
|
|
883
|
-
?.tourTypeOptions ?? []}
|
|
884
|
-
.launcherStyles=${this.launcherStyles}
|
|
885
|
-
.primaryColor=${this.primaryColor}
|
|
886
|
-
.backgroundColor=${this.backgroundColor}
|
|
887
|
-
.foregroundColorOnPrimaryBackgroundColor=${this
|
|
888
|
-
.foregroundColorOnPrimaryBackgroundColor ?? "white"}
|
|
889
|
-
.foregroundColorOnSecondaryBackgroundColor=${this
|
|
890
|
-
.foregroundColorOnSecondaryBackgroundColor ?? "black"}
|
|
891
|
-
.isMinimized=${this.isMinimized}
|
|
892
|
-
.onClickMinimize=${this.onClickMinimize}
|
|
893
|
-
.onSstClose=${this.onSstClose}
|
|
894
|
-
.overrideRentgrata=${this.overrideRentgrata}
|
|
895
|
-
.autoOpenChatWidget=${this.buildingWebchatView
|
|
896
|
-
?.autoOpenChat ?? false}
|
|
897
|
-
.mobileStyles=${isMobile() || this.isMinimized
|
|
898
|
-
? this.mobileStyles
|
|
899
|
-
: {}}
|
|
900
|
-
chatCallUsHeader=${this.buildingWebchatView
|
|
901
|
-
?.chatCallUsHeader ?? ""}
|
|
902
|
-
chatId="${this.chatId}"
|
|
903
|
-
phoneNumber="${this.phoneNumberForSource?.number ??
|
|
904
|
-
this.buildingWebchatView?.phoneNumber ??
|
|
905
|
-
""}"
|
|
906
|
-
buildingName=${this.buildingWebchatView?.name ?? ""}
|
|
907
|
-
orgSlug="${this.orgSlug}"
|
|
908
|
-
buildingSlug="${this.buildingSlug}"
|
|
909
|
-
sgtUrl="${this.buildingWebchatView?.sgtUrl ?? ""}"
|
|
910
|
-
selfGuidedToursTypeOffered="${this.buildingWebchatView
|
|
911
|
-
?.selfGuidedToursTypeOffered}"
|
|
912
|
-
selfGuidedTourEnabled="${this.buildingWebchatView
|
|
913
|
-
?.isSelfGuidedTourEnabled}"
|
|
914
|
-
designConcept="${this.designConcept ?? ""}"
|
|
915
|
-
currentLeadSource="${this.LeadSourceClient?.leadSource ??
|
|
916
|
-
null ??
|
|
917
|
-
""}"
|
|
918
|
-
featureFlagShowDropdown="${this.featureFlagShowDropdown}"
|
|
919
|
-
.leadSources="${this.leadSources ?? []}"
|
|
920
|
-
escortedToursLink="${this.buildingWebchatView
|
|
921
|
-
?.escortedToursLink ?? ""}"
|
|
922
|
-
virtualToursLink="${this.buildingWebchatView
|
|
923
|
-
?.virtualToursLink ?? ""}"
|
|
924
|
-
.showTourNextToChat="${this.showTourNextToChat ?? ""}"
|
|
925
|
-
@closeShowTourNextToChat=${() => {
|
|
926
|
-
this.showTourNextToChat = false;
|
|
927
|
-
this.hideLauncher = true;
|
|
928
|
-
}}
|
|
929
|
-
?hidden=${this.hideLauncher}
|
|
930
|
-
.hasCallUsEnabledDesktop=${this.enabledChatWidgets
|
|
931
|
-
.callDesktop}
|
|
932
|
-
.hasCallUsEnabledMobile=${this.enabledChatWidgets.callMobile}
|
|
933
|
-
.hasChatEnabledDesktop=${this.enabledChatWidgets.chatDesktop}
|
|
934
|
-
.hasChatEnabledMobile=${this.enabledChatWidgets.chatMobile}
|
|
935
|
-
.hasEmailEnabledDesktop=${this.enabledChatWidgets
|
|
936
|
-
.emailDesktop}
|
|
937
|
-
.hasEmailEnabledMobile=${this.enabledChatWidgets.emailMobile}
|
|
938
|
-
.hasTextUsEnabledDesktop=${this.enabledChatWidgets
|
|
939
|
-
.textDesktop}
|
|
940
|
-
.hasTextUsEnabledMobile=${this.enabledChatWidgets.textMobile}
|
|
941
|
-
.hasSSTEnabledDesktop=${this.enabledChatWidgets.sstDesktop}
|
|
942
|
-
.hasSSTEnabledMobile=${this.enabledChatWidgets.sstMobile}
|
|
943
|
-
.hasApplyNowEnabledDesktop=${this.buildingWebchatView
|
|
944
|
-
.shouldShowApplyNowDesktop}
|
|
945
|
-
.hasApplyNowEnabledMobile=${this.buildingWebchatView
|
|
946
|
-
.shouldShowApplyNowMobile}
|
|
947
|
-
.applicationLink=${this.buildingWebchatView.applicationLink}
|
|
948
|
-
.hasPricingCalculatorEnabledDesktop=${this.enabledChatWidgets
|
|
949
|
-
.calcDesktop}
|
|
950
|
-
.hasPricingCalculatorEnabledMobile=${this.enabledChatWidgets
|
|
951
|
-
.calcMobile}
|
|
952
|
-
.hasHideMobileFeatures=${this.hideMobileFeatures}
|
|
953
|
-
.top=${this.top}
|
|
954
|
-
.bottom=${this.bottom}
|
|
955
|
-
.left=${this.left}
|
|
956
|
-
.right=${this.right}
|
|
957
|
-
.leadSourceClient=${this.LeadSourceClient}
|
|
958
|
-
>
|
|
959
|
-
</meetelise-launcher>`
|
|
960
|
-
: ""
|
|
961
|
-
}
|
|
962
|
-
</div>
|
|
963
|
-
</meta>
|
|
964
|
-
`;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
declare global {
|
|
969
|
-
interface HTMLElementTagNameMap {
|
|
970
|
-
"me-chat": MEChat;
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
interface Window {
|
|
974
|
-
RCTPCampaign?: { CampaignDetails: { Source: string } };
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
const findElementById = (priorityIds: string[]): HTMLElement | null => {
|
|
979
|
-
for (const id of priorityIds) {
|
|
980
|
-
const element = document.getElementById(id);
|
|
981
|
-
if (element) {
|
|
982
|
-
return element;
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return null;
|
|
986
|
-
};
|
|
987
|
-
|
|
988
|
-
const overrideContactUsForm = async (
|
|
989
|
-
orgSlug: string,
|
|
990
|
-
chatId: string | null,
|
|
991
|
-
sampleRateToUse: number,
|
|
992
|
-
buildingSlug?: string,
|
|
993
|
-
leadSource?: string | null
|
|
994
|
-
): Promise<void> => {
|
|
995
|
-
if (!buildingSlug || !orgSlug) return;
|
|
996
|
-
const shouldUseOverrideContactUsForm =
|
|
997
|
-
await fetchFeatureFlagUseOverrideContactUsForm(buildingSlug);
|
|
998
|
-
if (!shouldUseOverrideContactUsForm) return;
|
|
999
|
-
|
|
1000
|
-
const form = findElementById([
|
|
1001
|
-
"myContactForm",
|
|
1002
|
-
"contactus",
|
|
1003
|
-
"fpa-myContactForm",
|
|
1004
|
-
]);
|
|
1005
|
-
let btn = undefined;
|
|
1006
|
-
|
|
1007
|
-
if (!form || !(form instanceof HTMLFormElement)) {
|
|
1008
|
-
const foundForm = document.querySelector("form");
|
|
1009
|
-
if (window.location.pathname.toLowerCase().includes("contactus")) {
|
|
1010
|
-
logContactUsFormError(
|
|
1011
|
-
buildingSlug,
|
|
1012
|
-
orgSlug,
|
|
1013
|
-
"Could not find form",
|
|
1014
|
-
foundForm ? { id: foundForm.id } : undefined
|
|
1015
|
-
);
|
|
1016
|
-
}
|
|
1017
|
-
return;
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
// If the form is apart of the schedule tour form, do not override
|
|
1021
|
-
// https://meetelise.slack.com/archives/C01BT9GB9LZ/p1706132172167819
|
|
1022
|
-
try {
|
|
1023
|
-
if (form.parentElement && form.parentElement.id === "scheduleTourForm") {
|
|
1024
|
-
return logContactUsFormError(
|
|
1025
|
-
buildingSlug,
|
|
1026
|
-
orgSlug,
|
|
1027
|
-
"Form is apart of schedule tour form!"
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
} catch (error) {
|
|
1031
|
-
// eslint-disable-next-line no-console
|
|
1032
|
-
console.error("error", error);
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
// Loop through the elements of the form
|
|
1036
|
-
for (let i = 0; i < form.elements.length; i++) {
|
|
1037
|
-
const element = form.elements[i];
|
|
1038
|
-
if (
|
|
1039
|
-
element.tagName.toLowerCase() === "button" &&
|
|
1040
|
-
element.getAttribute("data-selenium-id") === "fakebutton"
|
|
1041
|
-
) {
|
|
1042
|
-
btn = element;
|
|
1043
|
-
break;
|
|
1044
|
-
}
|
|
1045
|
-
if (element.getAttribute("id") === "fpa-contact-submit") {
|
|
1046
|
-
btn = element;
|
|
1047
|
-
break;
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
if (!btn) {
|
|
1052
|
-
return logContactUsFormError(
|
|
1053
|
-
buildingSlug,
|
|
1054
|
-
orgSlug,
|
|
1055
|
-
"Could not find submit button"
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
const eliseUrl =
|
|
1060
|
-
"https://app.meetelise.com/platformApi/state/create/contactMe";
|
|
1061
|
-
|
|
1062
|
-
const getFormElements = () => {
|
|
1063
|
-
const firstName = findElementById([
|
|
1064
|
-
"firstname",
|
|
1065
|
-
"txtName",
|
|
1066
|
-
"fpa-firstname",
|
|
1067
|
-
"Form_FirstName",
|
|
1068
|
-
]) as HTMLInputElement | null;
|
|
1069
|
-
const lastName = findElementById([
|
|
1070
|
-
"lastname",
|
|
1071
|
-
"txtName2",
|
|
1072
|
-
"fpa-lastname",
|
|
1073
|
-
"Form_LastName",
|
|
1074
|
-
]) as HTMLInputElement | null;
|
|
1075
|
-
const email = findElementById([
|
|
1076
|
-
"email",
|
|
1077
|
-
"txtEmail",
|
|
1078
|
-
"fpa-email",
|
|
1079
|
-
"Form_Email",
|
|
1080
|
-
]) as HTMLInputElement | null;
|
|
1081
|
-
const phone = findElementById([
|
|
1082
|
-
"phonenumber",
|
|
1083
|
-
"txtPhone",
|
|
1084
|
-
"fpa-phonenumber",
|
|
1085
|
-
"Form_Phone",
|
|
1086
|
-
]) as HTMLInputElement | null;
|
|
1087
|
-
const message = findElementById([
|
|
1088
|
-
"message",
|
|
1089
|
-
"txtComments",
|
|
1090
|
-
"fpa-email",
|
|
1091
|
-
"Form_Message",
|
|
1092
|
-
]) as HTMLTextAreaElement | null;
|
|
1093
|
-
|
|
1094
|
-
const formElements = { firstName, lastName, email, phone, message };
|
|
1095
|
-
return formElements;
|
|
1096
|
-
};
|
|
1097
|
-
|
|
1098
|
-
const isMissingFormElements = () => {
|
|
1099
|
-
if (Object.values(getFormElements()).some((el) => el === null)) {
|
|
1100
|
-
return true;
|
|
1101
|
-
}
|
|
1102
|
-
return false;
|
|
1103
|
-
};
|
|
1104
|
-
|
|
1105
|
-
const validateFormElements = () => {
|
|
1106
|
-
Object.values(getFormElements()).forEach((el) => {
|
|
1107
|
-
if (el?.getAttribute("aria-required") === "true" && !el.value) {
|
|
1108
|
-
el.className = "form-control required is-invalid";
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
};
|
|
1112
|
-
|
|
1113
|
-
const isValid = () => {
|
|
1114
|
-
return Object.values(getFormElements()).every((el) => {
|
|
1115
|
-
if (el === null) return false;
|
|
1116
|
-
if (el.getAttribute("aria-required") === "true" && !el.value) {
|
|
1117
|
-
return false;
|
|
1118
|
-
}
|
|
1119
|
-
if (
|
|
1120
|
-
(el.id === "email" || el.id === "phonenumber") &&
|
|
1121
|
-
el.getAttribute("aria-invalid") === "true"
|
|
1122
|
-
) {
|
|
1123
|
-
return false;
|
|
1124
|
-
}
|
|
1125
|
-
return true;
|
|
1126
|
-
});
|
|
1127
|
-
};
|
|
1128
|
-
|
|
1129
|
-
if (isMissingFormElements()) {
|
|
1130
|
-
const missingElements = Object.entries(getFormElements())
|
|
1131
|
-
.filter(([, val]) => val === null)
|
|
1132
|
-
.map(([key]) => key);
|
|
1133
|
-
return logContactUsFormError(
|
|
1134
|
-
buildingSlug,
|
|
1135
|
-
orgSlug,
|
|
1136
|
-
"Missing the following form elements: " + missingElements.join(", ")
|
|
1137
|
-
);
|
|
1138
|
-
}
|
|
1139
|
-
const originalButtonText = btn.textContent;
|
|
1140
|
-
|
|
1141
|
-
// Replace the original form element with the cloned one
|
|
1142
|
-
const clonedButton = btn.cloneNode(true) as HTMLButtonElement;
|
|
1143
|
-
btn.parentNode?.replaceChild(clonedButton, btn);
|
|
1144
|
-
|
|
1145
|
-
if (clonedButton) {
|
|
1146
|
-
logSignal({
|
|
1147
|
-
params: {
|
|
1148
|
-
chat_id: chatId,
|
|
1149
|
-
org_slug: orgSlug,
|
|
1150
|
-
building_slug: buildingSlug,
|
|
1151
|
-
is_form_override_success: true,
|
|
1152
|
-
},
|
|
1153
|
-
sampleRate: sampleRateToUse,
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
clonedButton.onclick = async function (event) {
|
|
1158
|
-
validateFormElements();
|
|
1159
|
-
|
|
1160
|
-
if (!isValid()) return;
|
|
1161
|
-
event.preventDefault();
|
|
1162
|
-
|
|
1163
|
-
clonedButton.textContent = "Processing request...";
|
|
1164
|
-
clonedButton.disabled = true;
|
|
1165
|
-
|
|
1166
|
-
const formValues: { [key: string]: string | undefined } = {};
|
|
1167
|
-
Object.entries(getFormElements()).forEach(
|
|
1168
|
-
([key, val]) => (formValues[key] = val?.value)
|
|
1169
|
-
);
|
|
1170
|
-
|
|
1171
|
-
const buildingWebchatView = await fetchBuildingWebchatView(
|
|
1172
|
-
orgSlug,
|
|
1173
|
-
buildingSlug
|
|
1174
|
-
);
|
|
1175
|
-
|
|
1176
|
-
if (!buildingWebchatView) {
|
|
1177
|
-
logContactUsFormError(buildingSlug, orgSlug, "Could not find building");
|
|
1178
|
-
return null;
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
const data = {
|
|
1182
|
-
email_address: formValues.email,
|
|
1183
|
-
first_name: formValues.firstName,
|
|
1184
|
-
last_name: formValues.lastName,
|
|
1185
|
-
phone_number: formValues.phone,
|
|
1186
|
-
first_message: formValues.message,
|
|
1187
|
-
building_id: buildingWebchatView.id,
|
|
1188
|
-
is_external_form: true,
|
|
1189
|
-
lead_sources: [
|
|
1190
|
-
...new Set(
|
|
1191
|
-
leadSource
|
|
1192
|
-
? [leadSource, getDefaultLeadSourceAttribution(orgSlug)]
|
|
1193
|
-
: [getDefaultLeadSourceAttribution(orgSlug)]
|
|
1194
|
-
),
|
|
1195
|
-
],
|
|
1196
|
-
};
|
|
1197
|
-
|
|
1198
|
-
const jsonData = JSON.stringify(data);
|
|
1199
|
-
|
|
1200
|
-
fetch(eliseUrl, {
|
|
1201
|
-
method: "POST",
|
|
1202
|
-
headers: {
|
|
1203
|
-
"Content-Type": "application/json",
|
|
1204
|
-
"building-slug": buildingSlug,
|
|
1205
|
-
"org-slug": orgSlug,
|
|
1206
|
-
},
|
|
1207
|
-
body: jsonData,
|
|
1208
|
-
})
|
|
1209
|
-
.then((response) => {
|
|
1210
|
-
if (!response.ok) {
|
|
1211
|
-
throw new Error(`HTTP error ${response.status}`);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
if (form) {
|
|
1215
|
-
form.reset();
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
Object.values(getFormElements()).forEach((el) => {
|
|
1219
|
-
if (!el) return;
|
|
1220
|
-
el.disabled = true;
|
|
1221
|
-
});
|
|
1222
|
-
clonedButton.textContent = "Submitted";
|
|
1223
|
-
clonedButton.disabled = true;
|
|
1224
|
-
|
|
1225
|
-
return response.json();
|
|
1226
|
-
})
|
|
1227
|
-
.catch(() => {
|
|
1228
|
-
clonedButton.textContent = originalButtonText;
|
|
1229
|
-
});
|
|
1230
|
-
};
|
|
1231
|
-
};
|
|
1232
|
-
|
|
1233
|
-
const logContactUsFormError = (
|
|
1234
|
-
buildingSlug: string,
|
|
1235
|
-
orgSlug: string,
|
|
1236
|
-
reason?: string,
|
|
1237
|
-
formIdInfo?: Record<string, unknown>
|
|
1238
|
-
) => {
|
|
1239
|
-
const url = `https://app.meetelise.com/platformApi/webchat/form-override-error`;
|
|
1240
|
-
const body = JSON.stringify({
|
|
1241
|
-
orgSlug,
|
|
1242
|
-
buildingSlug,
|
|
1243
|
-
reason,
|
|
1244
|
-
url: window.location.href,
|
|
1245
|
-
formIdInfo,
|
|
1246
|
-
});
|
|
1247
|
-
|
|
1248
|
-
fetch(url, {
|
|
1249
|
-
method: "POST",
|
|
1250
|
-
headers: {
|
|
1251
|
-
"Content-Type": "application/json",
|
|
1252
|
-
"building-slug": buildingSlug,
|
|
1253
|
-
"org-slug": orgSlug,
|
|
1254
|
-
},
|
|
1255
|
-
body,
|
|
1256
|
-
});
|
|
1257
|
-
};
|