@meetelise/chat 1.29.0 → 1.30.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.
Files changed (228) hide show
  1. package/dist/src/MyPubnub.d.ts +116 -0
  2. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.d.ts +2 -0
  3. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item.d.ts +22 -0
  4. package/dist/src/WebComponent/FeeCalculator/components/addon-item/index.d.ts +1 -0
  5. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.d.ts +2 -0
  6. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.d.ts +34 -0
  7. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.d.ts +2 -0
  8. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card.d.ts +21 -0
  9. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.d.ts +2 -0
  10. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item.d.ts +13 -0
  11. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.d.ts +2 -0
  12. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.d.ts +33 -0
  13. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.d.ts +2 -0
  14. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.d.ts +18 -0
  15. package/dist/src/WebComponent/FeeCalculator/components/index.d.ts +5 -0
  16. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.d.ts +2 -0
  17. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card.d.ts +13 -0
  18. package/dist/src/WebComponent/FeeCalculator/constants.d.ts +2 -0
  19. package/dist/src/WebComponent/FeeCalculator/fee-calculator-styles.d.ts +1 -0
  20. package/dist/src/WebComponent/FeeCalculator/fee-calculator.d.ts +59 -0
  21. package/dist/src/WebComponent/FeeCalculator/index.d.ts +2 -0
  22. package/dist/src/WebComponent/FeeCalculator/model/building-fee.d.ts +80 -0
  23. package/dist/src/WebComponent/FeeCalculator/model/transaction-category.d.ts +23 -0
  24. package/dist/src/WebComponent/LeadSourceClient.d.ts +46 -0
  25. package/dist/src/WebComponent/OfficeHours.d.ts +21 -0
  26. package/dist/src/WebComponent/Scheduler/date-picker.d.ts +28 -0
  27. package/dist/src/WebComponent/Scheduler/time-picker.d.ts +14 -0
  28. package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +100 -0
  29. package/dist/src/WebComponent/Scheduler/tour-type-option.d.ts +13 -0
  30. package/dist/src/WebComponent/Scheduler/tourSchedulerStyles.d.ts +1 -0
  31. package/dist/src/WebComponent/actions/InputStyles.d.ts +1 -0
  32. package/dist/src/WebComponent/actions/action-confirm-button.d.ts +13 -0
  33. package/dist/src/WebComponent/actions/call-us-window.d.ts +37 -0
  34. package/dist/src/WebComponent/actions/collapse-expand-button.d.ts +8 -0
  35. package/dist/src/WebComponent/actions/details-window.d.ts +14 -0
  36. package/dist/src/WebComponent/actions/email-us-window.d.ts +46 -0
  37. package/dist/src/WebComponent/actions/formatPhoneNumber.d.ts +17 -0
  38. package/dist/src/WebComponent/actions/minimize-expand-button.d.ts +8 -0
  39. package/dist/src/WebComponent/chat-additional-actions.d.ts +28 -0
  40. package/dist/src/WebComponent/health-chat.d.ts +47 -0
  41. package/dist/src/WebComponent/healthchat-styles.d.ts +1 -0
  42. package/dist/src/WebComponent/icons/ApplyOutlineIcon.d.ts +2 -0
  43. package/dist/src/WebComponent/icons/BookTourOutlineIcon.d.ts +2 -0
  44. package/dist/src/WebComponent/icons/CalculatorOutlineIcon.d.ts +2 -0
  45. package/dist/src/WebComponent/icons/ChatOutlineIcon.d.ts +2 -0
  46. package/dist/src/WebComponent/icons/ChevronLeftIcon.d.ts +2 -0
  47. package/dist/src/WebComponent/icons/ChevronRightIcon.d.ts +2 -0
  48. package/dist/src/WebComponent/icons/ContactResidentIcon.d.ts +2 -0
  49. package/dist/src/WebComponent/icons/DollarOutlineIcon.d.ts +3 -0
  50. package/dist/src/WebComponent/icons/EmailOutlineIcon.d.ts +2 -0
  51. package/dist/src/WebComponent/icons/HeyThereEmojiIcon.d.ts +2 -0
  52. package/dist/src/WebComponent/icons/PhoneOutlineIcon.d.ts +2 -0
  53. package/dist/src/WebComponent/icons/SendMessageIcon.d.ts +3 -0
  54. package/dist/src/WebComponent/icons/TourSelfGuidedIcon.d.ts +2 -0
  55. package/dist/src/WebComponent/icons/TourVirtuallyIcon.d.ts +2 -0
  56. package/dist/src/WebComponent/icons/TourWithAgentIcon.d.ts +2 -0
  57. package/dist/src/WebComponent/icons/XOutlineIcon.d.ts +2 -0
  58. package/dist/src/WebComponent/index.d.ts +2 -0
  59. package/dist/src/WebComponent/launcher/Launcher.d.ts +98 -0
  60. package/dist/src/WebComponent/launcher/launcherStyles.d.ts +1 -0
  61. package/dist/src/WebComponent/launcher/mobile-launcher.d.ts +27 -0
  62. package/dist/src/WebComponent/launcher/typeEmojiStyles.d.ts +1 -0
  63. package/dist/src/WebComponent/launcher/typeMiniStyles.d.ts +1 -0
  64. package/dist/src/WebComponent/launcher/typeMobileStyles.d.ts +1 -0
  65. package/dist/src/WebComponent/leasing-chat-styles.d.ts +1 -0
  66. package/dist/src/WebComponent/me-chat.d.ts +91 -0
  67. package/dist/src/WebComponent/me-select.d.ts +24 -0
  68. package/dist/src/WebComponent/mega-loader.d.ts +7 -0
  69. package/dist/src/WebComponent/mini-loader.d.ts +5 -0
  70. package/dist/src/WebComponent/pubnub-chat-styles.d.ts +1 -0
  71. package/dist/src/WebComponent/pubnub-chat.d.ts +49 -0
  72. package/dist/src/WebComponent/pubnub-media.d.ts +14 -0
  73. package/dist/src/WebComponent/pubnub-message-styles.d.ts +1 -0
  74. package/dist/src/WebComponent/pubnub-message.d.ts +39 -0
  75. package/dist/src/WebComponent/simple-launcher/simple-launcher-styles.d.ts +1 -0
  76. package/dist/src/WebComponent/simple-launcher/simple-launcher.d.ts +12 -0
  77. package/dist/src/WebComponent/utilities-chat.d.ts +47 -0
  78. package/dist/src/WebComponent/utilities-styles.d.ts +1 -0
  79. package/dist/src/WebComponent/utils.d.ts +31 -0
  80. package/dist/src/analytics.d.ts +64 -0
  81. package/dist/src/disclaimers.d.ts +8 -0
  82. package/dist/src/fetchBuildingABTestType.d.ts +8 -0
  83. package/dist/src/fetchBuildingInfo.d.ts +57 -0
  84. package/dist/src/fetchBuildingWebchatView.d.ts +123 -0
  85. package/dist/src/fetchFeatureFlag.d.ts +14 -0
  86. package/dist/src/fetchLeadSources.d.ts +4 -0
  87. package/dist/src/fetchPhoneNumberFromSource.d.ts +6 -0
  88. package/dist/src/getAvailabilities.d.ts +45 -0
  89. package/dist/src/getBuildingPhoneNumber.d.ts +1 -0
  90. package/dist/src/getShouldAllowScheduling.d.ts +1 -0
  91. package/dist/src/getShouldShowWebchat.d.ts +3 -0
  92. package/dist/src/getTimezoneString.d.ts +1 -0
  93. package/dist/src/globals.d.ts +1 -0
  94. package/dist/src/gtm.d.ts +6 -0
  95. package/dist/src/handleChatId.d.ts +11 -0
  96. package/dist/src/insertDNIIntoWebsite.d.ts +5 -0
  97. package/dist/src/insertLeadSourceIntoSchedulerLinks.d.ts +4 -0
  98. package/dist/src/main/MEChat.d.ts +74 -0
  99. package/dist/src/main/utils.d.ts +2 -0
  100. package/dist/src/postLeadSources.d.ts +3 -0
  101. package/dist/src/rentgrata.d.ts +4 -0
  102. package/dist/src/replaceSelectButtonsWithNewLink.d.ts +5 -0
  103. package/dist/src/services/fees/calculateQuote.d.ts +52 -0
  104. package/dist/src/services/fees/fetchBuildingFees.d.ts +24 -0
  105. package/dist/src/services/fees/fetchBuildingFloorplans.d.ts +21 -0
  106. package/dist/src/services/fees/utils.d.ts +1 -0
  107. package/dist/src/svgIcons.d.ts +5 -0
  108. package/dist/src/themes.d.ts +5 -0
  109. package/dist/src/types/rest-sdk.types.d.ts +11 -0
  110. package/dist/src/types/webchat-no-show-reason.d.ts +1 -0
  111. package/dist/src/utils.d.ts +13 -0
  112. package/package.json +1 -1
  113. package/public/dist/index.js +384 -179
  114. package/src/MyPubnub.ts +792 -0
  115. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.ts +79 -0
  116. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item.ts +121 -0
  117. package/src/WebComponent/FeeCalculator/components/addon-item/index.ts +1 -0
  118. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.ts +127 -0
  119. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts +191 -0
  120. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.ts +65 -0
  121. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card.ts +91 -0
  122. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.ts +44 -0
  123. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +38 -0
  124. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +144 -0
  125. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +241 -0
  126. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.ts +74 -0
  127. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts +72 -0
  128. package/src/WebComponent/FeeCalculator/components/index.ts +5 -0
  129. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.ts +39 -0
  130. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card.ts +39 -0
  131. package/src/WebComponent/FeeCalculator/constants.ts +3 -0
  132. package/src/WebComponent/FeeCalculator/fee-calculator-styles.ts +334 -0
  133. package/src/WebComponent/FeeCalculator/fee-calculator.ts +369 -0
  134. package/src/WebComponent/FeeCalculator/index.ts +4 -0
  135. package/src/WebComponent/FeeCalculator/model/building-fee.ts +120 -0
  136. package/src/WebComponent/FeeCalculator/model/transaction-category.ts +23 -0
  137. package/src/WebComponent/LeadSourceClient.ts +332 -0
  138. package/src/WebComponent/MEChat.css +5 -0
  139. package/src/WebComponent/OfficeHours.ts +73 -0
  140. package/src/WebComponent/Scheduler/date-picker.ts +405 -0
  141. package/src/WebComponent/Scheduler/time-picker.ts +190 -0
  142. package/src/WebComponent/Scheduler/tour-scheduler.ts +1373 -0
  143. package/src/WebComponent/Scheduler/tour-type-option.ts +112 -0
  144. package/src/WebComponent/Scheduler/tourSchedulerStyles.ts +418 -0
  145. package/src/WebComponent/actions/InputStyles.ts +57 -0
  146. package/src/WebComponent/actions/action-confirm-button.ts +125 -0
  147. package/src/WebComponent/actions/call-us-window.ts +445 -0
  148. package/src/WebComponent/actions/collapse-expand-button.ts +65 -0
  149. package/src/WebComponent/actions/details-window.ts +150 -0
  150. package/src/WebComponent/actions/email-us-window.ts +555 -0
  151. package/src/WebComponent/actions/formatPhoneNumber.ts +72 -0
  152. package/src/WebComponent/actions/minimize-expand-button.ts +93 -0
  153. package/src/WebComponent/chat-additional-actions.ts +135 -0
  154. package/src/WebComponent/health-chat.ts +270 -0
  155. package/src/WebComponent/healthchat-styles.ts +119 -0
  156. package/src/WebComponent/icons/ApplyOutlineIcon.ts +22 -0
  157. package/src/WebComponent/icons/BookTourOutlineIcon.ts +13 -0
  158. package/src/WebComponent/icons/CalculatorOutlineIcon.ts +22 -0
  159. package/src/WebComponent/icons/ChatOutlineIcon.ts +10 -0
  160. package/src/WebComponent/icons/ChevronLeftIcon.ts +7 -0
  161. package/src/WebComponent/icons/ChevronRightIcon.ts +7 -0
  162. package/src/WebComponent/icons/ContactResidentIcon.ts +9 -0
  163. package/src/WebComponent/icons/DollarOutlineIcon.ts +18 -0
  164. package/src/WebComponent/icons/EmailOutlineIcon.ts +7 -0
  165. package/src/WebComponent/icons/HeyThereEmojiIcon.ts +12 -0
  166. package/src/WebComponent/icons/PhoneOutlineIcon.ts +7 -0
  167. package/src/WebComponent/icons/SendMessageIcon.ts +17 -0
  168. package/src/WebComponent/icons/TourSelfGuidedIcon.ts +17 -0
  169. package/src/WebComponent/icons/TourVirtuallyIcon.ts +17 -0
  170. package/src/WebComponent/icons/TourWithAgentIcon.ts +17 -0
  171. package/src/WebComponent/icons/XOutlineIcon.ts +8 -0
  172. package/src/WebComponent/index.ts +2 -0
  173. package/src/WebComponent/launcher/Launcher.ts +1282 -0
  174. package/src/WebComponent/launcher/launcherStyles.ts +500 -0
  175. package/src/WebComponent/launcher/mobile-launcher.ts +162 -0
  176. package/src/WebComponent/launcher/typeEmojiStyles.ts +161 -0
  177. package/src/WebComponent/launcher/typeMiniStyles.ts +60 -0
  178. package/src/WebComponent/launcher/typeMobileStyles.ts +50 -0
  179. package/src/WebComponent/leasing-chat-styles.ts +114 -0
  180. package/src/WebComponent/me-chat.ts +1262 -0
  181. package/src/WebComponent/me-select.ts +322 -0
  182. package/src/WebComponent/mega-loader.ts +36 -0
  183. package/src/WebComponent/mini-loader.ts +28 -0
  184. package/src/WebComponent/pubnub-chat-styles.ts +204 -0
  185. package/src/WebComponent/pubnub-chat.ts +928 -0
  186. package/src/WebComponent/pubnub-media.ts +208 -0
  187. package/src/WebComponent/pubnub-message-styles.ts +54 -0
  188. package/src/WebComponent/pubnub-message.ts +431 -0
  189. package/src/WebComponent/simple-launcher/simple-launcher-styles.ts +34 -0
  190. package/src/WebComponent/simple-launcher/simple-launcher.ts +100 -0
  191. package/src/WebComponent/utilities-chat.ts +270 -0
  192. package/src/WebComponent/utilities-styles.ts +110 -0
  193. package/src/WebComponent/utils.ts +82 -0
  194. package/src/analytics.ts +217 -0
  195. package/src/assetUrls.ts +6 -0
  196. package/src/disclaimers.ts +58 -0
  197. package/src/fetchBuildingABTestType.ts +21 -0
  198. package/src/fetchBuildingInfo.ts +87 -0
  199. package/src/fetchBuildingWebchatView.ts +156 -0
  200. package/src/fetchFeatureFlag.ts +250 -0
  201. package/src/fetchLeadSources.ts +98 -0
  202. package/src/fetchPhoneNumberFromSource.ts +31 -0
  203. package/src/fetchWebchatPreferences.ts +54 -0
  204. package/src/getAvailabilities.ts +179 -0
  205. package/src/getBuildingPhoneNumber.ts +26 -0
  206. package/src/getShouldAllowScheduling.ts +16 -0
  207. package/src/getShouldShowWebchat.ts +114 -0
  208. package/src/getTimezoneString.ts +39 -0
  209. package/src/globals.ts +1 -0
  210. package/src/gtm.ts +17 -0
  211. package/src/handleChatId.ts +101 -0
  212. package/src/insertDNIIntoWebsite.ts +146 -0
  213. package/src/insertLeadSourceIntoSchedulerLinks.ts +71 -0
  214. package/src/main/MEChat.test.ts +110 -0
  215. package/src/main/MEChat.ts +404 -0
  216. package/src/main/utils.ts +70 -0
  217. package/src/postLeadSources.ts +44 -0
  218. package/src/rentgrata.ts +74 -0
  219. package/src/replaceSelectButtonsWithNewLink.ts +69 -0
  220. package/src/services/fees/calculateQuote.ts +135 -0
  221. package/src/services/fees/fetchBuildingFees.ts +63 -0
  222. package/src/services/fees/fetchBuildingFloorplans.ts +74 -0
  223. package/src/services/fees/utils.ts +4 -0
  224. package/src/svgIcons.ts +14 -0
  225. package/src/themes.ts +65 -0
  226. package/src/types/rest-sdk.types.ts +13 -0
  227. package/src/types/webchat-no-show-reason.ts +6 -0
  228. package/src/utils.ts +121 -0
