@meetelise/chat 1.34.7 → 1.35.1
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/dist/src/MyPubnub.d.ts +116 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/addon-item-matrix-qty-selector/addon-item-matrix-qty-selector-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/addon-item-matrix-qty-selector/addon-item-matrix-qty-selector.d.ts +28 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/addon-item-qty-selector/addon-item-qty-selector-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/addon-item-qty-selector/addon-item-qty-selector.d.ts +18 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/common-addon-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/rentable-item-qty-selector/rentable-item-qty-selector-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/rentable-item-qty-selector/rentable-item-qty-selector.d.ts +22 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.d.ts +46 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card.d.ts +21 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item.d.ts +13 -0
- package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.d.ts +34 -0
- package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.d.ts +18 -0
- package/dist/src/WebComponent/FeeCalculator/components/incentive-banner/incentive-banner-styles.d.ts +1 -0
- package/dist/src/WebComponent/FeeCalculator/components/incentive-banner/incentive-banner.d.ts +8 -0
- package/dist/src/WebComponent/FeeCalculator/components/incentive-banner/index.d.ts +1 -0
- package/dist/src/WebComponent/FeeCalculator/components/index.d.ts +5 -0
- package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card.d.ts +13 -0
- package/dist/src/WebComponent/FeeCalculator/constants.d.ts +3 -0
- package/dist/src/WebComponent/FeeCalculator/fee-calculator-styles.d.ts +1 -0
- package/dist/src/WebComponent/FeeCalculator/fee-calculator.d.ts +55 -0
- package/dist/src/WebComponent/FeeCalculator/index.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/model/building-fee-view.d.ts +41 -0
- package/dist/src/WebComponent/FeeCalculator/model/building-fee.d.ts +82 -0
- package/dist/src/WebComponent/FeeCalculator/model/desired-addon.d.ts +5 -0
- package/dist/src/WebComponent/FeeCalculator/model/desired-rentable-item.d.ts +4 -0
- package/dist/src/WebComponent/FeeCalculator/model/index.d.ts +13 -0
- package/dist/src/WebComponent/FeeCalculator/model/item-combination.d.ts +6 -0
- package/dist/src/WebComponent/FeeCalculator/model/item-quantity.d.ts +4 -0
- package/dist/src/WebComponent/FeeCalculator/model/pricing-matrix.d.ts +18 -0
- package/dist/src/WebComponent/FeeCalculator/model/pricing-rule.d.ts +8 -0
- package/dist/src/WebComponent/FeeCalculator/model/rent-frequency.d.ts +1 -0
- package/dist/src/WebComponent/FeeCalculator/model/rentable-item-summary.d.ts +9 -0
- package/dist/src/WebComponent/FeeCalculator/model/rentable-item.d.ts +9 -0
- package/dist/src/WebComponent/FeeCalculator/model/transaction-category.d.ts +23 -0
- package/dist/src/WebComponent/FeeCalculator/model/unit-fee-bundle.d.ts +31 -0
- package/dist/src/WebComponent/LeadSourceClient.d.ts +46 -0
- package/dist/src/WebComponent/OfficeHours.d.ts +21 -0
- package/dist/src/WebComponent/Scheduler/date-picker.d.ts +28 -0
- package/dist/src/WebComponent/Scheduler/time-picker.d.ts +16 -0
- package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +102 -0
- package/dist/src/WebComponent/Scheduler/tour-type-option.d.ts +13 -0
- package/dist/src/WebComponent/Scheduler/tourSchedulerStyles.d.ts +1 -0
- package/dist/src/WebComponent/actions/InputStyles.d.ts +1 -0
- package/dist/src/WebComponent/actions/action-confirm-button.d.ts +13 -0
- package/dist/src/WebComponent/actions/call-us-window.d.ts +37 -0
- package/dist/src/WebComponent/actions/collapse-expand-button.d.ts +8 -0
- package/dist/src/WebComponent/actions/details-window.d.ts +14 -0
- package/dist/src/WebComponent/actions/email-us-window.d.ts +46 -0
- package/dist/src/WebComponent/actions/formatPhoneNumber.d.ts +17 -0
- package/dist/src/WebComponent/actions/minimize-expand-button.d.ts +8 -0
- package/dist/src/WebComponent/chat-additional-actions.d.ts +28 -0
- package/dist/src/WebComponent/health-chat.d.ts +47 -0
- package/dist/src/WebComponent/healthchat-styles.d.ts +1 -0
- package/dist/src/WebComponent/icons/ApplyOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/BookTourOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/CalculatorOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/ChatOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/ChevronLeftIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/ChevronRightIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/ContactResidentIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/DollarOutlineIcon.d.ts +7 -0
- package/dist/src/WebComponent/icons/EmailOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/HeyThereEmojiIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/PhoneOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/SendMessageIcon.d.ts +3 -0
- package/dist/src/WebComponent/icons/TourSelfGuidedIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/TourVirtuallyIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/TourWithAgentIcon.d.ts +2 -0
- package/dist/src/WebComponent/icons/XOutlineIcon.d.ts +2 -0
- package/dist/src/WebComponent/index.d.ts +2 -0
- package/dist/src/WebComponent/launcher/Launcher.d.ts +99 -0
- package/dist/src/WebComponent/launcher/launcherStyles.d.ts +1 -0
- package/dist/src/WebComponent/launcher/mobile-launcher.d.ts +27 -0
- package/dist/src/WebComponent/launcher/typeEmojiStyles.d.ts +1 -0
- package/dist/src/WebComponent/launcher/typeMiniStyles.d.ts +1 -0
- package/dist/src/WebComponent/launcher/typeMobileStyles.d.ts +1 -0
- package/dist/src/WebComponent/leasing-chat-styles.d.ts +1 -0
- package/dist/src/WebComponent/loaders/index.d.ts +4 -0
- package/dist/src/WebComponent/loaders/mega-loader.d.ts +7 -0
- package/dist/src/WebComponent/loaders/skeleton-card.d.ts +12 -0
- package/dist/src/WebComponent/loaders/skeleton-loader-styles.d.ts +3 -0
- package/dist/src/WebComponent/loaders/skeleton-loader.d.ts +13 -0
- package/dist/src/WebComponent/me-chat.d.ts +91 -0
- package/dist/src/WebComponent/me-select.d.ts +24 -0
- package/dist/src/WebComponent/mini-loader.d.ts +5 -0
- package/dist/src/WebComponent/pubnub-chat-styles.d.ts +1 -0
- package/dist/src/WebComponent/pubnub-chat.d.ts +48 -0
- package/dist/src/WebComponent/pubnub-media.d.ts +14 -0
- package/dist/src/WebComponent/pubnub-message-styles.d.ts +1 -0
- package/dist/src/WebComponent/pubnub-message.d.ts +39 -0
- package/dist/src/WebComponent/simple-launcher/simple-launcher-styles.d.ts +1 -0
- package/dist/src/WebComponent/simple-launcher/simple-launcher.d.ts +12 -0
- package/dist/src/WebComponent/utilities-chat.d.ts +47 -0
- package/dist/src/WebComponent/utilities-styles.d.ts +1 -0
- package/dist/src/WebComponent/utils.d.ts +31 -0
- package/dist/src/analytics.d.ts +64 -0
- package/dist/src/disclaimers.d.ts +16 -0
- package/dist/src/fetchBuildingABTestType.d.ts +8 -0
- package/dist/src/fetchBuildingInfo.d.ts +58 -0
- package/dist/src/fetchBuildingWebchatView.d.ts +124 -0
- package/dist/src/fetchFeatureFlag.d.ts +14 -0
- package/dist/src/fetchLeadSources.d.ts +4 -0
- package/dist/src/fetchPhoneNumberFromSource.d.ts +6 -0
- package/dist/src/getAvailabilities.d.ts +46 -0
- package/dist/src/getBuildingPhoneNumber.d.ts +1 -0
- package/dist/src/getShouldAllowScheduling.d.ts +1 -0
- package/dist/src/getShouldShowWebchat.d.ts +3 -0
- package/dist/src/getTimezoneString.d.ts +1 -0
- package/dist/src/globals.d.ts +2 -0
- package/dist/src/gtm.d.ts +6 -0
- package/dist/src/handleChatId.d.ts +11 -0
- package/dist/src/insertDNIIntoWebsite.d.ts +5 -0
- package/dist/src/insertLeadSourceIntoSchedulerLinks.d.ts +4 -0
- package/dist/src/main/MEChat.d.ts +74 -0
- package/dist/src/main/utils.d.ts +2 -0
- package/dist/src/postLeadSources.d.ts +3 -0
- package/dist/src/rentgrata.d.ts +4 -0
- package/dist/src/replaceSelectButtonsWithNewLink.d.ts +5 -0
- package/dist/src/services/fees/calculateQuote.d.ts +14 -0
- package/dist/src/services/fees/fetchBuildingFeesV2.d.ts +10 -0
- package/dist/src/services/fees/fetchBuildingUnits.d.ts +29 -0
- package/dist/src/services/fees/utils.d.ts +1 -0
- package/dist/src/svgIcons.d.ts +5 -0
- package/dist/src/themes.d.ts +5 -0
- package/dist/src/types/incentive-v2.d.ts +23 -0
- package/dist/src/types/rest-sdk.types.d.ts +11 -0
- package/dist/src/types/webchat-no-show-reason.d.ts +1 -0
- package/dist/src/utils/getWidgetOverrides.d.ts +39 -0
- package/dist/src/utils/queryParamBuilder.d.ts +8 -0
- package/dist/src/utils.d.ts +13 -0
- package/package.json +1 -1
- package/public/dist/index.js +41 -41
- package/src/MyPubnub.ts +792 -0
- package/src/WebComponent/FeeCalculator/components/addons/addon-item-matrix-qty-selector/addon-item-matrix-qty-selector-styles.ts +35 -0
- package/src/WebComponent/FeeCalculator/components/addons/addon-item-matrix-qty-selector/addon-item-matrix-qty-selector.ts +206 -0
- package/src/WebComponent/FeeCalculator/components/addons/addon-item-qty-selector/addon-item-qty-selector-styles.ts +6 -0
- package/src/WebComponent/FeeCalculator/components/addons/addon-item-qty-selector/addon-item-qty-selector.ts +101 -0
- package/src/WebComponent/FeeCalculator/components/addons/common-addon-styles.ts +82 -0
- package/src/WebComponent/FeeCalculator/components/addons/rentable-item-qty-selector/rentable-item-qty-selector-styles.ts +9 -0
- package/src/WebComponent/FeeCalculator/components/addons/rentable-item-qty-selector/rentable-item-qty-selector.ts +124 -0
- package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.ts +142 -0
- package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts +243 -0
- package/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.ts +65 -0
- package/src/WebComponent/FeeCalculator/components/fee-card/fee-card.ts +91 -0
- package/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.ts +44 -0
- package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +38 -0
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +151 -0
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +248 -0
- package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.ts +82 -0
- package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts +76 -0
- package/src/WebComponent/FeeCalculator/components/incentive-banner/incentive-banner-styles.ts +40 -0
- package/src/WebComponent/FeeCalculator/components/incentive-banner/incentive-banner.ts +43 -0
- package/src/WebComponent/FeeCalculator/components/incentive-banner/index.ts +1 -0
- package/src/WebComponent/FeeCalculator/components/index.ts +5 -0
- package/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.ts +39 -0
- package/src/WebComponent/FeeCalculator/components/promo-card/promo-card.ts +39 -0
- package/src/WebComponent/FeeCalculator/constants.ts +5 -0
- package/src/WebComponent/FeeCalculator/fee-calculator-styles.ts +310 -0
- package/src/WebComponent/FeeCalculator/fee-calculator.ts +341 -0
- package/src/WebComponent/FeeCalculator/index.ts +4 -0
- package/src/WebComponent/FeeCalculator/model/building-fee-view.ts +84 -0
- package/src/WebComponent/FeeCalculator/model/building-fee.ts +126 -0
- package/src/WebComponent/FeeCalculator/model/desired-addon.ts +6 -0
- package/src/WebComponent/FeeCalculator/model/desired-rentable-item.ts +4 -0
- package/src/WebComponent/FeeCalculator/model/index.ts +13 -0
- package/src/WebComponent/FeeCalculator/model/item-combination.ts +16 -0
- package/src/WebComponent/FeeCalculator/model/item-quantity.ts +4 -0
- package/src/WebComponent/FeeCalculator/model/pricing-matrix.ts +45 -0
- package/src/WebComponent/FeeCalculator/model/pricing-rule.ts +9 -0
- package/src/WebComponent/FeeCalculator/model/rent-frequency.ts +1 -0
- package/src/WebComponent/FeeCalculator/model/rentable-item-summary.ts +10 -0
- package/src/WebComponent/FeeCalculator/model/rentable-item.ts +10 -0
- package/src/WebComponent/FeeCalculator/model/transaction-category.ts +23 -0
- package/src/WebComponent/FeeCalculator/model/unit-fee-bundle.ts +54 -0
- package/src/WebComponent/LeadSourceClient.ts +332 -0
- package/src/WebComponent/MEChat.css +5 -0
- package/src/WebComponent/OfficeHours.ts +73 -0
- package/src/WebComponent/Scheduler/date-picker.ts +405 -0
- package/src/WebComponent/Scheduler/time-picker.ts +195 -0
- package/src/WebComponent/Scheduler/tour-scheduler.ts +1430 -0
- package/src/WebComponent/Scheduler/tour-type-option.ts +112 -0
- package/src/WebComponent/Scheduler/tourSchedulerStyles.ts +418 -0
- package/src/WebComponent/actions/InputStyles.ts +57 -0
- package/src/WebComponent/actions/action-confirm-button.ts +125 -0
- package/src/WebComponent/actions/call-us-window.ts +467 -0
- package/src/WebComponent/actions/collapse-expand-button.ts +65 -0
- package/src/WebComponent/actions/details-window.ts +150 -0
- package/src/WebComponent/actions/email-us-window.ts +556 -0
- package/src/WebComponent/actions/formatPhoneNumber.ts +72 -0
- package/src/WebComponent/actions/minimize-expand-button.ts +93 -0
- package/src/WebComponent/chat-additional-actions.ts +135 -0
- package/src/WebComponent/health-chat.ts +270 -0
- package/src/WebComponent/healthchat-styles.ts +119 -0
- package/src/WebComponent/icons/ApplyOutlineIcon.ts +22 -0
- package/src/WebComponent/icons/BookTourOutlineIcon.ts +13 -0
- package/src/WebComponent/icons/CalculatorOutlineIcon.ts +22 -0
- package/src/WebComponent/icons/ChatOutlineIcon.ts +10 -0
- package/src/WebComponent/icons/ChevronLeftIcon.ts +7 -0
- package/src/WebComponent/icons/ChevronRightIcon.ts +7 -0
- package/src/WebComponent/icons/ContactResidentIcon.ts +9 -0
- package/src/WebComponent/icons/DollarOutlineIcon.ts +26 -0
- package/src/WebComponent/icons/EmailOutlineIcon.ts +7 -0
- package/src/WebComponent/icons/HeyThereEmojiIcon.ts +12 -0
- package/src/WebComponent/icons/PhoneOutlineIcon.ts +7 -0
- package/src/WebComponent/icons/SendMessageIcon.ts +17 -0
- package/src/WebComponent/icons/TourSelfGuidedIcon.ts +17 -0
- package/src/WebComponent/icons/TourVirtuallyIcon.ts +17 -0
- package/src/WebComponent/icons/TourWithAgentIcon.ts +17 -0
- package/src/WebComponent/icons/XOutlineIcon.ts +8 -0
- package/src/WebComponent/index.ts +2 -0
- package/src/WebComponent/launcher/Launcher.ts +1284 -0
- package/src/WebComponent/launcher/launcherStyles.ts +500 -0
- package/src/WebComponent/launcher/mobile-launcher.ts +162 -0
- package/src/WebComponent/launcher/typeEmojiStyles.ts +161 -0
- package/src/WebComponent/launcher/typeMiniStyles.ts +60 -0
- package/src/WebComponent/launcher/typeMobileStyles.ts +50 -0
- package/src/WebComponent/leasing-chat-styles.ts +114 -0
- package/src/WebComponent/loaders/index.ts +7 -0
- package/src/WebComponent/loaders/mega-loader.ts +36 -0
- package/src/WebComponent/loaders/skeleton-card.ts +31 -0
- package/src/WebComponent/loaders/skeleton-loader-styles.ts +112 -0
- package/src/WebComponent/loaders/skeleton-loader.ts +34 -0
- package/src/WebComponent/me-chat.ts +1264 -0
- package/src/WebComponent/me-select.ts +322 -0
- package/src/WebComponent/mini-loader.ts +28 -0
- package/src/WebComponent/pubnub-chat-styles.ts +204 -0
- package/src/WebComponent/pubnub-chat.ts +771 -0
- package/src/WebComponent/pubnub-media.ts +208 -0
- package/src/WebComponent/pubnub-message-styles.ts +54 -0
- package/src/WebComponent/pubnub-message.ts +431 -0
- package/src/WebComponent/simple-launcher/simple-launcher-styles.ts +34 -0
- package/src/WebComponent/simple-launcher/simple-launcher.ts +100 -0
- package/src/WebComponent/utilities-chat.ts +270 -0
- package/src/WebComponent/utilities-styles.ts +110 -0
- package/src/WebComponent/utils.ts +82 -0
- package/src/analytics.ts +217 -0
- package/src/assetUrls.ts +6 -0
- package/src/disclaimers.ts +301 -0
- package/src/fetchBuildingABTestType.ts +21 -0
- package/src/fetchBuildingInfo.ts +88 -0
- package/src/fetchBuildingWebchatView.ts +176 -0
- package/src/fetchFeatureFlag.ts +250 -0
- package/src/fetchLeadSources.ts +98 -0
- package/src/fetchPhoneNumberFromSource.ts +31 -0
- package/src/fetchWebchatPreferences.ts +54 -0
- package/src/getAvailabilities.ts +189 -0
- package/src/getBuildingPhoneNumber.ts +26 -0
- package/src/getShouldAllowScheduling.ts +16 -0
- package/src/getShouldShowWebchat.ts +114 -0
- package/src/getTimezoneString.ts +40 -0
- package/src/globals.ts +3 -0
- package/src/gtm.ts +17 -0
- package/src/handleChatId.ts +101 -0
- package/src/insertDNIIntoWebsite.ts +146 -0
- package/src/insertLeadSourceIntoSchedulerLinks.ts +71 -0
- package/src/main/MEChat.test.ts +110 -0
- package/src/main/MEChat.ts +404 -0
- package/src/main/utils.ts +70 -0
- package/src/postLeadSources.ts +44 -0
- package/src/rentgrata.ts +74 -0
- package/src/replaceSelectButtonsWithNewLink.ts +91 -0
- package/src/services/fees/calculateQuote.ts +74 -0
- package/src/services/fees/fetchBuildingFees.ts +50 -0
- package/src/services/fees/fetchBuildingFeesV2.ts +56 -0
- package/src/services/fees/fetchBuildingFloorplans.ts +74 -0
- package/src/services/fees/fetchBuildingUnits.ts +86 -0
- package/src/services/fees/utils.ts +4 -0
- package/src/svgIcons.ts +14 -0
- package/src/themes.ts +65 -0
- package/src/types/incentive-v2.ts +24 -0
- package/src/types/rest-sdk.types.ts +13 -0
- package/src/types/webchat-no-show-reason.ts +6 -0
- package/src/utils/getWidgetOverrides.ts +91 -0
- package/src/utils/queryParamBuilder.ts +28 -0
- package/src/utils.ts +121 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// DEPRECATED: This function is no longer used. It was used to insert the lead source into the scheduler links.
|
|
2
|
+
// We now prevent the redirect and force tour SST widget to open instead in replaceSSTLinkWithTourWidgetTrigger.ts.
|
|
3
|
+
export const insertLeadSourceIntoSchedulerLinks = (
|
|
4
|
+
leadSource: string
|
|
5
|
+
): void => {
|
|
6
|
+
const links = document.querySelectorAll("a");
|
|
7
|
+
links.forEach(function (link) {
|
|
8
|
+
const href = link.getAttribute("href");
|
|
9
|
+
if (href && href.startsWith("https://app.meetelise.com/")) {
|
|
10
|
+
const separator = href.includes("?") ? "&" : "?";
|
|
11
|
+
link.setAttribute(
|
|
12
|
+
"href",
|
|
13
|
+
href +
|
|
14
|
+
separator +
|
|
15
|
+
`eliseParsedLeadSource=${encodeURIComponent(leadSource)}`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const replaceSSTLinkWithTourWidgetTrigger = (
|
|
22
|
+
handleTourClicked: (e: MouseEvent) => void
|
|
23
|
+
): void => {
|
|
24
|
+
const sstRedirectElements = document.querySelectorAll("a");
|
|
25
|
+
sstRedirectElements.forEach(function (element) {
|
|
26
|
+
const href = element.getAttribute("href");
|
|
27
|
+
if (href && href.startsWith("https://app.meetelise.com/")) {
|
|
28
|
+
element.addEventListener("click", (event) => {
|
|
29
|
+
event.preventDefault(); // Prevents the default href redirect
|
|
30
|
+
handleTourClicked(event as MouseEvent);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const replacePageRedirectElementWithTourWidgetTrigger = (
|
|
37
|
+
handleTourClicked: (e: MouseEvent) => void
|
|
38
|
+
): void => {
|
|
39
|
+
// Gets any elements in format like <a href="/apartments/oh/westerville/schedule-a-tour" class=" ">Schedule a Tour</a>
|
|
40
|
+
const scheduleLinks = document.querySelectorAll('a[href$="schedule-a-tour"]');
|
|
41
|
+
scheduleLinks.forEach((linkElement) => {
|
|
42
|
+
if (!linkElement) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
linkElement.addEventListener("click", (event) => {
|
|
46
|
+
event.preventDefault(); // Prevents the default href redirect
|
|
47
|
+
handleTourClicked(event as MouseEvent);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const replaceTourTriggerElementWithTourWidgetTrigger = (
|
|
53
|
+
handleTourClicked: (e: MouseEvent) => void
|
|
54
|
+
): void => {
|
|
55
|
+
const scheduleLinks = document.querySelectorAll(
|
|
56
|
+
'a[href^="#leaseleads-tour-open"]'
|
|
57
|
+
);
|
|
58
|
+
scheduleLinks.forEach((linkElement) => {
|
|
59
|
+
if (!linkElement) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const newLink = document.createElement("a");
|
|
63
|
+
newLink.innerHTML = linkElement.innerHTML;
|
|
64
|
+
newLink.style.cursor = "pointer";
|
|
65
|
+
newLink.addEventListener("click", (event) => {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
handleTourClicked(event as MouseEvent);
|
|
68
|
+
});
|
|
69
|
+
linkElement.parentNode?.replaceChild(newLink, linkElement);
|
|
70
|
+
});
|
|
71
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { expect } from "@esm-bundle/chai";
|
|
2
|
+
import { stub, restore } from "sinon/pkg/sinon-esm";
|
|
3
|
+
import MEChat from "../../public/dist/index";
|
|
4
|
+
|
|
5
|
+
const stubResponse = {
|
|
6
|
+
json: stub().resolves({
|
|
7
|
+
id: 42,
|
|
8
|
+
userId: 42.1,
|
|
9
|
+
orgId: 42.2,
|
|
10
|
+
name: "Unit Test Building",
|
|
11
|
+
themeId: null,
|
|
12
|
+
avatarSrc: null,
|
|
13
|
+
avatarType: "",
|
|
14
|
+
userFirstName: "Ella",
|
|
15
|
+
userLastName: "",
|
|
16
|
+
logoSrc:
|
|
17
|
+
"https://eliseusercontent.meetelise.com/building/3660/test-logo.png",
|
|
18
|
+
chatTitle: "Elise",
|
|
19
|
+
chatSubtitle: "Leasing Agent ExtraordinAIre",
|
|
20
|
+
welcomeMessage:
|
|
21
|
+
"Welcome, I'm Elise! If you have any questions about Unit Test Building or would like to schedule a tour, I'm happy to help.",
|
|
22
|
+
systemWelcomeMessage: "I am an AI and may record this conversation!",
|
|
23
|
+
conversationMaintenanceMode: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const waitForElementWithSelectorToExist = async (
|
|
28
|
+
selector: string,
|
|
29
|
+
target: Node = document.body
|
|
30
|
+
): Promise<void> => {
|
|
31
|
+
return new Promise<void>((resolve) => {
|
|
32
|
+
// in case the element already exists
|
|
33
|
+
if (document.querySelector(selector)) {
|
|
34
|
+
resolve();
|
|
35
|
+
}
|
|
36
|
+
const observer = new MutationObserver(() => {
|
|
37
|
+
if (document.querySelector(selector)) {
|
|
38
|
+
resolve();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
observer.observe(target, { subtree: true, childList: true });
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// const wait = (delay, ...args) =>
|
|
46
|
+
// new Promise((resolve) => setTimeout(resolve, delay, ...args));
|
|
47
|
+
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
restore();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it.skip("shows the launcher", async function () {
|
|
53
|
+
// Given an API that returns this building theme
|
|
54
|
+
stub(window, "fetch").resolves(stubResponse);
|
|
55
|
+
|
|
56
|
+
// When I start MEChat
|
|
57
|
+
MEChat.start({
|
|
58
|
+
organization: "unit-test-org",
|
|
59
|
+
building: "unit-test-building",
|
|
60
|
+
});
|
|
61
|
+
await waitForElementWithSelectorToExist(".meetelise-chat.launcher > div");
|
|
62
|
+
|
|
63
|
+
// Then I should see a launcher
|
|
64
|
+
const launcher = document.querySelector<HTMLDivElement>(
|
|
65
|
+
".meetelise-chat.launcher"
|
|
66
|
+
).firstChild as HTMLDivElement;
|
|
67
|
+
|
|
68
|
+
// And the popup should be hidden
|
|
69
|
+
const popup = document.querySelector<HTMLSpanElement>(".__talkjs_popup");
|
|
70
|
+
expect(popup).to.be.an.instanceof(HTMLSpanElement);
|
|
71
|
+
const popupStyle = window.getComputedStyle(popup);
|
|
72
|
+
const popupDisplay = popupStyle.getPropertyValue("display");
|
|
73
|
+
expect(popupDisplay).to.equal("none");
|
|
74
|
+
|
|
75
|
+
launcher.click();
|
|
76
|
+
// Without waiting, the popup doesn't open in time for the next assertion
|
|
77
|
+
//await wait.skip(0);
|
|
78
|
+
|
|
79
|
+
// Then the popup should be visible
|
|
80
|
+
const popupStyle2 = window.getComputedStyle(popup);
|
|
81
|
+
const popupDisplay2 = popupStyle2.getPropertyValue("display");
|
|
82
|
+
expect(popupDisplay2).not.to.equal("none");
|
|
83
|
+
|
|
84
|
+
// Ideally, expect welcome message, but we can't select inside the iframe
|
|
85
|
+
// Ideally, expect theme colors, but we can't select inside the iframe
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it.skip("works via the programmatic interface", async function () {
|
|
89
|
+
// Given an API that returns this building theme
|
|
90
|
+
stub(window, "fetch").resolves(stubResponse);
|
|
91
|
+
|
|
92
|
+
// When I start MEChat
|
|
93
|
+
const chat = MEChat.start({
|
|
94
|
+
organization: "unit-test-org",
|
|
95
|
+
building: "unit-test-building",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await waitForElementWithSelectorToExist(".meetelise-chat.launcher > div");
|
|
99
|
+
|
|
100
|
+
// Ideally, verify behavior, but this will at least verify nothing throws
|
|
101
|
+
chat.show();
|
|
102
|
+
chat.hide();
|
|
103
|
+
chat.setTheme({
|
|
104
|
+
avatarInitials: "G",
|
|
105
|
+
});
|
|
106
|
+
chat.open();
|
|
107
|
+
chat.close();
|
|
108
|
+
chat.restartConversation();
|
|
109
|
+
chat.remove();
|
|
110
|
+
});
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { StyleInfo } from "lit/directives/style-map";
|
|
3
|
+
import "../WebComponent/me-chat";
|
|
4
|
+
import { MEChat as MEChatLitElement } from "../WebComponent/me-chat";
|
|
5
|
+
import "../WebComponent/health-chat";
|
|
6
|
+
import { HealthChat as HealthChatLitElement } from "../WebComponent/health-chat";
|
|
7
|
+
import "../WebComponent/utilities-chat";
|
|
8
|
+
import { UtilitiesChat as UtilitiesChatElement } from "../WebComponent/utilities-chat";
|
|
9
|
+
|
|
10
|
+
import { tintColor } from "../themes";
|
|
11
|
+
import { LogType, sendLoggingEvent } from "../analytics";
|
|
12
|
+
import { findBuildingSlugFromSite, handleRentgrataOverride } from "./utils";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The interface to MeetElise chat.
|
|
16
|
+
*
|
|
17
|
+
* To add meetelise chat to the screen, call its static method
|
|
18
|
+
* `start()` with your building and organization slug.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* MEChat.start({
|
|
22
|
+
* organization: 'the-jacobson-group',
|
|
23
|
+
* building: 'twin-rivers-pointe'
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
interface PositioningOptions {
|
|
28
|
+
right?: number;
|
|
29
|
+
bottom?: number;
|
|
30
|
+
top?: number;
|
|
31
|
+
left?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface HealthcareOptions extends PositioningOptions {
|
|
35
|
+
id: string;
|
|
36
|
+
}
|
|
37
|
+
export default class MEChat {
|
|
38
|
+
static meChat: MEChatLitElement | null = null;
|
|
39
|
+
static healthChat: HealthChatLitElement | null = null;
|
|
40
|
+
static utilitiesChat: UtilitiesChatElement | null = null;
|
|
41
|
+
static orgSlug = "";
|
|
42
|
+
static mutationObserver: MutationObserver | null = null;
|
|
43
|
+
static previousUrl = "";
|
|
44
|
+
static hasBuildingSlug: boolean | null = null;
|
|
45
|
+
static brandColor = "";
|
|
46
|
+
static backgroundColor = "";
|
|
47
|
+
static healthcareId = "";
|
|
48
|
+
static overridePlacement: {
|
|
49
|
+
right?: number;
|
|
50
|
+
bottom?: number;
|
|
51
|
+
top?: number;
|
|
52
|
+
left?: number;
|
|
53
|
+
} = {};
|
|
54
|
+
|
|
55
|
+
static healthcareStart(opts: HealthcareOptions, isInitialStart = true): void {
|
|
56
|
+
if (isInitialStart) {
|
|
57
|
+
this.healthcareId = opts.id;
|
|
58
|
+
this.overridePlacement = {
|
|
59
|
+
right: opts.right,
|
|
60
|
+
bottom: opts.bottom,
|
|
61
|
+
top: opts.top,
|
|
62
|
+
left: opts.left,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
installFont();
|
|
66
|
+
const healthChat = document.createElement("health-chat");
|
|
67
|
+
healthChat.setAttribute("class", "health-chat");
|
|
68
|
+
healthChat.setAttribute("role", "dialog");
|
|
69
|
+
healthChat.setAttribute("aria-label", "EliseAI Healthcare Widget");
|
|
70
|
+
healthChat.setAttribute("aria-describedby", "aria-describe-info");
|
|
71
|
+
healthChat.setAttribute("aria-modal", "true");
|
|
72
|
+
healthChat.setAttribute("healthcareId", opts.id);
|
|
73
|
+
|
|
74
|
+
healthChat.setAttribute("right", opts.right?.toString() || "unset");
|
|
75
|
+
healthChat.setAttribute("bottom", opts.bottom?.toString() || "unset");
|
|
76
|
+
healthChat.setAttribute("top", opts.top?.toString() || "unset");
|
|
77
|
+
healthChat.setAttribute("left", opts.left?.toString() || "unset");
|
|
78
|
+
|
|
79
|
+
document.body.appendChild(healthChat);
|
|
80
|
+
MEChat.healthChat = healthChat;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static start(opts: Options, isInitialStart = true): void {
|
|
84
|
+
// If clients are Yardi and have a resident portal with rentcafe,
|
|
85
|
+
// we do NOT want to display the launcher (if following in shows up anywhere in url).
|
|
86
|
+
if (
|
|
87
|
+
window.location.pathname.includes("residentservices") ||
|
|
88
|
+
window.location.pathname.includes("onlineleasing")
|
|
89
|
+
) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (isInitialStart) {
|
|
93
|
+
this.orgSlug =
|
|
94
|
+
opts.organization === "Pacific Urban Residential"
|
|
95
|
+
? "cbc11aba-21c4-4571-bc43-ff9d86a029e3"
|
|
96
|
+
: opts.organization;
|
|
97
|
+
this.hasBuildingSlug = !!opts.building;
|
|
98
|
+
this.overridePlacement = {
|
|
99
|
+
right: opts?.position?.right,
|
|
100
|
+
bottom: opts?.position?.bottom,
|
|
101
|
+
top: opts?.position?.top,
|
|
102
|
+
left: opts?.position?.left,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
installFont();
|
|
106
|
+
|
|
107
|
+
let meChatElement:
|
|
108
|
+
| MEChatLitElement
|
|
109
|
+
| UtilitiesChatElement
|
|
110
|
+
| HealthChatLitElement
|
|
111
|
+
| null = null;
|
|
112
|
+
|
|
113
|
+
switch (opts.widgetType) {
|
|
114
|
+
case WidgetType.Healthcare:
|
|
115
|
+
throw new Error(
|
|
116
|
+
"Healthcare widget is not supported yet, please use the healthcareStart method instead."
|
|
117
|
+
);
|
|
118
|
+
case WidgetType.Default:
|
|
119
|
+
meChatElement = document.createElement("me-chat");
|
|
120
|
+
break;
|
|
121
|
+
case WidgetType.Utilities:
|
|
122
|
+
meChatElement = document.createElement("utilities-chat");
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
meChatElement = document.createElement("me-chat");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!meChatElement) {
|
|
129
|
+
throw new Error("Invalid widget type");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
meChatElement.setAttribute(
|
|
133
|
+
"orgSlug",
|
|
134
|
+
opts.organization === "Pacific Urban Residential"
|
|
135
|
+
? "cbc11aba-21c4-4571-bc43-ff9d86a029e3"
|
|
136
|
+
: opts.organization
|
|
137
|
+
);
|
|
138
|
+
meChatElement.setAttribute(
|
|
139
|
+
"widgetType",
|
|
140
|
+
opts.widgetType || WidgetType.Default
|
|
141
|
+
);
|
|
142
|
+
meChatElement.setAttribute("class", "meetelise-chat");
|
|
143
|
+
meChatElement.setAttribute("role", "dialog");
|
|
144
|
+
meChatElement.setAttribute("aria-label", "EliseAI Widget");
|
|
145
|
+
meChatElement.setAttribute("aria-describedby", "aria-describe-info");
|
|
146
|
+
meChatElement.setAttribute("aria-modal", "true");
|
|
147
|
+
|
|
148
|
+
if (opts.brandColor) {
|
|
149
|
+
this.brandColor = opts.brandColor;
|
|
150
|
+
// we must tint the brand color, to ensure it is visible.
|
|
151
|
+
meChatElement.setAttribute(
|
|
152
|
+
"primaryColor",
|
|
153
|
+
tintColor(opts.brandColor, 0.3)
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (opts.backgroundColor) {
|
|
157
|
+
this.backgroundColor = opts.backgroundColor;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (meChatElement instanceof MEChatLitElement) {
|
|
161
|
+
this.handleBuildingslug(
|
|
162
|
+
meChatElement as MEChatLitElement,
|
|
163
|
+
opts.organization,
|
|
164
|
+
opts.building
|
|
165
|
+
);
|
|
166
|
+
if (opts.launcherStyles) {
|
|
167
|
+
meChatElement.launcherStyles = opts.launcherStyles;
|
|
168
|
+
}
|
|
169
|
+
if (opts.mobileStyles) {
|
|
170
|
+
meChatElement.mobileStyles = opts.mobileStyles;
|
|
171
|
+
}
|
|
172
|
+
if (opts.onWidgetLoaded) {
|
|
173
|
+
meChatElement.onWidgetLoaded = opts.onWidgetLoaded;
|
|
174
|
+
}
|
|
175
|
+
if (opts.overrideRentgrata) {
|
|
176
|
+
handleRentgrataOverride();
|
|
177
|
+
meChatElement.overrideRentgrata = true;
|
|
178
|
+
}
|
|
179
|
+
if (opts.onSstClose) {
|
|
180
|
+
meChatElement.onSstClose = opts.onSstClose;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (opts.position) {
|
|
185
|
+
meChatElement.setAttribute(
|
|
186
|
+
"right",
|
|
187
|
+
opts.position.right?.toString() || "unset"
|
|
188
|
+
);
|
|
189
|
+
meChatElement.setAttribute(
|
|
190
|
+
"bottom",
|
|
191
|
+
opts.position.bottom?.toString() || "unset"
|
|
192
|
+
);
|
|
193
|
+
meChatElement.setAttribute(
|
|
194
|
+
"top",
|
|
195
|
+
opts.position.top?.toString() || "unset"
|
|
196
|
+
);
|
|
197
|
+
meChatElement.setAttribute(
|
|
198
|
+
"left",
|
|
199
|
+
opts.position.left?.toString() || "unset"
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
+
(window as any).eliseAi = {};
|
|
204
|
+
document.body.appendChild(meChatElement);
|
|
205
|
+
|
|
206
|
+
if (meChatElement instanceof MEChatLitElement) {
|
|
207
|
+
MEChat.meChat = meChatElement;
|
|
208
|
+
}
|
|
209
|
+
if (meChatElement instanceof UtilitiesChatElement) {
|
|
210
|
+
MEChat.utilitiesChat = meChatElement;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
static async restartConversation(): Promise<void> {
|
|
215
|
+
if (!this.meChat) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
await this.meChat.restartConversation();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
static async remove(): Promise<void> {
|
|
222
|
+
if (!this.meChat) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
await this.meChat.remove();
|
|
226
|
+
document.body.removeChild(this.meChat);
|
|
227
|
+
MEChat.meChat = null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static async handleBuildingslug(
|
|
231
|
+
meChat: MEChatLitElement,
|
|
232
|
+
orgSlug?: string,
|
|
233
|
+
buildingSlug?: string
|
|
234
|
+
): Promise<void> {
|
|
235
|
+
if (buildingSlug) {
|
|
236
|
+
meChat.setAttribute("buildingSlug", buildingSlug);
|
|
237
|
+
// TODO(JMB): Uncomment this when we want to start logging mismatches instead of just the "no match found" case
|
|
238
|
+
// this.calculateBuildingSlugForLogging(buildingSlug);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (this.mutationObserver) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!orgSlug) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const foundBuildingSlugFromSite = await findBuildingSlugFromSite(orgSlug);
|
|
249
|
+
if (foundBuildingSlugFromSite) {
|
|
250
|
+
const opts = {
|
|
251
|
+
organization: orgSlug,
|
|
252
|
+
building: foundBuildingSlugFromSite,
|
|
253
|
+
brandColor: this.brandColor,
|
|
254
|
+
backgroundColor: this.backgroundColor,
|
|
255
|
+
};
|
|
256
|
+
this.start(opts, false);
|
|
257
|
+
}
|
|
258
|
+
this.previousUrl = window.location.href;
|
|
259
|
+
|
|
260
|
+
document.body.addEventListener(
|
|
261
|
+
"click",
|
|
262
|
+
() => {
|
|
263
|
+
requestAnimationFrame(() => {
|
|
264
|
+
if (
|
|
265
|
+
this.previousUrl === window.location.href ||
|
|
266
|
+
this.hasBuildingSlug
|
|
267
|
+
) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.previousUrl = window.location.href;
|
|
271
|
+
findBuildingSlugFromSite(orgSlug).then(
|
|
272
|
+
(foundBuildingSlugFromSite) => {
|
|
273
|
+
if (!foundBuildingSlugFromSite) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const opts = {
|
|
277
|
+
organization: orgSlug,
|
|
278
|
+
building: foundBuildingSlugFromSite,
|
|
279
|
+
brandColor: this.brandColor,
|
|
280
|
+
backgroundColor: this.backgroundColor,
|
|
281
|
+
};
|
|
282
|
+
this.start(opts, false);
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
true
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static async handleSingleFamilyUrl(): Promise<void> {
|
|
292
|
+
if (this.hasBuildingSlug) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
this.remove();
|
|
296
|
+
const url = window.location.href;
|
|
297
|
+
const requestUrl = `https://app.meetelise.com/platformApi/webchat/microsite_slug?uri=${encodeURIComponent(
|
|
298
|
+
url
|
|
299
|
+
)}`;
|
|
300
|
+
const buildingSlug = await axios.get<string | null>(requestUrl, {
|
|
301
|
+
headers: { ["org-slug"]: this.orgSlug },
|
|
302
|
+
});
|
|
303
|
+
// TODO: Figure out whether we only want to sample a percentage of these
|
|
304
|
+
if (Math.random() < 0.2) {
|
|
305
|
+
sendLoggingEvent({
|
|
306
|
+
logType:
|
|
307
|
+
buildingSlug && buildingSlug.data ? LogType.info : LogType.warn,
|
|
308
|
+
logTitle: `[BUILDING_SLUG_CALCULATED_${
|
|
309
|
+
buildingSlug ? "SUCCESS" : "FAILURE"
|
|
310
|
+
}]`,
|
|
311
|
+
logData: {
|
|
312
|
+
calculatedBuildingSlug: buildingSlug.data,
|
|
313
|
+
url,
|
|
314
|
+
orgSlug: this.orgSlug,
|
|
315
|
+
givenBuildingSlug: null,
|
|
316
|
+
reason: buildingSlug && buildingSlug.data ? null : "No match found",
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
if (!buildingSlug || !buildingSlug.data) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const opts = {
|
|
324
|
+
organization: this.orgSlug,
|
|
325
|
+
building: buildingSlug.data,
|
|
326
|
+
brandColor: this.brandColor,
|
|
327
|
+
backgroundColor: this.backgroundColor,
|
|
328
|
+
};
|
|
329
|
+
this.start(opts, false);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
static async calculateBuildingSlugForLogging(
|
|
333
|
+
givenBuildingSlug: string
|
|
334
|
+
): Promise<void> {
|
|
335
|
+
// TODO: Figure out whether we only want to sample a percentage of these
|
|
336
|
+
const url = window.location.href;
|
|
337
|
+
const requestUrl = `https://app.meetelise.com/platformApi/webchat/microsite_slug?uri=${encodeURIComponent(
|
|
338
|
+
url
|
|
339
|
+
)}`;
|
|
340
|
+
const buildingSlug = await axios.get<string | null>(requestUrl, {
|
|
341
|
+
headers: { ["org-slug"]: this.orgSlug },
|
|
342
|
+
});
|
|
343
|
+
if (Math.random() < 0.2) {
|
|
344
|
+
sendLoggingEvent({
|
|
345
|
+
logType:
|
|
346
|
+
buildingSlug && buildingSlug.data === givenBuildingSlug
|
|
347
|
+
? LogType.info
|
|
348
|
+
: LogType.warn,
|
|
349
|
+
logTitle: `[BUILDING_SLUG_CALCULATED_${
|
|
350
|
+
buildingSlug && buildingSlug.data === givenBuildingSlug
|
|
351
|
+
? "SUCCESS"
|
|
352
|
+
: "FAILURE"
|
|
353
|
+
}]`,
|
|
354
|
+
logData: {
|
|
355
|
+
calculatedBuildingSlug: buildingSlug.data,
|
|
356
|
+
url,
|
|
357
|
+
orgSlug: this.orgSlug,
|
|
358
|
+
givenBuildingSlug,
|
|
359
|
+
reason:
|
|
360
|
+
buildingSlug && buildingSlug.data === givenBuildingSlug
|
|
361
|
+
? null
|
|
362
|
+
: buildingSlug && !buildingSlug.data
|
|
363
|
+
? "No match found"
|
|
364
|
+
: buildingSlug && buildingSlug.data !== givenBuildingSlug
|
|
365
|
+
? "Mismatch"
|
|
366
|
+
: "No match found",
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (!buildingSlug || !buildingSlug.data) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export interface Options {
|
|
377
|
+
building: string;
|
|
378
|
+
organization: string;
|
|
379
|
+
avatarSrc?: string;
|
|
380
|
+
mini?: boolean;
|
|
381
|
+
launcherStyles?: StyleInfo;
|
|
382
|
+
brandColor?: string;
|
|
383
|
+
backgroundColor?: string;
|
|
384
|
+
mobileStyles?: StyleInfo;
|
|
385
|
+
position?: PositioningOptions;
|
|
386
|
+
onWidgetLoaded?: () => void;
|
|
387
|
+
overrideRentgrata?: boolean;
|
|
388
|
+
widgetType?: string;
|
|
389
|
+
onSstClose?: () => void;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export enum WidgetType {
|
|
393
|
+
Default = "default",
|
|
394
|
+
Healthcare = "healthcare",
|
|
395
|
+
Utilities = "utilities",
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/** You can't install a font from CSS in a shadow DOM, so we use JS to do it here in the regular DOM. */
|
|
399
|
+
const installFont = () => {
|
|
400
|
+
const link = document.createElement("link");
|
|
401
|
+
link.setAttribute("rel", "stylesheet");
|
|
402
|
+
link.setAttribute("type", "text/css");
|
|
403
|
+
document.head.appendChild(link);
|
|
404
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { LogType, sendLoggingEvent } from "../analytics";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
export const findBuildingSlugFromSite = async (
|
|
5
|
+
orgSlug: string
|
|
6
|
+
): Promise<string | null> => {
|
|
7
|
+
const url = window.location.href;
|
|
8
|
+
const requestUrl = `https://app.meetelise.com/platformApi/webchat/microsite_slug?uri=${encodeURIComponent(
|
|
9
|
+
url
|
|
10
|
+
)}`;
|
|
11
|
+
const buildingSlug = await axios.get<string | null>(requestUrl, {
|
|
12
|
+
headers: { ["org-slug"]: orgSlug },
|
|
13
|
+
});
|
|
14
|
+
// TODO: Figure out whether we only want to sample a percentage of these
|
|
15
|
+
if (Math.random() < 0.2) {
|
|
16
|
+
sendLoggingEvent({
|
|
17
|
+
logType: buildingSlug && buildingSlug.data ? LogType.info : LogType.warn,
|
|
18
|
+
logTitle: `[BUILDING_SLUG_CALCULATED_${
|
|
19
|
+
buildingSlug ? "SUCCESS" : "FAILURE"
|
|
20
|
+
}]`,
|
|
21
|
+
logData: {
|
|
22
|
+
calculatedBuildingSlug: buildingSlug.data,
|
|
23
|
+
url,
|
|
24
|
+
orgSlug: orgSlug,
|
|
25
|
+
givenBuildingSlug: null,
|
|
26
|
+
reason: buildingSlug && buildingSlug.data ? null : "No match found",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return buildingSlug.data;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const handleRentgrataOverride = async (): Promise<void> => {
|
|
34
|
+
const rentgrataWrapperElement = await waitForElement("rg-widget-compact");
|
|
35
|
+
if (!rentgrataWrapperElement) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
rentgrataWrapperElement.setAttribute("style", "display: none");
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const waitForElement = async (
|
|
42
|
+
elementId: string,
|
|
43
|
+
timeout = 5000
|
|
44
|
+
): Promise<Element> => {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const observer = new MutationObserver((mutationsList, observer) => {
|
|
47
|
+
const element = document.getElementById(elementId);
|
|
48
|
+
if (element) {
|
|
49
|
+
observer.disconnect();
|
|
50
|
+
resolve(element);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
55
|
+
|
|
56
|
+
const timeoutId = setTimeout(() => {
|
|
57
|
+
observer.disconnect();
|
|
58
|
+
reject(
|
|
59
|
+
new Error(`Element ${elementId} did not appear within ${timeout}ms`)
|
|
60
|
+
);
|
|
61
|
+
}, timeout);
|
|
62
|
+
|
|
63
|
+
const element = document.querySelector(elementId);
|
|
64
|
+
if (element) {
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
observer.disconnect();
|
|
67
|
+
resolve(element);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function getUrlQueryParameters(): { [queryKey: string]: string } | null {
|
|
2
|
+
if (isQueryMalformed()) {
|
|
3
|
+
return getMalformedQueryParameters();
|
|
4
|
+
}
|
|
5
|
+
return getStandardUrlQueryParameters();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function getStandardUrlQueryParameters(): {
|
|
9
|
+
[queryKey: string]: string;
|
|
10
|
+
} | null {
|
|
11
|
+
const queryParams = new URLSearchParams(window.location.search);
|
|
12
|
+
|
|
13
|
+
const hasUtmContent = queryParams.has("utm_content");
|
|
14
|
+
const hasUtmSource = queryParams.has("utm_source");
|
|
15
|
+
|
|
16
|
+
// If utm_content exists and utm_source does not, replace utm_content with utm_source
|
|
17
|
+
if (hasUtmContent && !hasUtmSource) {
|
|
18
|
+
const utmContentValue = queryParams.get("utm_content");
|
|
19
|
+
queryParams.delete("utm_content");
|
|
20
|
+
queryParams.set("utm_source", utmContentValue as string);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return Object.fromEntries(queryParams);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Some clients are sending malformed query parameters, so we need to handle those
|
|
27
|
+
// i.e. .../?switch_cls[id]=94593/?utm_source=MillCreekPlaces&utm_medium=Community+Portfolio+Page
|
|
28
|
+
function getMalformedQueryParameters(): { [queryKey: string]: string } | null {
|
|
29
|
+
const url = window.location.search;
|
|
30
|
+
const allParams: { [queryKey: string]: string } = {};
|
|
31
|
+
const malformedParts = url.split("?").slice(1).join("&");
|
|
32
|
+
const pairs = malformedParts.split("&");
|
|
33
|
+
pairs.forEach((pair) => {
|
|
34
|
+
const [key, value] = pair.split("=");
|
|
35
|
+
if (key && value) {
|
|
36
|
+
allParams[decodeURIComponent(key)] = decodeURIComponent(value);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return allParams;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const isQueryMalformed = (): boolean =>
|
|
44
|
+
(window.location.search.match(/\?/g) || []).length > 1;
|