@meetelise/chat 1.55.2 → 1.56.0
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 +38 -3
- package/dist/src/WebComponent/me-chat.d.ts +33 -0
- package/dist/src/WebComponent/pubnub-chat.d.ts +3 -0
- package/dist/src/WebComponent/pubnub-navigation.d.ts +17 -0
- package/dist/src/webchatNavigation.d.ts +38 -0
- package/package.json +1 -1
- package/public/dist/index.js +84 -46
- package/src/MyPubnub.ts +87 -5
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +5 -1
- package/src/WebComponent/me-chat.ts +158 -26
- package/src/WebComponent/pubnub-chat.ts +36 -10
- package/src/WebComponent/pubnub-navigation.ts +73 -0
- package/src/feeCalculatorLeaseTerm.test.ts +71 -0
- package/src/main/MEChat.ts +9 -1
- package/src/orgLevelNavigation.test.ts +625 -0
- package/src/services/fees/buildBuildingUnitsQuery.ts +4 -1
- package/src/services/fees/calculateQuote.ts +1 -1
- package/src/services/fees/fetchBuildingUnits.test.ts +20 -0
- package/src/webchatNavigation.test.ts +99 -0
- package/src/webchatNavigation.ts +108 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { css, html, LitElement, TemplateResult } from "lit";
|
|
2
|
+
import { customElement, property } from "lit/decorators.js";
|
|
3
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
4
|
+
import { SimpleNavigationChatMessage } from "../MyPubnub";
|
|
5
|
+
import { isMobile } from "../utils";
|
|
6
|
+
import { takeMeThere } from "../webchatNavigation";
|
|
7
|
+
import { InputStyles } from "./actions/InputStyles";
|
|
8
|
+
import { pubnubChatStyles } from "./pubnub-chat-styles";
|
|
9
|
+
|
|
10
|
+
/** The "Take me to {label}" button the agent sends after a reply. */
|
|
11
|
+
@customElement("pubnub-navigation")
|
|
12
|
+
export class PubnubNavigation extends LitElement {
|
|
13
|
+
static styles = [
|
|
14
|
+
InputStyles,
|
|
15
|
+
pubnubChatStyles,
|
|
16
|
+
css`
|
|
17
|
+
.navigation-button {
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
border: none;
|
|
20
|
+
border-radius: 8px;
|
|
21
|
+
padding: 8px 12px;
|
|
22
|
+
background: black;
|
|
23
|
+
color: white;
|
|
24
|
+
font-family: inherit;
|
|
25
|
+
text-align: left;
|
|
26
|
+
line-height: 1.4;
|
|
27
|
+
}
|
|
28
|
+
.navigation-button:hover {
|
|
29
|
+
opacity: 0.85;
|
|
30
|
+
}
|
|
31
|
+
.navigation-button:focus-visible {
|
|
32
|
+
outline: 2px solid #4d90fe;
|
|
33
|
+
outline-offset: 2px;
|
|
34
|
+
}
|
|
35
|
+
`,
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
@property({ attribute: false })
|
|
39
|
+
message: SimpleNavigationChatMessage | undefined;
|
|
40
|
+
|
|
41
|
+
@property({ attribute: false })
|
|
42
|
+
onMount: () => void = () => ({});
|
|
43
|
+
|
|
44
|
+
/** Overridable in tests; navigates the same tab by default. */
|
|
45
|
+
@property({ attribute: false })
|
|
46
|
+
navigate: (url: string) => void = (url) => window.location.assign(url);
|
|
47
|
+
|
|
48
|
+
updated(): void {
|
|
49
|
+
this.onMount();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
render(): TemplateResult {
|
|
53
|
+
if (!this.message) return html``;
|
|
54
|
+
const { navigation } = this.message;
|
|
55
|
+
return html`<button
|
|
56
|
+
type="button"
|
|
57
|
+
class=${classMap({
|
|
58
|
+
["navigation-button"]: true,
|
|
59
|
+
["webchat-font__desktop"]: !isMobile(),
|
|
60
|
+
["webchat-font__mobile"]: isMobile(),
|
|
61
|
+
})}
|
|
62
|
+
@click=${() => takeMeThere(navigation, this.navigate)}
|
|
63
|
+
>
|
|
64
|
+
Take me to ${navigation.label}
|
|
65
|
+
</button>`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
declare global {
|
|
70
|
+
interface HTMLElementTagNameMap {
|
|
71
|
+
"pubnub-navigation": PubnubNavigation;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { expect } from "@esm-bundle/chai";
|
|
2
|
+
import "../public/dist/index";
|
|
3
|
+
import type { FloorPlanSelector } from "./WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector";
|
|
4
|
+
|
|
5
|
+
describe("floor-plan-selector lease term", () => {
|
|
6
|
+
let selector: FloorPlanSelector;
|
|
7
|
+
let sentLeaseTerms: number[];
|
|
8
|
+
|
|
9
|
+
const getLeaseTermInput = (): HTMLInputElement => {
|
|
10
|
+
const input = selector.shadowRoot?.querySelector<HTMLInputElement>(
|
|
11
|
+
'input[type="number"]'
|
|
12
|
+
);
|
|
13
|
+
if (!input) throw new Error("Expected lease term input");
|
|
14
|
+
return input;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const enterLeaseTerm = async (value: string): Promise<void> => {
|
|
18
|
+
const input = getLeaseTermInput();
|
|
19
|
+
input.value = value;
|
|
20
|
+
input.dispatchEvent(new Event("input"));
|
|
21
|
+
await selector.updateComplete;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
beforeEach(async () => {
|
|
25
|
+
sentLeaseTerms = [];
|
|
26
|
+
selector = document.createElement(
|
|
27
|
+
"floor-plan-selector"
|
|
28
|
+
) as FloorPlanSelector;
|
|
29
|
+
selector.onLeaseTermChange = (leaseTerm) => sentLeaseTerms.push(leaseTerm);
|
|
30
|
+
document.body.appendChild(selector);
|
|
31
|
+
await selector.updateComplete;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
selector.remove();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("starts on the default lease term", () => {
|
|
39
|
+
expect(getLeaseTermInput().value).to.equal("12");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("sends each lease term the prospect types", async () => {
|
|
43
|
+
await enterLeaseTerm("1");
|
|
44
|
+
await enterLeaseTerm("18");
|
|
45
|
+
|
|
46
|
+
expect(sentLeaseTerms).to.deep.equal([1, 18]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("keeps the box empty without sending anything while it is retyped", async () => {
|
|
50
|
+
await enterLeaseTerm("");
|
|
51
|
+
// A rerender, for example from new units arriving, must not refill the box.
|
|
52
|
+
selector.requestUpdate();
|
|
53
|
+
await selector.updateComplete;
|
|
54
|
+
|
|
55
|
+
expect(getLeaseTermInput().value).to.equal("");
|
|
56
|
+
expect(sentLeaseTerms).to.deep.equal([]);
|
|
57
|
+
|
|
58
|
+
await enterLeaseTerm("1");
|
|
59
|
+
await enterLeaseTerm("18");
|
|
60
|
+
|
|
61
|
+
expect(getLeaseTermInput().value).to.equal("18");
|
|
62
|
+
expect(sentLeaseTerms).to.deep.equal([1, 18]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("ignores lease terms below one month", async () => {
|
|
66
|
+
await enterLeaseTerm("0");
|
|
67
|
+
await enterLeaseTerm("-6");
|
|
68
|
+
|
|
69
|
+
expect(sentLeaseTerms).to.deep.equal([]);
|
|
70
|
+
});
|
|
71
|
+
});
|
package/src/main/MEChat.ts
CHANGED
|
@@ -66,7 +66,11 @@ export interface StudioWebchatContext {
|
|
|
66
66
|
|
|
67
67
|
export interface StudioWebchatClearContext {
|
|
68
68
|
source?: "elise_studio";
|
|
69
|
-
reason?:
|
|
69
|
+
reason?:
|
|
70
|
+
| "no_property_for_route"
|
|
71
|
+
| "webchat_disabled"
|
|
72
|
+
| "ambiguous_route"
|
|
73
|
+
| string;
|
|
70
74
|
preserveCache?: boolean;
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -209,6 +213,10 @@ export default class MEChat {
|
|
|
209
213
|
// Centralized webchat is org-anchored: config comes from the org, not a
|
|
210
214
|
// per-building slug or site resolution.
|
|
211
215
|
meChatElement.setAttribute("centralConvo", "true");
|
|
216
|
+
if (opts.building) {
|
|
217
|
+
// Page context only: sent with visitor messages as declaredBuildingId.
|
|
218
|
+
meChatElement.setAttribute("declaredBuildingSlug", opts.building);
|
|
219
|
+
}
|
|
212
220
|
} else {
|
|
213
221
|
this.handleBuildingslug(
|
|
214
222
|
meChatElement as MEChatLitElement,
|