@@ -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;
@@ -0,0 +1,74 @@
1
+ import axios from "axios";
2
+
3
+ export const openRengrataWidget = (): void => {
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ const rentgrata = (window as any).rentgrata;
6
+ if (!rentgrata) {
7
+ return;
8
+ }
9
+ const rentgrataWidget = rentgrata.Widget;
10
+ if (!rentgrataWidget) {
11
+ return;
12
+ }
13
+ if (!rentgrataWidget.openWidget) {
14
+ return;
15
+ }
16
+ rentgrataWidget.openWidget();
17
+ };
18
+
19
+ export const closeRengrataWidget = (): void => {
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ const rentgrata = (window as any).rentgrata;
22
+ if (!rentgrata) {
23
+ return;
24
+ }
25
+ const rentgrataWidget = rentgrata.Widget;
26
+ if (!rentgrataWidget) {
27
+ return;
28
+ }
29
+ if (!rentgrataWidget.openWidget) {
30
+ return;
31
+ }
32
+ rentgrataWidget.close();
33
+ };
34
+
35
+ export const hasRentgrata = (): boolean => {
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ return !!(window as any).rentgrata;
38
+ };
39
+
40
+ export const updateRentgrataToken = async (
41
+ buildingSlug: string,
42
+ orgSlug: string
43
+ ): Promise<void> => {
44
+ const host = "https://app.meetelise.com";
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const rentgrata = (window as any).rentgrata;
47
+ if (!rentgrata) {
48
+ return;
49
+ }
50
+ const rentgrataWidget = rentgrata.Widget;
51
+ if (!rentgrataWidget) {
52
+ return;
53
+ }
54
+ const rentgrataConfig = rentgrataWidget.config;
55
+ if (!rentgrataConfig) {
56
+ return;
57
+ }
58
+
59
+ const widgetKey = rentgrataConfig.widgetKey;
60
+ if (!widgetKey) {
61
+ return;
62
+ }
63
+ await axios.post(
64
+ `${host}/platformApi/webchat/rentgrata?token=${widgetKey}`,
65
+ {},
66
+ {
67
+ headers: {
68
+ "Content-Type": "application/json",
69
+ "building-slug": buildingSlug ?? "",
70
+ "org-slug": orgSlug ?? "",
71
+ },
72
+ }
73
+ );
74
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Script to find all application links/buttons on a page and replace them with a
3
+ * new elise application link.
4
+ */
5
+ import { LogType, sendLoggingEvent } from "./analytics";
6
+
7
+ /**
8
+ * Script to find all "Select" buttons with specific URL patterns and replace them with a
9
+ * new application link.
10
+ */
11
+ export const replaceSelectButtonsWithNewLink = (
12
+ newApplicationLink: string,
13
+ orgSlug: string,
14
+ buildingSlug?: string
15
+ ): number => {
16
+ const urlPatterns = [
17
+ /thehavenatgreenhill\.securecafe\.com\/onlineleasing\/the-haven-at-greenhill\/oleapplication\.aspx(\?.*)?$/,
18
+ /securecafe\.com\/onlineleasing.*\/oleapplication\.aspx(\?.*)?$/,
19
+ /\/onlineleasing.*\/oleapplication\.aspx(\?.*)?$/,
20
+ /vsc\.myresman\.com\/Portal\/Applicants\/Availability(\?.*)?$/,
21
+ ];
22
+
23
+ const allElements = document.body.getElementsByTagName("a");
24
+ let totalReplacements = 0;
25
+
26
+ for (let i = 0; i < allElements.length; i++) {
27
+ const element = allElements[i] as HTMLAnchorElement;
28
+ if (element.nodeType !== Node.ELEMENT_NODE) continue;
29
+
30
+ const matchesUrlPattern = urlPatterns.some((pattern) =>
31
+ pattern.test(element.href)
32
+ );
33
+ const isSelectButtonWithUrl = matchesUrlPattern;
34
+
35
+ if (isSelectButtonWithUrl) {
36
+ const oldHref = element.getAttribute("href");
37
+ element.setAttribute("href", newApplicationLink);
38
+ totalReplacements++;
39
+
40
+ sendLoggingEvent({
41
+ logTitle: "SELECT_BUTTON_LINK_REPLACEMENT",
42
+ logData: {
43
+ type: "link-replacement",
44
+ oldHref,
45
+ newHref: newApplicationLink,
46
+ website: window.location.href,
47
+ },
48
+ logType: LogType.info,
49
+ buildingSlug,
50
+ orgSlug,
51
+ });
52
+ }
53
+ }
54
+
55
+ if (totalReplacements === 0) {
56
+ sendLoggingEvent({
57
+ logTitle: "SELECT_BUTTON_LINK_REPLACEMENT",
58
+ logData: {
59
+ type: "no-select-buttons-found",
60
+ website: window.location.href,
61
+ },
62
+ logType: LogType.warn,
63
+ buildingSlug,
64
+ orgSlug,
65
+ });
66
+ }
67
+
68
+ return totalReplacements;
69
+ };