@envive-ai/react-widgets-v3 0.3.67 → 0.3.69
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/CXIntegration/implementations/useGladlyUnifiedCXButton.cjs +112 -36
- package/dist/CXIntegration/implementations/useGladlyUnifiedCXButton.js +112 -36
- package/dist/debug/reportIssue.cjs +15 -3
- package/dist/debug/reportIssue.js +16 -4
- package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +4 -1
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.ts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +4 -1
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +2 -0
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.js +2 -0
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.cts +2 -2
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.ts +2 -2
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.ts +2 -2
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
- package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
- package/package.json +1 -1
- package/src/CXIntegration/implementations/__tests__/useGladlyUnifiedCXButton.test.ts +233 -0
- package/src/CXIntegration/implementations/useGladlyUnifiedCXButton.ts +173 -40
- package/src/debug/reportIssue.tsx +44 -4
- package/src/widgets/FloatingChatWidget/FloatingChatWidget.tsx +14 -1
- package/src/widgets/FloatingChatWidget/__tests__/FloatingChatWidget.cxClose.test.tsx +138 -0
- package/src/widgets/ProductCardWidget/ProductCardWidget.tsx +2 -0
- package/src/widgets/ProductCardWidget/__tests__/ProductCardWidget.test.tsx +24 -1
|
@@ -6,9 +6,12 @@ let __envive_ai_react_hooks_hooks_ElementObserver = require("@envive-ai/react-ho
|
|
|
6
6
|
|
|
7
7
|
//#region src/CXIntegration/implementations/useGladlyUnifiedCXButton.ts
|
|
8
8
|
const GLADLY_CONTAINER_ID = "gladlyChat_container";
|
|
9
|
-
const GLADLY_BUTTON_SELECTOR = "
|
|
10
|
-
const
|
|
11
|
-
const
|
|
9
|
+
const GLADLY_BUTTON_SELECTOR = "#custom-gladly-pill";
|
|
10
|
+
const HIDE_STYLE_ID = "envive-gladly-pill-hide";
|
|
11
|
+
const ENVIVE_BUTTON_HIDE_STYLE_ID = "envive-floating-button-hide";
|
|
12
|
+
const GLADLY_PANEL_OPEN_SIZE_THRESHOLD = 200;
|
|
13
|
+
const SHADOW_ATTACH_RETRY_MS = 300;
|
|
14
|
+
const SHADOW_POLL_MS = 250;
|
|
12
15
|
const getGladly = () => window.Gladly;
|
|
13
16
|
const forceHideContainer = (node) => {
|
|
14
17
|
node?.style.setProperty("display", "none", "important");
|
|
@@ -16,11 +19,76 @@ const forceHideContainer = (node) => {
|
|
|
16
19
|
const restoreContainer = (node) => {
|
|
17
20
|
node?.style.removeProperty("display");
|
|
18
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Hide the merchant's floating pill with an injected CSS rule instead of
|
|
24
|
+
* toggling `display` on a specific element reference. Gladly can re-create
|
|
25
|
+
* the pill node after our reference is taken (re-renders, SDK re-init), so a
|
|
26
|
+
* rule keyed by selector keeps applying no matter how many times the node is
|
|
27
|
+
* swapped out, whereas a stale/detached node reference would silently no-op
|
|
28
|
+
* and let the merchant pill reappear next to ours.
|
|
29
|
+
*/
|
|
30
|
+
const hideMerchantButton = () => {
|
|
31
|
+
if (document.getElementById(HIDE_STYLE_ID)) return;
|
|
32
|
+
const style = document.createElement("style");
|
|
33
|
+
style.id = HIDE_STYLE_ID;
|
|
34
|
+
style.textContent = `${GLADLY_BUTTON_SELECTOR} { display: none !important; }`;
|
|
35
|
+
document.head.appendChild(style);
|
|
36
|
+
};
|
|
37
|
+
const showMerchantButton = () => {
|
|
38
|
+
document.getElementById(HIDE_STYLE_ID)?.remove();
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Hide/show the Envive floating button via an injected CSS rule rather than
|
|
42
|
+
* `enviveFloatingButton.hide()/.show()`, which toggles inline `display` on a
|
|
43
|
+
* cached node reference. `FloatingChatWidget` unmounts and remounts that
|
|
44
|
+
* button in response to `isCXOpen` (see `buttonShouldRender`), so the cached
|
|
45
|
+
* reference can point at a node React has already removed — the toggle then
|
|
46
|
+
* silently no-ops and the button stays invisible after Gladly closes. A rule
|
|
47
|
+
* keyed by id keeps applying across remounts instead.
|
|
48
|
+
*/
|
|
49
|
+
const hideEnviveButton = () => {
|
|
50
|
+
if (document.getElementById(ENVIVE_BUTTON_HIDE_STYLE_ID)) return;
|
|
51
|
+
const style = document.createElement("style");
|
|
52
|
+
style.id = ENVIVE_BUTTON_HIDE_STYLE_ID;
|
|
53
|
+
style.textContent = `#${require_constants.FLOATING_BUTTON_ID} { display: none !important; }`;
|
|
54
|
+
document.head.appendChild(style);
|
|
55
|
+
};
|
|
56
|
+
const showEnviveButton = () => {
|
|
57
|
+
document.getElementById(ENVIVE_BUTTON_HIDE_STYLE_ID)?.remove();
|
|
58
|
+
};
|
|
59
|
+
const isPanelOpenInShadowRoot = (shadowRoot) => Array.from(shadowRoot.querySelectorAll("*")).some((el) => {
|
|
60
|
+
const rect = el.getBoundingClientRect();
|
|
61
|
+
return rect.width > GLADLY_PANEL_OPEN_SIZE_THRESHOLD && rect.height > GLADLY_PANEL_OPEN_SIZE_THRESHOLD;
|
|
62
|
+
});
|
|
19
63
|
const useGladlyUnifiedCXButton = ({ onSwitchToAgent, onCXClose, suppressMerchantButton }) => {
|
|
20
64
|
const gladlyContainer = (0, __envive_ai_react_hooks_hooks_ElementObserver.useElementObserver)(__envive_ai_react_hooks_application_utils.SelectorFactory.id(GLADLY_CONTAINER_ID));
|
|
21
|
-
const enviveFloatingButton = (0, __envive_ai_react_hooks_hooks_ElementObserver.useElementObserver)(__envive_ai_react_hooks_application_utils.SelectorFactory.id(require_constants.FLOATING_BUTTON_ID));
|
|
22
65
|
const wasOpenRef = (0, react.useRef)(false);
|
|
23
|
-
const
|
|
66
|
+
const hasConfirmedOpenRef = (0, react.useRef)(false);
|
|
67
|
+
const isSwitchEnabled = () => {
|
|
68
|
+
const gladly = getGladly();
|
|
69
|
+
const hasGladlySdk = !!gladly && typeof gladly.show === "function";
|
|
70
|
+
const hasGladlyButton = !!document.querySelector(GLADLY_BUTTON_SELECTOR);
|
|
71
|
+
const hasGladlyContainer = !!document.getElementById(GLADLY_CONTAINER_ID);
|
|
72
|
+
return hasGladlySdk || hasGladlyButton || hasGladlyContainer;
|
|
73
|
+
};
|
|
74
|
+
const handleOpen = () => {
|
|
75
|
+
wasOpenRef.current = true;
|
|
76
|
+
hideEnviveButton();
|
|
77
|
+
};
|
|
78
|
+
const handleClose = () => {
|
|
79
|
+
wasOpenRef.current = false;
|
|
80
|
+
hasConfirmedOpenRef.current = false;
|
|
81
|
+
onCXClose?.();
|
|
82
|
+
if (suppressMerchantButton) forceHideContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
83
|
+
showEnviveButton();
|
|
84
|
+
};
|
|
85
|
+
const checkShadowOpenStateRef = (0, react.useRef)(() => {});
|
|
86
|
+
checkShadowOpenStateRef.current = (shadowRoot) => {
|
|
87
|
+
if (isPanelOpenInShadowRoot(shadowRoot)) {
|
|
88
|
+
hasConfirmedOpenRef.current = true;
|
|
89
|
+
if (!wasOpenRef.current) handleOpen();
|
|
90
|
+
} else if (wasOpenRef.current && hasConfirmedOpenRef.current) handleClose();
|
|
91
|
+
};
|
|
24
92
|
gladlyContainer.onAdd((el) => {
|
|
25
93
|
if (suppressMerchantButton && el && !wasOpenRef.current) forceHideContainer(el);
|
|
26
94
|
});
|
|
@@ -28,45 +96,53 @@ const useGladlyUnifiedCXButton = ({ onSwitchToAgent, onCXClose, suppressMerchant
|
|
|
28
96
|
if (!suppressMerchantButton || !el || wasOpenRef.current) return;
|
|
29
97
|
if (el.style.display !== "none") forceHideContainer(el);
|
|
30
98
|
});
|
|
99
|
+
gladlyContainer.onRemove(() => {
|
|
100
|
+
if (wasOpenRef.current) handleClose();
|
|
101
|
+
});
|
|
31
102
|
(0, react.useEffect)(() => {
|
|
32
|
-
if (
|
|
103
|
+
if (suppressMerchantButton) hideMerchantButton();
|
|
104
|
+
else {
|
|
105
|
+
showMerchantButton();
|
|
106
|
+
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
107
|
+
}
|
|
108
|
+
return () => {
|
|
109
|
+
showMerchantButton();
|
|
110
|
+
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
111
|
+
};
|
|
33
112
|
}, [suppressMerchantButton]);
|
|
34
113
|
(0, react.useEffect)(() => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return;
|
|
114
|
+
let shadowObserver = null;
|
|
115
|
+
let retryIntervalId;
|
|
116
|
+
let pollIntervalId;
|
|
117
|
+
const attach = () => {
|
|
118
|
+
const shadowRoot = document.getElementById(GLADLY_CONTAINER_ID)?.shadowRoot;
|
|
119
|
+
if (!shadowRoot || shadowObserver) return;
|
|
120
|
+
shadowObserver = new MutationObserver(() => checkShadowOpenStateRef.current(shadowRoot));
|
|
121
|
+
shadowObserver.observe(shadowRoot, {
|
|
122
|
+
childList: true,
|
|
123
|
+
subtree: true,
|
|
124
|
+
attributes: true
|
|
125
|
+
});
|
|
126
|
+
checkShadowOpenStateRef.current(shadowRoot);
|
|
127
|
+
pollIntervalId = window.setInterval(() => checkShadowOpenStateRef.current(shadowRoot), SHADOW_POLL_MS);
|
|
128
|
+
if (retryIntervalId) {
|
|
129
|
+
window.clearInterval(retryIntervalId);
|
|
130
|
+
retryIntervalId = void 0;
|
|
53
131
|
}
|
|
54
|
-
const rect = node.getBoundingClientRect();
|
|
55
|
-
const isOpen = rect.width > GLADLY_OPEN_SIZE_THRESHOLD && rect.height > GLADLY_OPEN_SIZE_THRESHOLD;
|
|
56
|
-
if (isOpen && !wasOpenRef.current) handleOpen();
|
|
57
|
-
else if (!isOpen && wasOpenRef.current) handleClose();
|
|
58
132
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
133
|
+
retryIntervalId = window.setInterval(attach, SHADOW_ATTACH_RETRY_MS);
|
|
134
|
+
attach();
|
|
135
|
+
return () => {
|
|
136
|
+
shadowObserver?.disconnect();
|
|
137
|
+
if (retryIntervalId) window.clearInterval(retryIntervalId);
|
|
138
|
+
if (pollIntervalId) window.clearInterval(pollIntervalId);
|
|
139
|
+
};
|
|
140
|
+
}, []);
|
|
66
141
|
const toggle = () => {
|
|
67
142
|
onSwitchToAgent();
|
|
68
|
-
|
|
143
|
+
hideEnviveButton();
|
|
69
144
|
wasOpenRef.current = true;
|
|
145
|
+
hasConfirmedOpenRef.current = false;
|
|
70
146
|
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
71
147
|
const gladly = getGladly();
|
|
72
148
|
if (gladly && typeof gladly.show === "function") {
|
|
@@ -5,9 +5,12 @@ import { useElementObserver } from "@envive-ai/react-hooks/hooks/ElementObserver
|
|
|
5
5
|
|
|
6
6
|
//#region src/CXIntegration/implementations/useGladlyUnifiedCXButton.ts
|
|
7
7
|
const GLADLY_CONTAINER_ID = "gladlyChat_container";
|
|
8
|
-
const GLADLY_BUTTON_SELECTOR = "
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const GLADLY_BUTTON_SELECTOR = "#custom-gladly-pill";
|
|
9
|
+
const HIDE_STYLE_ID = "envive-gladly-pill-hide";
|
|
10
|
+
const ENVIVE_BUTTON_HIDE_STYLE_ID = "envive-floating-button-hide";
|
|
11
|
+
const GLADLY_PANEL_OPEN_SIZE_THRESHOLD = 200;
|
|
12
|
+
const SHADOW_ATTACH_RETRY_MS = 300;
|
|
13
|
+
const SHADOW_POLL_MS = 250;
|
|
11
14
|
const getGladly = () => window.Gladly;
|
|
12
15
|
const forceHideContainer = (node) => {
|
|
13
16
|
node?.style.setProperty("display", "none", "important");
|
|
@@ -15,11 +18,76 @@ const forceHideContainer = (node) => {
|
|
|
15
18
|
const restoreContainer = (node) => {
|
|
16
19
|
node?.style.removeProperty("display");
|
|
17
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Hide the merchant's floating pill with an injected CSS rule instead of
|
|
23
|
+
* toggling `display` on a specific element reference. Gladly can re-create
|
|
24
|
+
* the pill node after our reference is taken (re-renders, SDK re-init), so a
|
|
25
|
+
* rule keyed by selector keeps applying no matter how many times the node is
|
|
26
|
+
* swapped out, whereas a stale/detached node reference would silently no-op
|
|
27
|
+
* and let the merchant pill reappear next to ours.
|
|
28
|
+
*/
|
|
29
|
+
const hideMerchantButton = () => {
|
|
30
|
+
if (document.getElementById(HIDE_STYLE_ID)) return;
|
|
31
|
+
const style = document.createElement("style");
|
|
32
|
+
style.id = HIDE_STYLE_ID;
|
|
33
|
+
style.textContent = `${GLADLY_BUTTON_SELECTOR} { display: none !important; }`;
|
|
34
|
+
document.head.appendChild(style);
|
|
35
|
+
};
|
|
36
|
+
const showMerchantButton = () => {
|
|
37
|
+
document.getElementById(HIDE_STYLE_ID)?.remove();
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Hide/show the Envive floating button via an injected CSS rule rather than
|
|
41
|
+
* `enviveFloatingButton.hide()/.show()`, which toggles inline `display` on a
|
|
42
|
+
* cached node reference. `FloatingChatWidget` unmounts and remounts that
|
|
43
|
+
* button in response to `isCXOpen` (see `buttonShouldRender`), so the cached
|
|
44
|
+
* reference can point at a node React has already removed — the toggle then
|
|
45
|
+
* silently no-ops and the button stays invisible after Gladly closes. A rule
|
|
46
|
+
* keyed by id keeps applying across remounts instead.
|
|
47
|
+
*/
|
|
48
|
+
const hideEnviveButton = () => {
|
|
49
|
+
if (document.getElementById(ENVIVE_BUTTON_HIDE_STYLE_ID)) return;
|
|
50
|
+
const style = document.createElement("style");
|
|
51
|
+
style.id = ENVIVE_BUTTON_HIDE_STYLE_ID;
|
|
52
|
+
style.textContent = `#${FLOATING_BUTTON_ID} { display: none !important; }`;
|
|
53
|
+
document.head.appendChild(style);
|
|
54
|
+
};
|
|
55
|
+
const showEnviveButton = () => {
|
|
56
|
+
document.getElementById(ENVIVE_BUTTON_HIDE_STYLE_ID)?.remove();
|
|
57
|
+
};
|
|
58
|
+
const isPanelOpenInShadowRoot = (shadowRoot) => Array.from(shadowRoot.querySelectorAll("*")).some((el) => {
|
|
59
|
+
const rect = el.getBoundingClientRect();
|
|
60
|
+
return rect.width > GLADLY_PANEL_OPEN_SIZE_THRESHOLD && rect.height > GLADLY_PANEL_OPEN_SIZE_THRESHOLD;
|
|
61
|
+
});
|
|
18
62
|
const useGladlyUnifiedCXButton = ({ onSwitchToAgent, onCXClose, suppressMerchantButton }) => {
|
|
19
63
|
const gladlyContainer = useElementObserver(SelectorFactory.id(GLADLY_CONTAINER_ID));
|
|
20
|
-
const enviveFloatingButton = useElementObserver(SelectorFactory.id(FLOATING_BUTTON_ID));
|
|
21
64
|
const wasOpenRef = useRef(false);
|
|
22
|
-
const
|
|
65
|
+
const hasConfirmedOpenRef = useRef(false);
|
|
66
|
+
const isSwitchEnabled = () => {
|
|
67
|
+
const gladly = getGladly();
|
|
68
|
+
const hasGladlySdk = !!gladly && typeof gladly.show === "function";
|
|
69
|
+
const hasGladlyButton = !!document.querySelector(GLADLY_BUTTON_SELECTOR);
|
|
70
|
+
const hasGladlyContainer = !!document.getElementById(GLADLY_CONTAINER_ID);
|
|
71
|
+
return hasGladlySdk || hasGladlyButton || hasGladlyContainer;
|
|
72
|
+
};
|
|
73
|
+
const handleOpen = () => {
|
|
74
|
+
wasOpenRef.current = true;
|
|
75
|
+
hideEnviveButton();
|
|
76
|
+
};
|
|
77
|
+
const handleClose = () => {
|
|
78
|
+
wasOpenRef.current = false;
|
|
79
|
+
hasConfirmedOpenRef.current = false;
|
|
80
|
+
onCXClose?.();
|
|
81
|
+
if (suppressMerchantButton) forceHideContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
82
|
+
showEnviveButton();
|
|
83
|
+
};
|
|
84
|
+
const checkShadowOpenStateRef = useRef(() => {});
|
|
85
|
+
checkShadowOpenStateRef.current = (shadowRoot) => {
|
|
86
|
+
if (isPanelOpenInShadowRoot(shadowRoot)) {
|
|
87
|
+
hasConfirmedOpenRef.current = true;
|
|
88
|
+
if (!wasOpenRef.current) handleOpen();
|
|
89
|
+
} else if (wasOpenRef.current && hasConfirmedOpenRef.current) handleClose();
|
|
90
|
+
};
|
|
23
91
|
gladlyContainer.onAdd((el) => {
|
|
24
92
|
if (suppressMerchantButton && el && !wasOpenRef.current) forceHideContainer(el);
|
|
25
93
|
});
|
|
@@ -27,45 +95,53 @@ const useGladlyUnifiedCXButton = ({ onSwitchToAgent, onCXClose, suppressMerchant
|
|
|
27
95
|
if (!suppressMerchantButton || !el || wasOpenRef.current) return;
|
|
28
96
|
if (el.style.display !== "none") forceHideContainer(el);
|
|
29
97
|
});
|
|
98
|
+
gladlyContainer.onRemove(() => {
|
|
99
|
+
if (wasOpenRef.current) handleClose();
|
|
100
|
+
});
|
|
30
101
|
useEffect(() => {
|
|
31
|
-
if (
|
|
102
|
+
if (suppressMerchantButton) hideMerchantButton();
|
|
103
|
+
else {
|
|
104
|
+
showMerchantButton();
|
|
105
|
+
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
106
|
+
}
|
|
107
|
+
return () => {
|
|
108
|
+
showMerchantButton();
|
|
109
|
+
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
110
|
+
};
|
|
32
111
|
}, [suppressMerchantButton]);
|
|
33
112
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return;
|
|
113
|
+
let shadowObserver = null;
|
|
114
|
+
let retryIntervalId;
|
|
115
|
+
let pollIntervalId;
|
|
116
|
+
const attach = () => {
|
|
117
|
+
const shadowRoot = document.getElementById(GLADLY_CONTAINER_ID)?.shadowRoot;
|
|
118
|
+
if (!shadowRoot || shadowObserver) return;
|
|
119
|
+
shadowObserver = new MutationObserver(() => checkShadowOpenStateRef.current(shadowRoot));
|
|
120
|
+
shadowObserver.observe(shadowRoot, {
|
|
121
|
+
childList: true,
|
|
122
|
+
subtree: true,
|
|
123
|
+
attributes: true
|
|
124
|
+
});
|
|
125
|
+
checkShadowOpenStateRef.current(shadowRoot);
|
|
126
|
+
pollIntervalId = window.setInterval(() => checkShadowOpenStateRef.current(shadowRoot), SHADOW_POLL_MS);
|
|
127
|
+
if (retryIntervalId) {
|
|
128
|
+
window.clearInterval(retryIntervalId);
|
|
129
|
+
retryIntervalId = void 0;
|
|
52
130
|
}
|
|
53
|
-
const rect = node.getBoundingClientRect();
|
|
54
|
-
const isOpen = rect.width > GLADLY_OPEN_SIZE_THRESHOLD && rect.height > GLADLY_OPEN_SIZE_THRESHOLD;
|
|
55
|
-
if (isOpen && !wasOpenRef.current) handleOpen();
|
|
56
|
-
else if (!isOpen && wasOpenRef.current) handleClose();
|
|
57
131
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
132
|
+
retryIntervalId = window.setInterval(attach, SHADOW_ATTACH_RETRY_MS);
|
|
133
|
+
attach();
|
|
134
|
+
return () => {
|
|
135
|
+
shadowObserver?.disconnect();
|
|
136
|
+
if (retryIntervalId) window.clearInterval(retryIntervalId);
|
|
137
|
+
if (pollIntervalId) window.clearInterval(pollIntervalId);
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
65
140
|
const toggle = () => {
|
|
66
141
|
onSwitchToAgent();
|
|
67
|
-
|
|
142
|
+
hideEnviveButton();
|
|
68
143
|
wasOpenRef.current = true;
|
|
144
|
+
hasConfirmedOpenRef.current = false;
|
|
69
145
|
restoreContainer(document.getElementById(GLADLY_CONTAINER_ID));
|
|
70
146
|
const gladly = getGladly();
|
|
71
147
|
if (gladly && typeof gladly.show === "function") {
|
|
@@ -11,6 +11,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
11
11
|
let __envive_ai_react_hooks_atoms_chat = require("@envive-ai/react-hooks/atoms/chat");
|
|
12
12
|
let jotai = require("jotai");
|
|
13
13
|
let __envive_ai_react_hooks_atoms_app = require("@envive-ai/react-hooks/atoms/app");
|
|
14
|
+
let react_dom = require("react-dom");
|
|
14
15
|
let classnames = require("classnames");
|
|
15
16
|
classnames = require_rolldown_runtime.__toESM(classnames);
|
|
16
17
|
let __envive_ai_react_hooks_application_commerce_api = require("@envive-ai/react-hooks/application/commerce-api");
|
|
@@ -333,10 +334,16 @@ const ReportFooter = ({ isReporting, errorMessage, reportedByIsInvalid, isReason
|
|
|
333
334
|
})
|
|
334
335
|
});
|
|
335
336
|
};
|
|
336
|
-
const
|
|
337
|
+
const getPortalTarget = (node) => {
|
|
338
|
+
const root = node?.getRootNode();
|
|
339
|
+
if (root instanceof ShadowRoot) return root;
|
|
340
|
+
if (root instanceof Document) return root.body;
|
|
341
|
+
return null;
|
|
342
|
+
};
|
|
343
|
+
const Drawer = ({ isOpen, onClose, children, width = "md:envive-tw-w-[80%] lg:envive-tw-w-[67%]", anchorNode }) => {
|
|
337
344
|
if (!isOpen) return null;
|
|
338
|
-
|
|
339
|
-
className: "envive-tw-fixed envive-tw-right-[0] envive-tw-top-[0] envive-tw-z-[
|
|
345
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
346
|
+
className: "envive-tw-fixed envive-tw-right-[0] envive-tw-top-[0] envive-tw-z-[2147483647] envive-tw-flex envive-tw-w-full envive-tw-flex-row envive-tw-justify-end",
|
|
340
347
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
341
348
|
className: "envive-tw-bg envive-tw-flex-grow envive-tw-bg-black/40",
|
|
342
349
|
onClick: onClose
|
|
@@ -348,8 +355,11 @@ const Drawer = ({ isOpen, onClose, children, width = "md:envive-tw-w-[80%] lg:en
|
|
|
348
355
|
})
|
|
349
356
|
})]
|
|
350
357
|
});
|
|
358
|
+
const portalTarget = getPortalTarget(anchorNode);
|
|
359
|
+
return portalTarget ? (0, react_dom.createPortal)(content, portalTarget) : content;
|
|
351
360
|
};
|
|
352
361
|
const ReportIssue = () => {
|
|
362
|
+
const anchorRef = (0, react.useRef)(null);
|
|
353
363
|
const { messages, suggestions, userEvents } = (0, jotai.useAtomValue)(__envive_ai_react_hooks_atoms_chat.chatAtom);
|
|
354
364
|
const lastMessages = (0, jotai.useAtomValue)(__envive_ai_react_hooks_atoms_chat.lastAssistantMessageAtom);
|
|
355
365
|
const [lastMessagesText, setLastMessagesText] = (0, react.useState)("");
|
|
@@ -474,6 +484,7 @@ const ReportIssue = () => {
|
|
|
474
484
|
}));
|
|
475
485
|
}, []);
|
|
476
486
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
487
|
+
ref: anchorRef,
|
|
477
488
|
className: "envive-tw-mx-[16px] envive-tw-block envive-tw-h-[24px] envive-tw-w-full",
|
|
478
489
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
479
490
|
type: "button",
|
|
@@ -497,6 +508,7 @@ const ReportIssue = () => {
|
|
|
497
508
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Drawer, {
|
|
498
509
|
isOpen,
|
|
499
510
|
onClose,
|
|
511
|
+
anchorNode: anchorRef.current,
|
|
500
512
|
children: [
|
|
501
513
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReportHeader, { onClose }),
|
|
502
514
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IconCloseVariant_default } from "../packages/icons/dist/IconCloseVariant.js";
|
|
2
2
|
import { GenericSelect } from "./GenericSelect.js";
|
|
3
3
|
import chatEmbed_default from "./chatEmbed.js";
|
|
4
|
-
import { useCallback, useEffect, useState } from "react";
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
5
|
import Logger from "@envive-ai/react-hooks/application/logging";
|
|
6
6
|
import { MessageType } from "@envive-ai/react-hooks/application/models";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -9,6 +9,7 @@ import { chatAtom, lastAssistantMessageAtom } from "@envive-ai/react-hooks/atoms
|
|
|
9
9
|
import { useAtomValue } from "jotai";
|
|
10
10
|
import { userIdAtom } from "@envive-ai/react-hooks/atoms/app";
|
|
11
11
|
import { ReportSessionRequestReportPriorityEnum, ReportSessionRequestReportTypeEnum } from "@spiffy-ai/commerce-api-client";
|
|
12
|
+
import { createPortal } from "react-dom";
|
|
12
13
|
import classNames from "classnames";
|
|
13
14
|
import CommerceApiClient from "@envive-ai/react-hooks/application/commerce-api";
|
|
14
15
|
import { orgShortNameAtom } from "@envive-ai/react-hooks/atoms/envive/enviveConfig";
|
|
@@ -328,10 +329,16 @@ const ReportFooter = ({ isReporting, errorMessage, reportedByIsInvalid, isReason
|
|
|
328
329
|
})
|
|
329
330
|
});
|
|
330
331
|
};
|
|
331
|
-
const
|
|
332
|
+
const getPortalTarget = (node) => {
|
|
333
|
+
const root = node?.getRootNode();
|
|
334
|
+
if (root instanceof ShadowRoot) return root;
|
|
335
|
+
if (root instanceof Document) return root.body;
|
|
336
|
+
return null;
|
|
337
|
+
};
|
|
338
|
+
const Drawer = ({ isOpen, onClose, children, width = "md:envive-tw-w-[80%] lg:envive-tw-w-[67%]", anchorNode }) => {
|
|
332
339
|
if (!isOpen) return null;
|
|
333
|
-
|
|
334
|
-
className: "envive-tw-fixed envive-tw-right-[0] envive-tw-top-[0] envive-tw-z-[
|
|
340
|
+
const content = /* @__PURE__ */ jsxs("div", {
|
|
341
|
+
className: "envive-tw-fixed envive-tw-right-[0] envive-tw-top-[0] envive-tw-z-[2147483647] envive-tw-flex envive-tw-w-full envive-tw-flex-row envive-tw-justify-end",
|
|
335
342
|
children: [/* @__PURE__ */ jsx("div", {
|
|
336
343
|
className: "envive-tw-bg envive-tw-flex-grow envive-tw-bg-black/40",
|
|
337
344
|
onClick: onClose
|
|
@@ -343,8 +350,11 @@ const Drawer = ({ isOpen, onClose, children, width = "md:envive-tw-w-[80%] lg:en
|
|
|
343
350
|
})
|
|
344
351
|
})]
|
|
345
352
|
});
|
|
353
|
+
const portalTarget = getPortalTarget(anchorNode);
|
|
354
|
+
return portalTarget ? createPortal(content, portalTarget) : content;
|
|
346
355
|
};
|
|
347
356
|
const ReportIssue = () => {
|
|
357
|
+
const anchorRef = useRef(null);
|
|
348
358
|
const { messages, suggestions, userEvents } = useAtomValue(chatAtom);
|
|
349
359
|
const lastMessages = useAtomValue(lastAssistantMessageAtom);
|
|
350
360
|
const [lastMessagesText, setLastMessagesText] = useState("");
|
|
@@ -469,6 +479,7 @@ const ReportIssue = () => {
|
|
|
469
479
|
}));
|
|
470
480
|
}, []);
|
|
471
481
|
return /* @__PURE__ */ jsxs("div", {
|
|
482
|
+
ref: anchorRef,
|
|
472
483
|
className: "envive-tw-mx-[16px] envive-tw-block envive-tw-h-[24px] envive-tw-w-full",
|
|
473
484
|
children: [/* @__PURE__ */ jsx("button", {
|
|
474
485
|
type: "button",
|
|
@@ -492,6 +503,7 @@ const ReportIssue = () => {
|
|
|
492
503
|
}), /* @__PURE__ */ jsxs(Drawer, {
|
|
493
504
|
isOpen,
|
|
494
505
|
onClose,
|
|
506
|
+
anchorNode: anchorRef.current,
|
|
495
507
|
children: [
|
|
496
508
|
/* @__PURE__ */ jsx(ReportHeader, { onClose }),
|
|
497
509
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps, WithBaseWidgetOptions } from "./types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime13 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/hocs/withBaseWidget/withBaseWidget.d.ts
|
|
5
5
|
declare function withBaseWidget<P extends BaseWidgetProps>(Widget: React.ComponentType<P>, options?: WithBaseWidgetOptions): {
|
|
6
|
-
(props: P):
|
|
6
|
+
(props: P): react_jsx_runtime13.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps, WithBaseWidgetOptions } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime16 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/hocs/withBaseWidget/withBaseWidget.d.ts
|
|
5
5
|
declare function withBaseWidget<P extends BaseWidgetProps>(Widget: React.ComponentType<P>, options?: WithBaseWidgetOptions): {
|
|
6
|
-
(props: P):
|
|
6
|
+
(props: P): react_jsx_runtime16.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
//#endregion
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region ../widgets/dist/SearchResults/SearchResultsWidget.d.ts
|
|
4
4
|
//#region src/SearchResults/SearchResultsWidget.d.ts
|
|
5
|
-
declare const SearchResultsWidget: () =>
|
|
5
|
+
declare const SearchResultsWidget: () => react_jsx_runtime1.JSX.Element;
|
|
6
6
|
//#endregion
|
|
7
7
|
|
|
8
8
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps } from "../../hocs/withBaseWidget/types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime11 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts
|
|
5
5
|
declare const ChatPreviewComparisonWidgetWithBaseWidget: {
|
|
6
|
-
(props: BaseWidgetProps):
|
|
6
|
+
(props: BaseWidgetProps): react_jsx_runtime11.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
interface ChatPreviewComparisonWidgetProps {
|
|
@@ -12,7 +12,7 @@ interface ChatPreviewComparisonWidgetProps {
|
|
|
12
12
|
declare const ChatPreviewComparisonWidget: {
|
|
13
13
|
({
|
|
14
14
|
widgetConfigId
|
|
15
|
-
}: ChatPreviewComparisonWidgetProps):
|
|
15
|
+
}: ChatPreviewComparisonWidgetProps): react_jsx_runtime11.JSX.Element;
|
|
16
16
|
displayName: string;
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps } from "../../hocs/withBaseWidget/types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime5 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts
|
|
5
5
|
declare const ChatPreviewLoadingWidgetWithBaseWidget: {
|
|
6
|
-
(props: BaseWidgetProps):
|
|
6
|
+
(props: BaseWidgetProps): react_jsx_runtime5.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
interface ChatPreviewLoadingWidgetProps {
|
|
@@ -11,6 +11,6 @@ interface ChatPreviewLoadingWidgetProps {
|
|
|
11
11
|
}
|
|
12
12
|
declare const ChatPreviewLoadingWidget: ({
|
|
13
13
|
widgetConfigId
|
|
14
|
-
}: ChatPreviewLoadingWidgetProps) =>
|
|
14
|
+
}: ChatPreviewLoadingWidgetProps) => react_jsx_runtime5.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { ChatPreviewLoadingWidget, ChatPreviewLoadingWidgetProps, ChatPreviewLoadingWidgetWithBaseWidget };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps } from "../../hocs/withBaseWidget/types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime14 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts
|
|
5
5
|
declare const ChatPreviewLoadingWidgetWithBaseWidget: {
|
|
6
|
-
(props: BaseWidgetProps):
|
|
6
|
+
(props: BaseWidgetProps): react_jsx_runtime14.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
interface ChatPreviewLoadingWidgetProps {
|
|
@@ -11,6 +11,6 @@ interface ChatPreviewLoadingWidgetProps {
|
|
|
11
11
|
}
|
|
12
12
|
declare const ChatPreviewLoadingWidget: ({
|
|
13
13
|
widgetConfigId
|
|
14
|
-
}: ChatPreviewLoadingWidgetProps) =>
|
|
14
|
+
}: ChatPreviewLoadingWidgetProps) => react_jsx_runtime14.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { ChatPreviewLoadingWidget, ChatPreviewLoadingWidgetProps, ChatPreviewLoadingWidgetWithBaseWidget };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps } from "../../hocs/withBaseWidget/types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts
|
|
5
5
|
declare const ChatPreviewWidgetWithBaseWidget: {
|
|
6
|
-
(props: BaseWidgetProps):
|
|
6
|
+
(props: BaseWidgetProps): react_jsx_runtime9.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
interface ChatPreviewWidgetProps {
|
|
@@ -12,7 +12,7 @@ interface ChatPreviewWidgetProps {
|
|
|
12
12
|
declare const ChatPreviewWidget: {
|
|
13
13
|
({
|
|
14
14
|
widgetConfigId
|
|
15
|
-
}: ChatPreviewWidgetProps):
|
|
15
|
+
}: ChatPreviewWidgetProps): react_jsx_runtime9.JSX.Element;
|
|
16
16
|
displayName: string;
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseWidgetProps } from "../../hocs/withBaseWidget/types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts
|
|
5
5
|
declare const ChatPreviewWidgetWithBaseWidget: {
|
|
6
|
-
(props: BaseWidgetProps):
|
|
6
|
+
(props: BaseWidgetProps): react_jsx_runtime12.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
interface ChatPreviewWidgetProps {
|
|
@@ -12,7 +12,7 @@ interface ChatPreviewWidgetProps {
|
|
|
12
12
|
declare const ChatPreviewWidget: {
|
|
13
13
|
({
|
|
14
14
|
widgetConfigId
|
|
15
|
-
}: ChatPreviewWidgetProps):
|
|
15
|
+
}: ChatPreviewWidgetProps): react_jsx_runtime12.JSX.Element;
|
|
16
16
|
displayName: string;
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
@@ -85,7 +85,10 @@ const FloatingChatWidgetHandler = (props) => {
|
|
|
85
85
|
enabled: customerServiceIntegration?.enabled ?? false,
|
|
86
86
|
suppressMerchantButton: customerServiceIntegration?.suppressMerchantButton ?? false,
|
|
87
87
|
onSwitchToAgent: () => setIsCXOpen(true),
|
|
88
|
-
onCXClose: () =>
|
|
88
|
+
onCXClose: () => {
|
|
89
|
+
setIsCXOpen(false);
|
|
90
|
+
if (!previewChatAlwaysOpen) closeChat(__envive_ai_react_hooks_application_models.ChatElementDisplayLocationV3.FLOATING_CHAT_CLOSE_BUTTON, void 0, "close_button");
|
|
91
|
+
},
|
|
89
92
|
children: ({ isSwitchEnabled, toggle }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [!previewButtonOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FloatingChatOverlay.FloatingChatOverlay, {
|
|
90
93
|
isOpened: effectiveIsOpen,
|
|
91
94
|
isResultsModalOpen,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime19 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/widgets/FloatingChatWidget/FloatingChatWidget.d.ts
|
|
4
4
|
interface FloatingChatWidgetProps {
|
|
@@ -13,7 +13,7 @@ declare const FloatingChatWidget: {
|
|
|
13
13
|
previewChatAlwaysOpen,
|
|
14
14
|
previewCXButtonsEnabled,
|
|
15
15
|
previewDisclaimer
|
|
16
|
-
}?: FloatingChatWidgetProps):
|
|
16
|
+
}?: FloatingChatWidgetProps): react_jsx_runtime19.JSX.Element;
|
|
17
17
|
displayName: string;
|
|
18
18
|
};
|
|
19
19
|
//#endregion
|