@meetelise/chat 1.40.1 → 1.40.3
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/WebComponent/Scheduler/date-picker.d.ts +2 -0
- package/dist/src/WebComponent/Scheduler/time-picker.d.ts +3 -1
- package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +4 -0
- package/dist/src/WebComponent/launcher/Launcher.d.ts +1 -0
- package/dist/src/getAvailabilities.d.ts +10 -0
- package/package.json +1 -1
- package/public/dist/index.js +163 -159
- package/src/WebComponent/Scheduler/date-picker.ts +11 -1
- package/src/WebComponent/Scheduler/time-picker.ts +14 -2
- package/src/WebComponent/Scheduler/tour-scheduler.ts +122 -1
- package/src/WebComponent/launcher/Launcher.ts +3 -0
- package/src/WebComponent/me-chat.ts +2 -0
- package/src/fetchBuildingWebchatView.ts +1 -1
- package/src/getAvailabilities.ts +10 -1
|
@@ -32,12 +32,15 @@ export class DatePicker extends LitElement {
|
|
|
32
32
|
@property({ attribute: "year", type: Number })
|
|
33
33
|
defaultYear?: number;
|
|
34
34
|
|
|
35
|
+
@property({ attribute: true })
|
|
36
|
+
defaultDate?: Date;
|
|
37
|
+
|
|
35
38
|
@property({ attribute: false })
|
|
36
39
|
availabilities?: {
|
|
37
40
|
[day: string]: Date[];
|
|
38
41
|
};
|
|
39
42
|
|
|
40
|
-
private _selectedDate?: Date =
|
|
43
|
+
private _selectedDate?: Date = this.defaultDate;
|
|
41
44
|
set selectedDate(date: Date | undefined) {
|
|
42
45
|
const old = this._selectedDate;
|
|
43
46
|
this._selectedDate = date;
|
|
@@ -55,6 +58,13 @@ export class DatePicker extends LitElement {
|
|
|
55
58
|
return this._selectedDate;
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
protected firstUpdated(): void {
|
|
62
|
+
if (!this.defaultDate) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.selectedDate = this.defaultDate;
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
now = new Date();
|
|
59
69
|
|
|
60
70
|
private _monthShown =
|
|
@@ -31,14 +31,26 @@ export class TimePicker extends LitElement {
|
|
|
31
31
|
@property({ attribute: true })
|
|
32
32
|
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
33
33
|
|
|
34
|
+
@property({ attribute: true })
|
|
35
|
+
defaultSelectedTime?: TimePickerOption | null = null;
|
|
36
|
+
|
|
34
37
|
@state()
|
|
35
|
-
private selected?: TimePickerOption;
|
|
38
|
+
private selected?: TimePickerOption | null = this.defaultSelectedTime;
|
|
36
39
|
|
|
37
40
|
@property({ attribute: false })
|
|
38
|
-
get selectedTime(): undefined | TimePickerOption {
|
|
41
|
+
get selectedTime(): undefined | TimePickerOption | null {
|
|
39
42
|
return this.selected;
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
willUpdate(changedProperties: Map<string, unknown>): void {
|
|
46
|
+
if (
|
|
47
|
+
changedProperties.has("defaultSelectedTime") &&
|
|
48
|
+
this.selected === null
|
|
49
|
+
) {
|
|
50
|
+
this.selected = this.defaultSelectedTime;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
static styles = css`
|
|
43
55
|
* {
|
|
44
56
|
box-sizing: border-box;
|
|
@@ -10,13 +10,19 @@ import "./date-picker.ts";
|
|
|
10
10
|
import "./time-picker.ts";
|
|
11
11
|
import "../me-select.ts";
|
|
12
12
|
import {
|
|
13
|
+
dateStringToDateWithTimeZoneOffset,
|
|
14
|
+
dateToDateWithTimeZoneOffset,
|
|
13
15
|
DateWithTimeZoneOffset,
|
|
14
16
|
getAvailabilitiesGroupedByDay,
|
|
15
17
|
getExistenceOfAvailabilitiesByTourType,
|
|
18
|
+
getRawAvailabilities,
|
|
16
19
|
getTimezoneForBuilding,
|
|
17
20
|
resetAvailabilitiesCache,
|
|
18
21
|
} from "../../getAvailabilities";
|
|
19
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
TourAvailabilityResponse,
|
|
24
|
+
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum,
|
|
25
|
+
} from "../../types/rest-sdk.types";
|
|
20
26
|
import { format } from "date-fns";
|
|
21
27
|
import { DatePicker } from "./date-picker";
|
|
22
28
|
import { MESelect } from "../me-select";
|
|
@@ -46,6 +52,7 @@ import { TourWithAgentIcon } from "../icons/TourWithAgentIcon";
|
|
|
46
52
|
import { shouldOpenTourLink } from "../../fetchBuildingWebchatView";
|
|
47
53
|
import formatInTimeZone from "date-fns-tz/formatInTimeZone";
|
|
48
54
|
import { getTimezoneAbbreviation } from "../../getTimezoneString";
|
|
55
|
+
import startOfDay from "date-fns/startOfDay";
|
|
49
56
|
|
|
50
57
|
@customElement("tour-scheduler")
|
|
51
58
|
export class TourScheduler extends LitElement {
|
|
@@ -66,6 +73,8 @@ export class TourScheduler extends LitElement {
|
|
|
66
73
|
@property({ attribute: true })
|
|
67
74
|
escortedToursLink = "";
|
|
68
75
|
@property({ attribute: true })
|
|
76
|
+
escortedToursTypeOffered = "";
|
|
77
|
+
@property({ attribute: true })
|
|
69
78
|
virtualToursLink = "";
|
|
70
79
|
@property({ attribute: true })
|
|
71
80
|
virtualToursTypeOffered = "";
|
|
@@ -234,6 +243,40 @@ export class TourScheduler extends LitElement {
|
|
|
234
243
|
}
|
|
235
244
|
}, 0) === 1;
|
|
236
245
|
|
|
246
|
+
const availabilities = await getRawAvailabilities(this.buildingId);
|
|
247
|
+
const highestRankedTourType =
|
|
248
|
+
this._getHighestRankedTourType(availabilities);
|
|
249
|
+
const availableTimesForHighestRankedTourType = highestRankedTourType
|
|
250
|
+
? availabilities.availability?.[highestRankedTourType]
|
|
251
|
+
?.availableTourStartTimes
|
|
252
|
+
: [];
|
|
253
|
+
const firstAvailableTimeSlotForHighestRankedTourType =
|
|
254
|
+
availableTimesForHighestRankedTourType?.[0];
|
|
255
|
+
if (
|
|
256
|
+
highestRankedTourType &&
|
|
257
|
+
firstAvailableTimeSlotForHighestRankedTourType &&
|
|
258
|
+
highestRankedTourType !==
|
|
259
|
+
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.Unknown &&
|
|
260
|
+
highestRankedTourType !==
|
|
261
|
+
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.MediaTour
|
|
262
|
+
) {
|
|
263
|
+
this.selectedDate =
|
|
264
|
+
typeof firstAvailableTimeSlotForHighestRankedTourType === "string"
|
|
265
|
+
? startOfDay(
|
|
266
|
+
parseISO(firstAvailableTimeSlotForHighestRankedTourType)
|
|
267
|
+
)
|
|
268
|
+
: startOfDay(firstAvailableTimeSlotForHighestRankedTourType);
|
|
269
|
+
this.tourType = rankedOrderTourTypeToTourType[highestRankedTourType];
|
|
270
|
+
this.selectedTime =
|
|
271
|
+
typeof firstAvailableTimeSlotForHighestRankedTourType === "string"
|
|
272
|
+
? dateStringToDateWithTimeZoneOffset(
|
|
273
|
+
firstAvailableTimeSlotForHighestRankedTourType
|
|
274
|
+
)
|
|
275
|
+
: dateToDateWithTimeZoneOffset(
|
|
276
|
+
firstAvailableTimeSlotForHighestRankedTourType
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
237
280
|
if (hasOneShowTourType) {
|
|
238
281
|
this.tourType = Object.keys(this.shouldShowTourType).find(
|
|
239
282
|
(key) => this.shouldShowTourType[key as TourType]
|
|
@@ -271,6 +314,56 @@ export class TourScheduler extends LitElement {
|
|
|
271
314
|
}
|
|
272
315
|
};
|
|
273
316
|
|
|
317
|
+
_getHighestRankedTourType = (
|
|
318
|
+
availabilities: TourAvailabilityResponse
|
|
319
|
+
): TourAvailabilityResponseRankOrderedSupportedTourTypesEnum => {
|
|
320
|
+
const rankedTourTypeToAvailabilities = (
|
|
321
|
+
availabilities.rankOrderedSupportedTourTypes ?? []
|
|
322
|
+
)
|
|
323
|
+
.map((tt) => {
|
|
324
|
+
return {
|
|
325
|
+
tourType: tt,
|
|
326
|
+
availabilities:
|
|
327
|
+
availabilities.availability?.[tt]?.availableTourStartTimes,
|
|
328
|
+
};
|
|
329
|
+
})
|
|
330
|
+
.filter((rtt) => {
|
|
331
|
+
if (
|
|
332
|
+
rtt.tourType ===
|
|
333
|
+
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.Unknown ||
|
|
334
|
+
rtt.tourType ===
|
|
335
|
+
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.MediaTour
|
|
336
|
+
) {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
const convertedTourType = rankedOrderTourTypeToTourType[rtt.tourType];
|
|
340
|
+
const tourTypeOffered = this._getTourTypeOffered(convertedTourType);
|
|
341
|
+
|
|
342
|
+
if (!tourTypeOffered) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
return (
|
|
346
|
+
!shouldOpenTourLink(convertedTourType, tourTypeOffered) &&
|
|
347
|
+
rtt.availabilities &&
|
|
348
|
+
rtt.availabilities.length > 0
|
|
349
|
+
);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
const highestRankedTourType = rankedTourTypeToAvailabilities[0];
|
|
353
|
+
return highestRankedTourType.tourType;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
_getTourTypeOffered = (tourType: TourType): string | null => {
|
|
357
|
+
if (tourType === TourType.Guided) {
|
|
358
|
+
return this.escortedToursTypeOffered;
|
|
359
|
+
} else if (tourType === TourType.Self) {
|
|
360
|
+
return this.selfGuidedToursTypeOffered;
|
|
361
|
+
} else if (tourType === TourType.Virtual) {
|
|
362
|
+
return this.virtualToursTypeOffered;
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
};
|
|
366
|
+
|
|
274
367
|
firstUpdated = async (): Promise<void> => {
|
|
275
368
|
await this._setAvailabilities();
|
|
276
369
|
};
|
|
@@ -756,6 +849,7 @@ export class TourScheduler extends LitElement {
|
|
|
756
849
|
this.availabilitiesGroupedByDay,
|
|
757
850
|
(dates) => dates.map((date) => new Date(date.offset))
|
|
758
851
|
)}
|
|
852
|
+
.defaultDate=${this.selectedDate}
|
|
759
853
|
@change=${(e: Event) => {
|
|
760
854
|
// if the user clicked a tour type that is suppose to redirect, we redirect that use when they select a date
|
|
761
855
|
// This can happen if the user clicks, is redirect, and then comes back to the webchat
|
|
@@ -792,6 +886,24 @@ export class TourScheduler extends LitElement {
|
|
|
792
886
|
<time-picker
|
|
793
887
|
?selecteddateexists=${!!this.selectedDate}
|
|
794
888
|
.timezone=${this.calendarTimeZone}
|
|
889
|
+
.defaultSelectedTime=${this.selectedTime
|
|
890
|
+
? {
|
|
891
|
+
dateWithTimeZoneOffset: this.selectedTime,
|
|
892
|
+
displayTime: format(
|
|
893
|
+
parseISO(
|
|
894
|
+
`${this.selectedTime.datetime}${this.selectedTime.offset}`
|
|
895
|
+
),
|
|
896
|
+
"h:mmaaa"
|
|
897
|
+
),
|
|
898
|
+
displayTimeZoned: formatInTimeZone(
|
|
899
|
+
parseISO(
|
|
900
|
+
`${this.selectedTime.datetime}${this.selectedTime.offset}`
|
|
901
|
+
),
|
|
902
|
+
this.calendarTimeZone,
|
|
903
|
+
"h:mmaaa"
|
|
904
|
+
),
|
|
905
|
+
}
|
|
906
|
+
: null}
|
|
795
907
|
.options=${this.selectedDate
|
|
796
908
|
? this.availabilitiesGroupedByDay[
|
|
797
909
|
format(this.selectedDate, "y-MM-dd")
|
|
@@ -1423,6 +1535,15 @@ const tourTypeMap = {
|
|
|
1423
1535
|
TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.VirtualShowing,
|
|
1424
1536
|
};
|
|
1425
1537
|
|
|
1538
|
+
const rankedOrderTourTypeToTourType = {
|
|
1539
|
+
[TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.WithAgent]:
|
|
1540
|
+
TourType.Guided,
|
|
1541
|
+
[TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.SelfGuided]:
|
|
1542
|
+
TourType.Self,
|
|
1543
|
+
[TourAvailabilityResponseRankOrderedSupportedTourTypesEnum.VirtualShowing]:
|
|
1544
|
+
TourType.Virtual,
|
|
1545
|
+
};
|
|
1546
|
+
|
|
1426
1547
|
const tourTypeForSubmission = {
|
|
1427
1548
|
[TourType.Guided]: "escorted-tour",
|
|
1428
1549
|
[TourType.Self]: "self-guided-tour",
|
|
@@ -99,6 +99,8 @@ export class Launcher extends LitElement {
|
|
|
99
99
|
@property({ attribute: true })
|
|
100
100
|
escortedToursLink = "";
|
|
101
101
|
@property({ attribute: true })
|
|
102
|
+
escortedToursTypeOffered = "";
|
|
103
|
+
@property({ attribute: true })
|
|
102
104
|
virtualToursLink = "";
|
|
103
105
|
@property({ attribute: true })
|
|
104
106
|
virtualToursTypeOffered = "";
|
|
@@ -1201,6 +1203,7 @@ export class Launcher extends LitElement {
|
|
|
1201
1203
|
selfGuidedTourEnabled="${this.selfGuidedTourEnabled}"
|
|
1202
1204
|
selfGuidedToursTypeOffered="${this.selfGuidedToursTypeOffered}"
|
|
1203
1205
|
escortedToursLink="${this.escortedToursLink}"
|
|
1206
|
+
.escortedToursTypeOffered="${this.escortedToursTypeOffered}"
|
|
1204
1207
|
virtualToursLink="${this.virtualToursLink}"
|
|
1205
1208
|
virtualToursTypeOffered="${this.virtualToursTypeOffered}"
|
|
1206
1209
|
currentLeadSource="${this.currentLeadSource}"
|
|
@@ -924,6 +924,8 @@ export class MEChat extends LitElement {
|
|
|
924
924
|
.leadSources="${this.leadSources ?? []}"
|
|
925
925
|
escortedToursLink="${this.buildingWebchatView
|
|
926
926
|
?.escortedToursLink ?? ""}"
|
|
927
|
+
.escortedToursTypeOffered="${this.buildingWebchatView
|
|
928
|
+
.escortedToursTypeOffered}"
|
|
927
929
|
virtualToursLink="${this.buildingWebchatView
|
|
928
930
|
?.virtualToursLink ?? ""}"
|
|
929
931
|
virtualToursTypeOffered="${this.buildingWebchatView
|
package/src/getAvailabilities.ts
CHANGED
|
@@ -181,9 +181,18 @@ export const getAvailabilitiesGroupedByDay = async (
|
|
|
181
181
|
* // returns { datetime: '2022-06-27T09:00:00', offset: '-07:00' }
|
|
182
182
|
* dateStringToDateWithTimeZoneOffset('2022-06-27T09:00:00-07:00')
|
|
183
183
|
* */
|
|
184
|
-
const dateStringToDateWithTimeZoneOffset = (
|
|
184
|
+
export const dateStringToDateWithTimeZoneOffset = (
|
|
185
185
|
dateString: string
|
|
186
186
|
): DateWithTimeZoneOffset => ({
|
|
187
187
|
datetime: dateString.slice(0, 19),
|
|
188
188
|
offset: dateString.slice(19),
|
|
189
189
|
});
|
|
190
|
+
|
|
191
|
+
export const dateToDateWithTimeZoneOffset = (
|
|
192
|
+
date: Date
|
|
193
|
+
): DateWithTimeZoneOffset => {
|
|
194
|
+
const datetime = format(date, "yyyy-MM-dd'T'HH:mm:ss");
|
|
195
|
+
const offset = format(date, "xxx");
|
|
196
|
+
|
|
197
|
+
return { datetime, offset };
|
|
198
|
+
};
|