@meetelise/chat 1.20.39 → 1.20.40

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.
@@ -47,6 +47,8 @@ export class Launcher extends LitElement {
47
47
  @property()
48
48
  phoneNumber = "";
49
49
  @property({ attribute: true })
50
+ chatId = "";
51
+ @property({ attribute: true })
50
52
  chatCallUsHeader = "";
51
53
  @property({ attribute: false })
52
54
  buildingId = 0;
@@ -58,6 +60,10 @@ export class Launcher extends LitElement {
58
60
  sgtUrl = "";
59
61
  @property({ attribute: true })
60
62
  buildingABTestType = "";
63
+ @property({ attribute: false })
64
+ leadSources: string[] = [];
65
+ @property({ attribute: false })
66
+ currentLeadSource = "";
61
67
  @property({ attribute: true })
62
68
  escortedToursLink = "";
63
69
  @property({ attribute: true })
@@ -381,6 +387,9 @@ export class Launcher extends LitElement {
381
387
  ${this.isEmailWindowOpen
382
388
  ? html`<div class="launcher__window-wrapper">
383
389
  <email-us-window
390
+ chatId="${this.chatId}"
391
+ .leadSources="${this.leadSources}"
392
+ currentLeadSource="${this.currentLeadSource}"
384
393
  orgSlug="${this.orgSlug}"
385
394
  buildingSlug="${this.buildingSlug}"
386
395
  ${ref(this.emailUsWindowRef)}
@@ -402,11 +411,13 @@ export class Launcher extends LitElement {
402
411
  ${this.isSSTWindowOpen
403
412
  ? html`<div class="launcher__window-wrapper">
404
413
  <tour-scheduler
414
+ chatId="${this.chatId}"
405
415
  orgSlug="${this.orgSlug}"
406
416
  buildingSlug="${this.buildingSlug}"
407
417
  sgtUrl="${this.sgtUrl}"
408
418
  escortedToursLink="${this.escortedToursLink}"
409
419
  virtualToursLink="${this.virtualToursLink}"
420
+ .leadSources="${this.leadSources}"
410
421
  .layoutOptions=${this.layoutOptions}
411
422
  .unitOptions=${this.unitOptions}
412
423
  .tourTypeOptions=${this.tourTypeOptions}
@@ -8,7 +8,7 @@ import {
8
8
  import "./tour-type-option.ts";
9
9
  import "./date-picker.ts";
10
10
  import "./time-picker.ts";
11
- import "./me-select.ts";
11
+ import "../me-select.ts";
12
12
  import {
13
13
  DateWithTimeZoneOffset,
14
14
  getAvailabilitiesGroupedByDay,
@@ -17,7 +17,7 @@ import {
17
17
  import { TourAvailabilityResponseRankOrderedSupportedTourTypesEnum } from "@meetelise/rest-sdk";
18
18
  import { format } from "date-fns";
19
19
  import { DatePicker } from "./date-picker";
20
- import { MESelect } from "./me-select";
20
+ import { MESelect } from "../me-select";
21
21
  import { TimePicker } from "./time-picker";
22
22
  import { LabeledOption, UnitV2 } from "../../fetchBuildingInfo";
23
23
  import { isMobile } from "../../utils";
@@ -28,6 +28,7 @@ import parseISO from "date-fns/parseISO";
28
28
  import compareAsc from "date-fns/compareAsc";
29
29
  import { InputStyles } from "../actions/InputStyles";
30
30
  import { classMap } from "lit/directives/class-map.js";
31
+ import postLeadSources from "../../postLeadSources";
31
32
 
32
33
  const getHumanReadableLayout = (layout: string) => {
33
34
  if (layout == "studio") return "Studio";
@@ -53,6 +54,8 @@ export class TourScheduler extends LitElement {
53
54
  unitOptions: UnitV2[] = [];
54
55
  @property({ attribute: false })
55
56
  tourTypeOptions: LabeledOption[] = [];
57
+ @property({ attribute: true })
58
+ chatId = "";
56
59
  @property({ type: Number })
57
60
  buildingId = 0;
58
61
  @property({ attribute: true })
@@ -96,6 +99,9 @@ export class TourScheduler extends LitElement {
96
99
  @state()
97
100
  private tourIsBooked = false;
98
101
 
102
+ @property({ attribute: false })
103
+ leadSources: string[] = [];
104
+
99
105
  @query(".nameContainer#firstName input")
100
106
  firstNameInput!: HTMLInputElement;
101
107
  @query(".nameContainer#lastName input")
@@ -108,6 +114,8 @@ export class TourScheduler extends LitElement {
108
114
  unitTypeSelect!: MESelect;
109
115
  @query("me-select#layoutType")
110
116
  layoutTypeSelect!: MESelect;
117
+ @query("me-select#leadSource")
118
+ selectedLeadSource!: MESelect;
111
119
 
112
120
  firstUpdated = async (): Promise<void> => {
113
121
  const availabilitiesExistForTourType =
@@ -308,13 +316,15 @@ export class TourScheduler extends LitElement {
308
316
  this.phoneNumber.length === 14
309
317
  );
310
318
  },
319
+ leadSource: (): boolean => !!this.selectedLeadSource?.value,
311
320
  };
312
321
 
313
322
  formIsValidForSubmission = (): boolean => {
314
323
  const isValid =
315
324
  this.validators.tourType() &&
316
325
  this.validators.dateAndTime() &&
317
- this.validators.leadInfo();
326
+ this.validators.leadInfo() &&
327
+ this.validators.leadSource();
318
328
  return isValid;
319
329
  };
320
330
 
@@ -367,6 +377,13 @@ export class TourScheduler extends LitElement {
367
377
  ["org-slug"]: this.orgSlug,
368
378
  },
369
379
  });
380
+ await postLeadSources({
381
+ chatId: this.chatId,
382
+ website: window.location.origin,
383
+ referrer: document.referrer,
384
+ buildingSlug: this.buildingSlug,
385
+ selectedLeadSource: this.selectedLeadSource.value ?? "",
386
+ });
370
387
  this.isSubmitting = false;
371
388
  this.tourIsBooked = true;
372
389
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -401,7 +418,7 @@ export class TourScheduler extends LitElement {
401
418
  /* grid stuff */
402
419
  display: grid;
403
420
  grid-template-columns: 229px 432px 305px;
404
- grid-template-rows: 44px 54px 32px 195px 167px 1px;
421
+ grid-template-rows: 44px 54px 32px 245px 117px 1px;
405
422
  }
406
423
 
407
424
  @media screen and (max-width: 1000px) {
@@ -503,8 +520,6 @@ export class TourScheduler extends LitElement {
503
520
  #yourInformationMenu input {
504
521
  width: 100%;
505
522
  height: 49px;
506
- border: 1px solid #83818e;
507
- padding: 13px 11px 14px 11px;
508
523
  }
509
524
 
510
525
  .unitLayoutChoices {
@@ -514,9 +529,15 @@ export class TourScheduler extends LitElement {
514
529
  display: flex;
515
530
  flex-direction: column;
516
531
  }
532
+ .unitLayoutChoicesDropdowns {
533
+ display: flex;
534
+ justify-content: space-between;
535
+ gap: 6px;
536
+ }
517
537
 
518
538
  .unitLayoutChoice {
519
539
  margin-bottom: 12px;
540
+ width: -webkit-fill-available;
520
541
  }
521
542
 
522
543
  h2.unitLayoutChoice {
@@ -1046,92 +1067,126 @@ export class TourScheduler extends LitElement {
1046
1067
  </div>
1047
1068
  </div>
1048
1069
 
1049
- <div class="inputContainer" id="email">
1050
- <input
1051
- class="webchat-input"
1052
- type="email"
1053
- inputmode="email"
1054
- placeholder="Email"
1055
- name="email"
1056
- autocomplete="email"
1057
- .value=${this.email}
1058
- @input=${this.onChangeEmail}
1059
- />
1070
+ <div class="inputContainer" id="email">
1071
+ <input
1072
+ class="webchat-input"
1073
+ type="email"
1074
+ inputmode="email"
1075
+ placeholder="Email"
1076
+ name="email"
1077
+ autocomplete="email"
1078
+ .value=${this.email}
1079
+ @input=${this.onChangeEmail}
1080
+ />
1081
+ </div>
1082
+ <div class="inputContainer" id="phone">
1083
+ <input
1084
+ class="webchat-input"
1085
+ type="tel"
1086
+ inputmode="tel"
1087
+ placeholder="Phone"
1088
+ name="phone"
1089
+ autocomplete="tel-national"
1090
+ maxlength="14"
1091
+ .value=${this.phoneNumber}
1092
+ @keydown=${this.handlePhoneKeydown}
1093
+ @keyup=${this.handlePhoneKeyup}
1094
+ @input=${(e: Event) => {
1095
+ if (!e.target) {
1096
+ return;
1097
+ }
1098
+ this.phoneNumber = formatToPhone(
1099
+ (e.target as HTMLInputElement).value
1100
+ );
1101
+ }}
1102
+ />
1103
+ </div>
1104
+ <me-select
1105
+ id="leadSource"
1106
+ placeholder="How did you hear about us?"
1107
+ .options="${this.leadSources.map((i) => ({
1108
+ label: i,
1109
+ value: i,
1110
+ }))}"
1111
+ @change=${() => {
1112
+ this.requestUpdate();
1113
+ }}
1114
+ >
1115
+ </me-select>
1060
1116
  </div>
1061
- <div class="inputContainer" id="phone">
1062
- <input
1063
- class="webchat-input"
1064
- type="tel"
1065
- inputmode="tel"
1066
- placeholder="Phone"
1067
- name="phone"
1068
- autocomplete="tel-national"
1069
- maxlength="14"
1070
- .value=${this.phoneNumber}
1071
- @keydown=${this.handlePhoneKeydown}
1072
- @keyup=${this.handlePhoneKeyup}
1073
- @input=${(e: Event) => {
1074
- if (!e.target) {
1075
- return;
1076
- }
1077
- this.phoneNumber = formatToPhone(
1078
- (e.target as HTMLInputElement).value
1079
- );
1080
- }}
1081
- />
1117
+
1118
+
1119
+
1120
+
1121
+ <div class="unitLayoutChoices">
1122
+
1123
+
1124
+ ${
1125
+ this.layoutOptions.length > 0
1126
+ ? html`<h2 class="unitLayoutChoice">
1127
+ What would you like to view?
1128
+ </h2>`
1129
+ : ""
1130
+ }
1131
+ <div class="unitLayoutChoicesDropdowns">
1132
+ ${
1133
+ this.layoutOptions.length > 0
1134
+ ? html`<div class="unitLayoutChoice">
1135
+ <div class="unitLayoutOptions">
1136
+ <me-select
1137
+ id="layoutType"
1138
+ placeholder="Select layout"
1139
+ .options="${sortedLayouts(this.layoutOptions).map(
1140
+ (i) => ({
1141
+ label: getHumanReadableLayout(i),
1142
+ value: i,
1143
+ })
1144
+ )}"
1145
+ defaultOption="Studio"
1146
+ @change=${() => {
1147
+ // to revalidate the form.
1148
+ this.requestUpdate();
1149
+ }}
1150
+ >Studio
1151
+ </me-select>
1152
+ </div>
1153
+ </div>`
1154
+ : ""
1155
+ }
1156
+ ${
1157
+ this.unitOptions.filter(
1158
+ (i) =>
1159
+ !this.layoutTypeSelect ||
1160
+ i.layout === this.layoutTypeSelect.value
1161
+ ).length > 0
1162
+ ? html`
1163
+ <me-select
1164
+ id="unitType"
1165
+ placeholder="Select unit"
1166
+ .options="${this.unitOptions
1167
+ .filter(
1168
+ (i) =>
1169
+ !this.layoutTypeSelect ||
1170
+ i.layout === this.layoutTypeSelect.value
1171
+ )
1172
+ .map((i) => ({
1173
+ label: i.name,
1174
+ value: i.name,
1175
+ }))}"
1176
+ defaultOption="Studio"
1177
+ @change=${() => {
1178
+ // to revalidate the form
1179
+ this.requestUpdate();
1180
+ }}
1181
+ >Studio
1182
+ </me-select>
1183
+ `
1184
+ : ""
1185
+ }
1186
+ </div>
1187
+
1188
+
1082
1189
  </div>
1083
- </div>
1084
- <div class="unitLayoutChoices">
1085
- ${this.layoutOptions.length > 0
1086
- ? html`<div class="unitLayoutChoice">
1087
- <h2 class="unitLayoutChoice">What would you like to view?</h2>
1088
- <div class="unitLayoutOptions">
1089
- <me-select
1090
- id="layoutType"
1091
- placeholder="Select layout"
1092
- .options="${sortedLayouts(this.layoutOptions).map((i) => ({
1093
- label: getHumanReadableLayout(i),
1094
- value: i,
1095
- }))}"
1096
- defaultOption="Studio"
1097
- @change=${() => {
1098
- // to revalidate the form.
1099
- this.requestUpdate();
1100
- }}
1101
- >Studio
1102
- </me-select>
1103
- </div>
1104
- </div>`
1105
- : ""}
1106
- ${this.unitOptions.filter(
1107
- (i) =>
1108
- !this.layoutTypeSelect || i.layout === this.layoutTypeSelect.value
1109
- ).length > 0
1110
- ? html`<div class="unitLayoutChoice">
1111
- <div class="unitLayoutOptions">
1112
- <me-select
1113
- id="unitType"
1114
- placeholder="Select unit"
1115
- .options="${this.unitOptions
1116
- .filter(
1117
- (i) =>
1118
- !this.layoutTypeSelect ||
1119
- i.layout === this.layoutTypeSelect.value
1120
- )
1121
- .map((i) => ({
1122
- label: i.name,
1123
- value: i.name,
1124
- }))}"
1125
- defaultOption="Studio"
1126
- @change=${() => {
1127
- // to revalidate the form
1128
- this.requestUpdate();
1129
- }}
1130
- >Studio
1131
- </me-select>
1132
- </div>
1133
- </div>`
1134
- : ""}
1135
1190
  </div> `;
1136
1191
  }
1137
1192
 
@@ -1199,6 +1254,8 @@ export class TourScheduler extends LitElement {
1199
1254
  class="${classnames("tour-scheduler", {
1200
1255
  loading: this.waitingForAvailabilities,
1201
1256
  })}"
1257
+ @leadsource="${(e: CustomEvent) =>
1258
+ (this.selectedLeadSource = e.detail.selectedLeadSource)}"
1202
1259
  >
1203
1260
  <h1 id="scheduleATour">
1204
1261
  ${this.waitingForAvailabilities
@@ -5,15 +5,15 @@ export const InputStyles = css`
5
5
  outline: none;
6
6
  color: #202020;
7
7
  font-weight: 400;
8
- font-size: 14px;
9
- line-height: 14px;
8
+ font-size: 16px;
9
+ line-height: 16px;
10
10
  font-family: "Poppins";
11
11
 
12
12
  background: #ffffff;
13
13
  border-radius: 20px;
14
14
  border: none;
15
15
  padding: 0px 20px;
16
- border: 1px solid #ffffff;
16
+ border: 1px solid #83818e;
17
17
  }
18
18
  .webchat-textarea {
19
19
  padding: 20px 20px;
@@ -28,7 +28,7 @@ export const InputStyles = css`
28
28
  }
29
29
 
30
30
  .webchat-input::placeholder {
31
- opacity: 0.5;
31
+ color: rgba(32, 32, 32, 0.5);
32
32
  font-family: "Poppins";
33
33
  font-size: 16px;
34
34
  }
@@ -37,10 +37,6 @@ export class DetailsWindow extends LitElement {
37
37
  justify-content: space-between;
38
38
  }
39
39
  .header-text {
40
- font-weight: 700;
41
- font-size: 14px;
42
- line-height: 22px;
43
-
44
40
  font-family: "Helvetica";
45
41
  font-style: normal;
46
42
  font-weight: 700;
@@ -96,7 +92,6 @@ export class DetailsWindow extends LitElement {
96
92
  ["details-window-wrapper"]: !this.useGradientDesign,
97
93
  })}
98
94
  style=${styleMap({
99
- height: this.height,
100
95
  width: this.isMobileSized ? "-webkit-fill-available" : this.width,
101
96
  })}
102
97
  >
@@ -1,9 +1,12 @@
1
1
  import { css, html, LitElement, TemplateResult } from "lit";
2
- import { customElement, property, state } from "lit/decorators.js";
2
+ import { customElement, property, query, state } from "lit/decorators.js";
3
3
  import { classMap } from "lit/directives/class-map.js";
4
4
  import { createRef, ref, Ref } from "lit/directives/ref.js";
5
5
  import { installActionConfirmButton } from "./action-confirm-button";
6
6
  import { installDetailsWindow } from "./details-window";
7
+ import postLeadSources from "../../postLeadSources";
8
+ import "../me-select.ts";
9
+ import { MESelect } from "../me-select";
7
10
  import {
8
11
  formatToPhone,
9
12
  isModifierKey,
@@ -90,9 +93,14 @@ export class EmailUsWindow extends LitElement {
90
93
  InputStyles,
91
94
  ];
92
95
 
96
+ @property({ attribute: false })
97
+ leadSources: string[] = [];
98
+
93
99
  @property({ attribute: false })
94
100
  onCloseClicked?: (e: MouseEvent) => void;
95
101
 
102
+ @property({ attribute: true })
103
+ chatId = "";
96
104
  @property({ attribute: false })
97
105
  buildingId = 0;
98
106
  @property({ attribute: true })
@@ -118,6 +126,9 @@ export class EmailUsWindow extends LitElement {
118
126
  @state()
119
127
  message = "";
120
128
 
129
+ @query("me-select#leadSource")
130
+ selectedLeadSource!: MESelect;
131
+
121
132
  @state()
122
133
  hasNameError = false;
123
134
  @state()
@@ -127,6 +138,8 @@ export class EmailUsWindow extends LitElement {
127
138
  @state()
128
139
  hasMessageError = false;
129
140
  @state()
141
+ hasLeadSourceError = false;
142
+ @state()
130
143
  hasSubmittedForm = false;
131
144
  @state()
132
145
  windowHeight = 525;
@@ -192,6 +205,7 @@ export class EmailUsWindow extends LitElement {
192
205
  this.hasEmailError = false;
193
206
  this.hasPhoneNumberError = false;
194
207
  this.hasMessageError = false;
208
+ this.hasLeadSourceError = false;
195
209
  this.hasSubmissionError = false;
196
210
  if (!this.firstName || !this.lastName) {
197
211
  this.hasNameError = true;
@@ -205,6 +219,9 @@ export class EmailUsWindow extends LitElement {
205
219
  if (!this.message) {
206
220
  this.hasMessageError = true;
207
221
  }
222
+ if (!this.selectedLeadSource || !this.selectedLeadSource.value) {
223
+ this.hasLeadSourceError = true;
224
+ }
208
225
  this.windowHeight = 525 + 30 * this.getNumErrors();
209
226
  };
210
227
 
@@ -217,7 +234,8 @@ export class EmailUsWindow extends LitElement {
217
234
  this.hasNameError ||
218
235
  this.hasEmailError ||
219
236
  this.hasPhoneNumberError ||
220
- this.hasMessageError
237
+ this.hasMessageError ||
238
+ this.hasLeadSourceError
221
239
  ) {
222
240
  return;
223
241
  }
@@ -235,6 +253,13 @@ export class EmailUsWindow extends LitElement {
235
253
  this.orgSlug,
236
254
  this.buildingSlug
237
255
  );
256
+ postLeadSources({
257
+ chatId: this.chatId,
258
+ website: window.location.origin,
259
+ referrer: document.referrer,
260
+ buildingSlug: this.buildingSlug,
261
+ selectedLeadSource: this.selectedLeadSource.value ?? "",
262
+ });
238
263
  this.hasSubmittedForm = true;
239
264
  this.isSubmitting = false;
240
265
  // Remove the height of the button when it leaves the loading state
@@ -253,6 +278,7 @@ export class EmailUsWindow extends LitElement {
253
278
  this.hasEmailError,
254
279
  this.hasPhoneNumberError,
255
280
  this.hasMessageError,
281
+ this.hasLeadSourceError,
256
282
  this.hasSubmissionError,
257
283
  ].filter((v) => v).length;
258
284
  };
@@ -298,7 +324,6 @@ export class EmailUsWindow extends LitElement {
298
324
  <details-window
299
325
  headerText="Email our leasing team"
300
326
  .onCloseClick=${this.onCloseClicked}
301
- height="${this.windowHeight}px"
302
327
  useGradientDesign="true"
303
328
  >
304
329
  <div class="email-us-wrapper">
@@ -371,6 +396,22 @@ export class EmailUsWindow extends LitElement {
371
396
  `
372
397
  : ""}
373
398
  <div class="email-us__vertical-spacer"></div>
399
+ <me-select
400
+ id="leadSource"
401
+ placeholder="How did you hear about us?"
402
+ .options="${this.leadSources.map((i) => ({
403
+ label: i,
404
+ value: i,
405
+ }))}"
406
+ @change=${() => {
407
+ this.requestUpdate();
408
+ }}
409
+ >
410
+ </me-select>
411
+ ${this.hasLeadSourceError
412
+ ? html` <div class="email-us__error-text">Include a source</div> `
413
+ : ""}
414
+ <div class="email-us__vertical-spacer"></div>
374
415
  <textarea
375
416
  placeholder="Message"
376
417
  .value=${this.message}
@@ -10,6 +10,7 @@ import { createChatID, getChatID } from "../chatID";
10
10
  import createConversation from "../createConversation";
11
11
  import fetchBuildingInfo, { Building } from "../fetchBuildingInfo";
12
12
  import fetchBuildingABTestType from "../fetchBuildingABTestType";
13
+ import fetchCurrentParsedLeadSource from "../fetchCurrentParsedLeadSource";
13
14
  import { getTheme, Theme, ThemeIdString } from "../themes";
14
15
  import { isMobile } from "../utils";
15
16
  import { installLauncher } from "./Launcher";
@@ -22,6 +23,7 @@ import { getRawAvailabilities } from "../getAvailabilities";
22
23
  import { StyleInfo } from "lit/directives/style-map";
23
24
  import addMinutes from "date-fns/addMinutes";
24
25
  import formatISO from "date-fns/formatISO";
26
+ import fetchLeadSources from "../fetchLeadSources";
25
27
 
26
28
  export interface Options {
27
29
  building: string;
@@ -131,6 +133,10 @@ export class MEChat extends LitElement {
131
133
  @state()
132
134
  private buildingABTestType: string | null = null;
133
135
  @state()
136
+ private leadSources: string[] | null = null;
137
+ @state()
138
+ private currentLeadSource: string | null = null;
139
+ @state()
134
140
  private hasMounted = false;
135
141
  @state()
136
142
  private hideLauncher = false;
@@ -138,8 +144,6 @@ export class MEChat extends LitElement {
138
144
  private isLoading = true;
139
145
  @state()
140
146
  private talkjsPopupElement: Element | null = null;
141
- @state()
142
- private myContactHeader: Element | null = null;
143
147
 
144
148
  private yardiDNIScriptInterval: NodeJS.Timer | null = null;
145
149
  launcherRef: Ref<Launcher> = createRef();
@@ -157,6 +161,8 @@ export class MEChat extends LitElement {
157
161
  }
158
162
  this.building = await fetchBuildingInfo(this.orgSlug, this.buildingSlug);
159
163
  const buildingABTest = await fetchBuildingABTestType(this.buildingSlug);
164
+ this.leadSources = await fetchLeadSources(this.buildingSlug);
165
+ this.currentLeadSource = await fetchCurrentParsedLeadSource();
160
166
 
161
167
  this.buildingABTestType = buildingABTest?.abTestType ?? "";
162
168
  getRawAvailabilities(this.building.id); // we're not using this here, just want to cache the result
@@ -435,6 +441,7 @@ export class MEChat extends LitElement {
435
441
  .launcherStyles=${this.launcherStyles}
436
442
  .autoOpenChatWidget=${this.building.autoOpenChatWidget ?? false}
437
443
  chatCallUsHeader=${this.building?.chatCallUsHeader ?? ""}
444
+ chatId="${this.chatId}"
438
445
  phoneNumber="${this.building?.phoneNumber ?? ""}"
439
446
  textColor="${this.theme.chatHeader.textColor}"
440
447
  backgroundColor="${this.theme.chatPaneBackgroundColor}"
@@ -442,6 +449,8 @@ export class MEChat extends LitElement {
442
449
  buildingSlug="${this.buildingSlug}"
443
450
  sgtUrl="${this.building?.sgtUrl ?? ""}"
444
451
  buildingABTestType="${this.buildingABTestType ?? ""}"
452
+ currentLeadSource="${this.currentLeadSource ?? ""}"
453
+ .leadSources="${this.leadSources ?? []}"
445
454
  escortedToursLink="${this.building?.escortedToursLink ?? ""}"
446
455
  virtualToursLink="${this.building?.virtualToursLink ?? ""}"
447
456
  ?hidden=${this.hideLauncher}