@meetelise/chat 1.47.2 → 1.48.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/main/MEChat.d.ts +43 -2
- package/package.json +1 -1
- package/public/dist/index.js +36 -36
- package/src/main/MEChat.test.ts +19 -0
- package/src/main/MEChat.ts +171 -6
package/src/main/MEChat.test.ts
CHANGED
|
@@ -49,6 +49,25 @@ afterEach(() => {
|
|
|
49
49
|
restore();
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
it("does not throw when removing a widget that already detached itself", async function () {
|
|
53
|
+
const element = document.createElement("me-chat");
|
|
54
|
+
document.body.appendChild(element);
|
|
55
|
+
|
|
56
|
+
(MEChat as unknown as { meChat: HTMLElement | null }).meChat = element;
|
|
57
|
+
|
|
58
|
+
await (
|
|
59
|
+
MEChat as unknown as { removeWidget: () => Promise<void> }
|
|
60
|
+
).removeWidget();
|
|
61
|
+
|
|
62
|
+
expect((MEChat as unknown as { meChat: HTMLElement | null }).meChat).to.equal(
|
|
63
|
+
null
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
await (
|
|
67
|
+
MEChat as unknown as { removeWidget: () => Promise<void> }
|
|
68
|
+
).removeWidget();
|
|
69
|
+
});
|
|
70
|
+
|
|
52
71
|
it.skip("shows the launcher", async function () {
|
|
53
72
|
// Given an API that returns this building theme
|
|
54
73
|
stub(window, "fetch").resolves(stubResponse);
|
package/src/main/MEChat.ts
CHANGED
|
@@ -34,6 +34,47 @@ interface PositioningOptions {
|
|
|
34
34
|
export interface HealthcareOptions extends PositioningOptions {
|
|
35
35
|
id: string;
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
export type StudioWebchatMode = "host_managed_context";
|
|
39
|
+
|
|
40
|
+
export type StudioWebchatSessionScopeType =
|
|
41
|
+
| "building"
|
|
42
|
+
| "building_group"
|
|
43
|
+
| "site";
|
|
44
|
+
|
|
45
|
+
export interface StudioWebchatSessionScope {
|
|
46
|
+
type: StudioWebchatSessionScopeType;
|
|
47
|
+
key: string;
|
|
48
|
+
buildingSlug?: string;
|
|
49
|
+
siteId?: string;
|
|
50
|
+
buildingGroupId?: string | number;
|
|
51
|
+
defaultBuildingSlug?: string;
|
|
52
|
+
allowedBuildingSlugs?: string[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface StudioWebchatContext {
|
|
56
|
+
source?: "elise_studio";
|
|
57
|
+
siteId?: string;
|
|
58
|
+
propertyId?: string | number | null;
|
|
59
|
+
organization?: string | null;
|
|
60
|
+
building?: string | null;
|
|
61
|
+
buildingGroupId?: string | number | null;
|
|
62
|
+
sessionScope?: StudioWebchatSessionScope;
|
|
63
|
+
path?: string;
|
|
64
|
+
pageId?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface StudioWebchatClearContext {
|
|
68
|
+
source?: "elise_studio";
|
|
69
|
+
reason?: "no_property_for_route" | "webchat_disabled" | "ambiguous_route" | string;
|
|
70
|
+
preserveCache?: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface StudioWebchatOptions {
|
|
74
|
+
siteId: string;
|
|
75
|
+
mode?: StudioWebchatMode;
|
|
76
|
+
}
|
|
77
|
+
|
|
37
78
|
export default class MEChat {
|
|
38
79
|
static meChat: MEChatLitElement | null = null;
|
|
39
80
|
static healthChat: HealthChatLitElement | null = null;
|
|
@@ -45,6 +86,11 @@ export default class MEChat {
|
|
|
45
86
|
static brandColor = "";
|
|
46
87
|
static backgroundColor = "";
|
|
47
88
|
static healthcareId = "";
|
|
89
|
+
static activeStudioOrgSlug = "";
|
|
90
|
+
static activeStudioBuildingSlug = "";
|
|
91
|
+
static activeStudioSessionScopeKey = "";
|
|
92
|
+
static activeStudioOptions: Options | null = null;
|
|
93
|
+
static studioUpdateToken = 0;
|
|
48
94
|
static overridePlacement: {
|
|
49
95
|
right?: number;
|
|
50
96
|
bottom?: number;
|
|
@@ -91,7 +137,7 @@ export default class MEChat {
|
|
|
91
137
|
this.orgSlug =
|
|
92
138
|
opts.organization === "Pacific Urban Residential"
|
|
93
139
|
? "cbc11aba-21c4-4571-bc43-ff9d86a029e3"
|
|
94
|
-
: opts.organization;
|
|
140
|
+
: opts.organization || "";
|
|
95
141
|
this.hasBuildingSlug = !!opts.building;
|
|
96
142
|
this.overridePlacement = {
|
|
97
143
|
right: opts?.position?.right,
|
|
@@ -102,6 +148,11 @@ export default class MEChat {
|
|
|
102
148
|
}
|
|
103
149
|
installFont();
|
|
104
150
|
|
|
151
|
+
if (opts.studio && !opts.building) {
|
|
152
|
+
this.handleStudioContext(opts);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
105
156
|
let meChatElement:
|
|
106
157
|
| MEChatLitElement
|
|
107
158
|
| UtilitiesChatElement
|
|
@@ -131,7 +182,7 @@ export default class MEChat {
|
|
|
131
182
|
"orgSlug",
|
|
132
183
|
opts.organization === "Pacific Urban Residential"
|
|
133
184
|
? "cbc11aba-21c4-4571-bc43-ff9d86a029e3"
|
|
134
|
-
: opts.organization
|
|
185
|
+
: opts.organization || ""
|
|
135
186
|
);
|
|
136
187
|
meChatElement.setAttribute(
|
|
137
188
|
"widgetType",
|
|
@@ -216,14 +267,102 @@ export default class MEChat {
|
|
|
216
267
|
}
|
|
217
268
|
|
|
218
269
|
static async remove(): Promise<void> {
|
|
270
|
+
this.studioUpdateToken += 1;
|
|
271
|
+
await this.removeWidget();
|
|
272
|
+
this.activeStudioOrgSlug = "";
|
|
273
|
+
this.activeStudioBuildingSlug = "";
|
|
274
|
+
this.activeStudioSessionScopeKey = "";
|
|
275
|
+
this.activeStudioOptions = null;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
static async removeWidget(): Promise<void> {
|
|
219
279
|
if (!this.meChat) {
|
|
220
280
|
return;
|
|
221
281
|
}
|
|
222
|
-
|
|
223
|
-
|
|
282
|
+
const meChat = this.meChat;
|
|
283
|
+
await meChat.remove();
|
|
284
|
+
meChat.parentNode?.removeChild(meChat);
|
|
224
285
|
MEChat.meChat = null;
|
|
225
286
|
}
|
|
226
287
|
|
|
288
|
+
static handleStudioContext(opts: Options): void {
|
|
289
|
+
if (!opts.studio) return;
|
|
290
|
+
|
|
291
|
+
this.activeStudioOptions = opts;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
static updateStudioContext(context: StudioWebchatContext): void {
|
|
295
|
+
const opts = this.activeStudioOptions;
|
|
296
|
+
if (!opts?.studio) return;
|
|
297
|
+
const updateToken = ++this.studioUpdateToken;
|
|
298
|
+
|
|
299
|
+
if (context.siteId && context.siteId !== opts.studio.siteId) {
|
|
300
|
+
sendLoggingEvent({
|
|
301
|
+
logType: LogType.warn,
|
|
302
|
+
logTitle: "[STUDIO_WEBCHAT_CONTEXT_SITE_MISMATCH]",
|
|
303
|
+
logData: {
|
|
304
|
+
activeSiteId: opts.studio.siteId,
|
|
305
|
+
contextSiteId: context.siteId,
|
|
306
|
+
url: window.location.href,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const orgSlug = coerceStudioContextString(context.organization);
|
|
313
|
+
const buildingSlug = coerceStudioContextString(context.building);
|
|
314
|
+
|
|
315
|
+
if (!orgSlug || !buildingSlug) {
|
|
316
|
+
this.clearStudioContext({
|
|
317
|
+
source: "elise_studio",
|
|
318
|
+
reason: "missing_context",
|
|
319
|
+
preserveCache: true,
|
|
320
|
+
});
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const sessionScopeKey = coerceStudioSessionScopeKey(
|
|
325
|
+
context.sessionScope,
|
|
326
|
+
buildingSlug
|
|
327
|
+
);
|
|
328
|
+
const normalizedOrgSlug = normalizeOrgSlug(orgSlug);
|
|
329
|
+
|
|
330
|
+
if (
|
|
331
|
+
this.activeStudioOrgSlug === normalizedOrgSlug &&
|
|
332
|
+
this.activeStudioBuildingSlug === buildingSlug &&
|
|
333
|
+
this.activeStudioSessionScopeKey === sessionScopeKey
|
|
334
|
+
) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
void this.removeWidget().then(() => {
|
|
339
|
+
if (updateToken !== this.studioUpdateToken) return;
|
|
340
|
+
|
|
341
|
+
this.activeStudioOrgSlug = normalizedOrgSlug;
|
|
342
|
+
this.activeStudioBuildingSlug = buildingSlug;
|
|
343
|
+
this.activeStudioSessionScopeKey = sessionScopeKey;
|
|
344
|
+
this.orgSlug = normalizedOrgSlug;
|
|
345
|
+
|
|
346
|
+
this.start(
|
|
347
|
+
{
|
|
348
|
+
...opts,
|
|
349
|
+
organization: orgSlug,
|
|
350
|
+
building: buildingSlug,
|
|
351
|
+
},
|
|
352
|
+
false
|
|
353
|
+
);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
static clearStudioContext(_context?: StudioWebchatClearContext): void {
|
|
358
|
+
void _context;
|
|
359
|
+
this.studioUpdateToken += 1;
|
|
360
|
+
this.activeStudioOrgSlug = "";
|
|
361
|
+
this.activeStudioBuildingSlug = "";
|
|
362
|
+
this.activeStudioSessionScopeKey = "";
|
|
363
|
+
void this.removeWidget();
|
|
364
|
+
}
|
|
365
|
+
|
|
227
366
|
static async handleBuildingslug(
|
|
228
367
|
meChat: MEChatLitElement,
|
|
229
368
|
orgSlug?: string,
|
|
@@ -369,9 +508,35 @@ export default class MEChat {
|
|
|
369
508
|
}
|
|
370
509
|
}
|
|
371
510
|
|
|
511
|
+
function coerceStudioContextString(value: string | null | undefined): string {
|
|
512
|
+
if (typeof value !== "string") {
|
|
513
|
+
return "";
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return value.trim();
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function normalizeOrgSlug(orgSlug: string): string {
|
|
520
|
+
return orgSlug === "Pacific Urban Residential"
|
|
521
|
+
? "cbc11aba-21c4-4571-bc43-ff9d86a029e3"
|
|
522
|
+
: orgSlug;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function coerceStudioSessionScopeKey(
|
|
526
|
+
sessionScope: StudioWebchatSessionScope | undefined,
|
|
527
|
+
buildingSlug: string
|
|
528
|
+
): string {
|
|
529
|
+
if (!sessionScope?.key) {
|
|
530
|
+
return `building:${buildingSlug}`;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return sessionScope.key;
|
|
534
|
+
}
|
|
535
|
+
|
|
372
536
|
export interface Options {
|
|
373
|
-
building
|
|
374
|
-
organization
|
|
537
|
+
building?: string;
|
|
538
|
+
organization?: string;
|
|
539
|
+
studio?: StudioWebchatOptions;
|
|
375
540
|
avatarSrc?: string;
|
|
376
541
|
mini?: boolean;
|
|
377
542
|
launcherStyles?: StyleInfo;
|