impact-chatbot 2.3.47 → 2.3.49
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/components/message-template/components/message-content/tabular-content/index.d.ts +4 -1
- package/dist/index.cjs.css +116 -0
- package/dist/index.cjs.js +341 -64
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.css +116 -0
- package/dist/index.esm.js +341 -64
- package/dist/index.esm.js.map +1 -1
- package/dist/tabNotification.d.ts +19 -0
- package/dist/utlis.d.ts +11 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -767,6 +767,55 @@ const generateConversationObject = (conversationId) => {
|
|
|
767
767
|
};
|
|
768
768
|
}
|
|
769
769
|
};
|
|
770
|
+
/**
|
|
771
|
+
* Extracts userExplicitInput and textWithColumnNames from a saved filter set.
|
|
772
|
+
* @param {object} selectedFilterSet - The selected saved filter set object
|
|
773
|
+
* @param {string} userText - The user's input text (used to build textWithColumnNames)
|
|
774
|
+
* @param {object} existingExplicitInput - Optional existing userExplicitInput to merge with (e.g. from @ mentions)
|
|
775
|
+
* @returns {{ userExplicitInput: object, textWithColumnNames: string }}
|
|
776
|
+
*/
|
|
777
|
+
const extractSavedFilterData = (selectedFilterSet, userText = "", existingExplicitInput = {}) => {
|
|
778
|
+
let userExplicitInput = { ...existingExplicitInput };
|
|
779
|
+
let textWithColumnNames = "";
|
|
780
|
+
if (!selectedFilterSet?.saved_filter_preference) {
|
|
781
|
+
return { userExplicitInput: existingExplicitInput, textWithColumnNames };
|
|
782
|
+
}
|
|
783
|
+
selectedFilterSet.saved_filter_preference.forEach((filter) => {
|
|
784
|
+
const attrName = filter.attribute_name;
|
|
785
|
+
if (!attrName)
|
|
786
|
+
return;
|
|
787
|
+
let filterValues = [];
|
|
788
|
+
if (Array.isArray(filter.values)) {
|
|
789
|
+
filter.values.forEach((v) => {
|
|
790
|
+
if (v && Array.isArray(v.values)) {
|
|
791
|
+
filterValues.push(...v.values.map(String));
|
|
792
|
+
}
|
|
793
|
+
else if (typeof v === "string" || typeof v === "number") {
|
|
794
|
+
filterValues.push(String(v));
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
if (filterValues.length > 0) {
|
|
799
|
+
if (userExplicitInput[attrName]) {
|
|
800
|
+
userExplicitInput[attrName] = [
|
|
801
|
+
...new Set([...userExplicitInput[attrName], ...filterValues]),
|
|
802
|
+
];
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
userExplicitInput[attrName] = [...new Set(filterValues)];
|
|
806
|
+
}
|
|
807
|
+
const filterText = `${attrName}: ${filterValues.join(", ")}`;
|
|
808
|
+
textWithColumnNames = textWithColumnNames
|
|
809
|
+
? `${filterText} ${textWithColumnNames}`
|
|
810
|
+
: `${filterText} ${userText}`;
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
// Ensure textWithColumnNames ends with the user's text
|
|
814
|
+
if (textWithColumnNames && !textWithColumnNames.includes(userText) && userText.trim()) {
|
|
815
|
+
textWithColumnNames = `${textWithColumnNames} ${userText}`.trim();
|
|
816
|
+
}
|
|
817
|
+
return { userExplicitInput, textWithColumnNames };
|
|
818
|
+
};
|
|
770
819
|
|
|
771
820
|
// Special character mapping for text replacement
|
|
772
821
|
const SPECIAL_CHARACTER_MAPPING = {
|
|
@@ -1858,6 +1907,7 @@ const useAgentFlow = (dateFormat, chatDataRef, currentMode, setShowChatPlacehold
|
|
|
1858
1907
|
chat_input: data?.chatInput,
|
|
1859
1908
|
delay: 0.3,
|
|
1860
1909
|
chat_id: utilityObjectData?.uniqueChatId ? utilityObjectData?.uniqueChatId : utilityObjectData?.currentAgentChatId,
|
|
1910
|
+
answer_mode: data?.answerMode || "auto",
|
|
1861
1911
|
...(!isEmpty(utilityObjectData?.additionalArgs) ? utilityObjectData.additionalArgs : {}),
|
|
1862
1912
|
};
|
|
1863
1913
|
// Handle @ filter mentions - user_explicit_input contains filter values
|
|
@@ -4623,7 +4673,7 @@ const Rectangle = ({ type, icon, title, description, onClick, hoverable }) => {
|
|
|
4623
4673
|
return (jsx("div", { className: `${classes.rectangle} ${classes[type]} ${hoverable ? classes.rectangleHoverable : ''}`, onClick: onClick, title: isTruncated ? title : null, children: jsxs("div", { className: classes.textContainer, children: [jsx(Typography, { className: classes.title, ref: titleRef, children: title }), jsx(Typography, { className: classes.description, children: description })] }) }));
|
|
4624
4674
|
};
|
|
4625
4675
|
const ChatPlaceholder = (props) => {
|
|
4626
|
-
const { dateFormat, chatDataRef, currentMode, setShowChatPlaceholder, setLoader, setCurrentAgentId, baseUrl, setBaseUrl, setCurrentSessionId, customChatConfig, chatDataInfoRef, setChatDataState, userInput, legacyAgentScreen, activeConversationId, chatBodyRef, chatbotContext, setInitValue, setSessionId, thinkingContent, setThinkingContent, isThinking, setIsThinking, chatId, setChatId, isStop, setIsStop, functionsRef, functionsState, setFunctionsState, thinkingHeaderMessage, setThinkingHeaderMessage, uniqueChatId, setUniqueChatId, fieldNumber, setFieldNumber, setAdditionalArgs, questions, displayQuestions, setActiveConversationId } = props;
|
|
4676
|
+
const { dateFormat, chatDataRef, currentMode, setShowChatPlaceholder, setLoader, setCurrentAgentId, baseUrl, setBaseUrl, setCurrentSessionId, customChatConfig, chatDataInfoRef, setChatDataState, userInput, legacyAgentScreen, activeConversationId, chatBodyRef, chatbotContext, setInitValue, setSessionId, thinkingContent, setThinkingContent, isThinking, setIsThinking, chatId, setChatId, isStop, setIsStop, functionsRef, functionsState, setFunctionsState, thinkingHeaderMessage, setThinkingHeaderMessage, uniqueChatId, setUniqueChatId, fieldNumber, setFieldNumber, setAdditionalArgs, questions, displayQuestions, setActiveConversationId, selectedFilterSet, answerMode, } = props;
|
|
4627
4677
|
const classes = useStyles$6();
|
|
4628
4678
|
globalStyles();
|
|
4629
4679
|
const [cardList, setCardList] = useState([]);
|
|
@@ -4707,7 +4757,17 @@ const ChatPlaceholder = (props) => {
|
|
|
4707
4757
|
user_input: title,
|
|
4708
4758
|
init: true,
|
|
4709
4759
|
delay: 0.3,
|
|
4760
|
+
answer_mode: answerMode || "auto",
|
|
4710
4761
|
};
|
|
4762
|
+
// If a saved filter set is selected, merge its filters into the payload
|
|
4763
|
+
if (selectedFilterSet?.saved_filter_preference) {
|
|
4764
|
+
const { userExplicitInput, textWithColumnNames } = extractSavedFilterData(selectedFilterSet, title);
|
|
4765
|
+
if (!isEmpty$1(userExplicitInput)) {
|
|
4766
|
+
initiateAgentPayload.user_explicit_input = userExplicitInput;
|
|
4767
|
+
initiateAgentPayload.chat_input = title;
|
|
4768
|
+
initiateAgentPayload.user_input = textWithColumnNames || title;
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4711
4771
|
setAgentFlow(initiateAgentPayload, "", baseUrl);
|
|
4712
4772
|
}
|
|
4713
4773
|
// setAgentFlow(initiateAgentPayload, "", baseUrl);
|
|
@@ -5086,6 +5146,15 @@ const sseevent = (message, messageToStoreRef) => {
|
|
|
5086
5146
|
}
|
|
5087
5147
|
return new MessageEvent(type, { data: data });
|
|
5088
5148
|
}
|
|
5149
|
+
if (parsedData?.status === "notification") {
|
|
5150
|
+
messageToStoreRef.current.notificationData = {
|
|
5151
|
+
message: parsedData?.message || "",
|
|
5152
|
+
chat_id: parsedData?.chat_id || "",
|
|
5153
|
+
session_id: parsedData?.session_id || "",
|
|
5154
|
+
};
|
|
5155
|
+
// Do NOT append notification messages to chatData.response — return early
|
|
5156
|
+
return new MessageEvent(type, { data: data });
|
|
5157
|
+
}
|
|
5089
5158
|
if (parsedData?.status === "thinking") {
|
|
5090
5159
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingStream =
|
|
5091
5160
|
messageToStoreRef.current.chatData.thinkingResponse.thinkingStream +
|
|
@@ -5122,13 +5191,6 @@ const sseevent = (message, messageToStoreRef) => {
|
|
|
5122
5191
|
? parsedData.additional_args
|
|
5123
5192
|
: {};
|
|
5124
5193
|
}
|
|
5125
|
-
if (parsedData?.status === "notification") {
|
|
5126
|
-
messageToStoreRef.current.notificationData = {
|
|
5127
|
-
message: parsedData?.message || "",
|
|
5128
|
-
chat_id: parsedData?.chat_id || "",
|
|
5129
|
-
session_id: parsedData?.session_id || "",
|
|
5130
|
-
};
|
|
5131
|
-
}
|
|
5132
5194
|
if (parsedData?.status === "completed" ||
|
|
5133
5195
|
parsedData?.status === "follow-up") {
|
|
5134
5196
|
messageToStoreRef.current.initValue = true;
|
|
@@ -5391,10 +5453,10 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5391
5453
|
if (sessionId) {
|
|
5392
5454
|
stopAgentFlow({ session_id: sessionId }, baseUrl);
|
|
5393
5455
|
}
|
|
5394
|
-
dispatch(setStepFormStreamData({ status: "error", chunks: [...chunksRef] }));
|
|
5456
|
+
dispatch(setStepFormStreamData({ status: "error", chunks: [...chunksRef], sessionId }));
|
|
5395
5457
|
};
|
|
5396
5458
|
// Signal that streaming has started (after setting stepFormStreamControl so useEffect sees the flag)
|
|
5397
|
-
dispatch(setStepFormStreamData({ status: "streaming_start", chunks: [] }));
|
|
5459
|
+
dispatch(setStepFormStreamData({ status: "streaming_start", chunks: [], sessionId }));
|
|
5398
5460
|
// Fire DOM event so SmartBot can show stop icon (Redux gets cleared by TabularContent before parent effects run)
|
|
5399
5461
|
window.dispatchEvent(new CustomEvent("stepFormStreamStart"));
|
|
5400
5462
|
sourceRef.current = AxiosSource(endPoint, {
|
|
@@ -5416,14 +5478,14 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5416
5478
|
chunksRef.push(data);
|
|
5417
5479
|
// Dispatch widget chunks immediately for real-time rendering
|
|
5418
5480
|
if (data?.status === "widget") {
|
|
5419
|
-
dispatch(setStepFormStreamData({ status: "widget_chunk", chunks: [data] }));
|
|
5481
|
+
dispatch(setStepFormStreamData({ status: "widget_chunk", chunks: [data], sessionId }));
|
|
5420
5482
|
}
|
|
5421
5483
|
// If this chunk also carries [DONE], dispatch collected chunks now
|
|
5422
5484
|
if (data?.message === "[DONE]") {
|
|
5423
5485
|
stepFormStreamControl.isStreaming = false;
|
|
5424
5486
|
stepFormStreamControl.abort = null;
|
|
5425
5487
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5426
|
-
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5488
|
+
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef], sessionId }));
|
|
5427
5489
|
}
|
|
5428
5490
|
}
|
|
5429
5491
|
else if (data?.status === "completed" || data?.status === "follow-up" || data?.message === "[DONE]") {
|
|
@@ -5447,7 +5509,7 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5447
5509
|
if (data?.status === "completed" && !hasStepForm) {
|
|
5448
5510
|
window.dispatchEvent(new CustomEvent("stepFormStreamCompleted"));
|
|
5449
5511
|
}
|
|
5450
|
-
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef] }));
|
|
5512
|
+
dispatch(setStepFormStreamData({ status: "done", chunks: [...chunksRef], sessionId }));
|
|
5451
5513
|
}
|
|
5452
5514
|
else if (data?.message) {
|
|
5453
5515
|
chunksRef.push({ status: "content", message: data.message });
|
|
@@ -5462,7 +5524,7 @@ const ButtonContent = ({ bodyText, isFormDisabled = false, isStepFormSubmit = fa
|
|
|
5462
5524
|
stepFormStreamControl.isStreaming = false;
|
|
5463
5525
|
stepFormStreamControl.abort = null;
|
|
5464
5526
|
window.dispatchEvent(new CustomEvent("stepFormStreamEnd"));
|
|
5465
|
-
dispatch(setStepFormStreamData({ status: "error", chunks: chunksRef }));
|
|
5527
|
+
dispatch(setStepFormStreamData({ status: "error", chunks: chunksRef, sessionId }));
|
|
5466
5528
|
});
|
|
5467
5529
|
};
|
|
5468
5530
|
const renderButtons = () => {
|
|
@@ -6734,6 +6796,165 @@ const StepsResponseTab = (props) => {
|
|
|
6734
6796
|
], value: tabValue }) }));
|
|
6735
6797
|
};
|
|
6736
6798
|
|
|
6799
|
+
/**
|
|
6800
|
+
* Tab Notification Utility
|
|
6801
|
+
* Shows a red badge on the browser tab favicon and updates the document title
|
|
6802
|
+
* when new step_form chunks arrive while the user is on a different tab.
|
|
6803
|
+
* Similar to Facebook's unread message count badge.
|
|
6804
|
+
*/
|
|
6805
|
+
const ORIGINAL_TITLE = " Impact Smart ";
|
|
6806
|
+
const FAVICON_SELECTOR = 'link[rel="icon"]';
|
|
6807
|
+
let notificationCount = 0;
|
|
6808
|
+
let originalFaviconHref = null;
|
|
6809
|
+
let faviconCanvas = null;
|
|
6810
|
+
let faviconCtx = null;
|
|
6811
|
+
let faviconImg = null;
|
|
6812
|
+
let isInitialized = false;
|
|
6813
|
+
let visibilityListenerAttached = false;
|
|
6814
|
+
let titleBlinkInterval = null;
|
|
6815
|
+
/**
|
|
6816
|
+
* Initialize the canvas and load the original favicon image.
|
|
6817
|
+
* Called lazily on first notification.
|
|
6818
|
+
*/
|
|
6819
|
+
function init() {
|
|
6820
|
+
if (isInitialized)
|
|
6821
|
+
return;
|
|
6822
|
+
isInitialized = true;
|
|
6823
|
+
const faviconEl = document.querySelector(FAVICON_SELECTOR);
|
|
6824
|
+
originalFaviconHref = faviconEl ? faviconEl.href : "/assets/IA.svg";
|
|
6825
|
+
faviconCanvas = document.createElement("canvas");
|
|
6826
|
+
faviconCanvas.width = 64;
|
|
6827
|
+
faviconCanvas.height = 64;
|
|
6828
|
+
faviconCtx = faviconCanvas.getContext("2d");
|
|
6829
|
+
faviconImg = new Image();
|
|
6830
|
+
faviconImg.crossOrigin = "anonymous";
|
|
6831
|
+
faviconImg.src = originalFaviconHref;
|
|
6832
|
+
if (!visibilityListenerAttached) {
|
|
6833
|
+
visibilityListenerAttached = true;
|
|
6834
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
/**
|
|
6838
|
+
* When the user returns to the tab, clear all notifications.
|
|
6839
|
+
*/
|
|
6840
|
+
function handleVisibilityChange() {
|
|
6841
|
+
if (!document.hidden && notificationCount > 0) {
|
|
6842
|
+
clearTabNotification();
|
|
6843
|
+
}
|
|
6844
|
+
}
|
|
6845
|
+
/**
|
|
6846
|
+
* Draw the favicon with a red notification badge showing the count.
|
|
6847
|
+
*/
|
|
6848
|
+
function drawBadge(count) {
|
|
6849
|
+
if (!faviconCtx || !faviconCanvas)
|
|
6850
|
+
return;
|
|
6851
|
+
const size = faviconCanvas.width;
|
|
6852
|
+
faviconCtx.clearRect(0, 0, size, size);
|
|
6853
|
+
// Draw original favicon
|
|
6854
|
+
if (faviconImg && faviconImg.complete && faviconImg.naturalWidth > 0) {
|
|
6855
|
+
faviconCtx.drawImage(faviconImg, 0, 0, size, size);
|
|
6856
|
+
}
|
|
6857
|
+
if (count <= 0)
|
|
6858
|
+
return;
|
|
6859
|
+
const text = count > 99 ? "99+" : String(count);
|
|
6860
|
+
// Badge dimensions
|
|
6861
|
+
const badgeRadius = 14;
|
|
6862
|
+
const badgeX = size - badgeRadius - 1;
|
|
6863
|
+
const badgeY = badgeRadius + 1;
|
|
6864
|
+
// Draw red circle
|
|
6865
|
+
faviconCtx.beginPath();
|
|
6866
|
+
faviconCtx.arc(badgeX, badgeY, badgeRadius, 0, 2 * Math.PI);
|
|
6867
|
+
faviconCtx.fillStyle = "#e53e3e";
|
|
6868
|
+
faviconCtx.fill();
|
|
6869
|
+
// White border
|
|
6870
|
+
faviconCtx.lineWidth = 2;
|
|
6871
|
+
faviconCtx.strokeStyle = "#ffffff";
|
|
6872
|
+
faviconCtx.stroke();
|
|
6873
|
+
// Draw count text
|
|
6874
|
+
faviconCtx.fillStyle = "#ffffff";
|
|
6875
|
+
faviconCtx.font = `bold ${count > 9 ? 14 : 18}px sans-serif`;
|
|
6876
|
+
faviconCtx.textAlign = "center";
|
|
6877
|
+
faviconCtx.textBaseline = "middle";
|
|
6878
|
+
faviconCtx.fillText(text, badgeX, badgeY + 1);
|
|
6879
|
+
}
|
|
6880
|
+
/**
|
|
6881
|
+
* Update the favicon element in the DOM.
|
|
6882
|
+
*/
|
|
6883
|
+
function applyFavicon(dataUrl) {
|
|
6884
|
+
let faviconEl = document.querySelector(FAVICON_SELECTOR);
|
|
6885
|
+
if (!faviconEl) {
|
|
6886
|
+
faviconEl = document.createElement("link");
|
|
6887
|
+
faviconEl.rel = "icon";
|
|
6888
|
+
document.head.appendChild(faviconEl);
|
|
6889
|
+
}
|
|
6890
|
+
faviconEl.href = dataUrl;
|
|
6891
|
+
}
|
|
6892
|
+
/**
|
|
6893
|
+
* Increment the tab notification count.
|
|
6894
|
+
* Only shows badge when the tab is not visible (user is on another tab).
|
|
6895
|
+
*/
|
|
6896
|
+
function showTabNotification() {
|
|
6897
|
+
// Only notify when user is NOT looking at this tab
|
|
6898
|
+
if (!document.hidden)
|
|
6899
|
+
return;
|
|
6900
|
+
init();
|
|
6901
|
+
notificationCount += 1;
|
|
6902
|
+
// Start blinking title to grab attention
|
|
6903
|
+
startTitleBlink();
|
|
6904
|
+
// Draw and apply badge favicon
|
|
6905
|
+
const renderBadge = () => {
|
|
6906
|
+
drawBadge(notificationCount);
|
|
6907
|
+
applyFavicon(faviconCanvas.toDataURL("image/png"));
|
|
6908
|
+
};
|
|
6909
|
+
if (faviconImg && faviconImg.complete) {
|
|
6910
|
+
renderBadge();
|
|
6911
|
+
}
|
|
6912
|
+
else if (faviconImg) {
|
|
6913
|
+
faviconImg.onload = renderBadge;
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
/**
|
|
6917
|
+
* Alternates the document title between notification message and a blank/attention string
|
|
6918
|
+
* to create a blinking effect that catches the user's eye (like WhatsApp Web / Facebook).
|
|
6919
|
+
*/
|
|
6920
|
+
function startTitleBlink() {
|
|
6921
|
+
if (titleBlinkInterval)
|
|
6922
|
+
clearInterval(titleBlinkInterval);
|
|
6923
|
+
let showNotification = true;
|
|
6924
|
+
const notificationTitle = `(${notificationCount}) New form awaiting input`;
|
|
6925
|
+
// Set immediately
|
|
6926
|
+
document.title = notificationTitle;
|
|
6927
|
+
titleBlinkInterval = setInterval(() => {
|
|
6928
|
+
if (showNotification) {
|
|
6929
|
+
document.title = ORIGINAL_TITLE.trim();
|
|
6930
|
+
}
|
|
6931
|
+
else {
|
|
6932
|
+
document.title = `(${notificationCount}) New form awaiting input`;
|
|
6933
|
+
}
|
|
6934
|
+
showNotification = !showNotification;
|
|
6935
|
+
}, 1000);
|
|
6936
|
+
}
|
|
6937
|
+
/**
|
|
6938
|
+
* Stop the title blink interval.
|
|
6939
|
+
*/
|
|
6940
|
+
function stopTitleBlink() {
|
|
6941
|
+
if (titleBlinkInterval) {
|
|
6942
|
+
clearInterval(titleBlinkInterval);
|
|
6943
|
+
titleBlinkInterval = null;
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
/**
|
|
6947
|
+
* Clear all tab notifications — restore original title and favicon.
|
|
6948
|
+
*/
|
|
6949
|
+
function clearTabNotification() {
|
|
6950
|
+
notificationCount = 0;
|
|
6951
|
+
stopTitleBlink();
|
|
6952
|
+
document.title = ORIGINAL_TITLE;
|
|
6953
|
+
if (originalFaviconHref) {
|
|
6954
|
+
applyFavicon(originalFaviconHref);
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6957
|
+
|
|
6737
6958
|
/**
|
|
6738
6959
|
* Module-level Map to persist streaming state across component remounts (tab switches).
|
|
6739
6960
|
* Keyed by a stable identifier derived from input payload + mode + conversation ID.
|
|
@@ -7063,6 +7284,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7063
7284
|
setStepChange((prev) => !prev);
|
|
7064
7285
|
}
|
|
7065
7286
|
else if (data.status === "step_form") {
|
|
7287
|
+
showTabNotification();
|
|
7066
7288
|
const formWidgetData = isArray(data.widget_data)
|
|
7067
7289
|
? data.widget_data
|
|
7068
7290
|
: [data.widget_data];
|
|
@@ -7347,6 +7569,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7347
7569
|
data: isEmpty(dummyButton)
|
|
7348
7570
|
? [textResponseTobeParsed, ...finalData]
|
|
7349
7571
|
: [textResponseTobeParsed, ...finalData, dummyButton],
|
|
7572
|
+
session_id: messageToStoreRef.current.sessionId || "",
|
|
7350
7573
|
},
|
|
7351
7574
|
},
|
|
7352
7575
|
};
|
|
@@ -7431,6 +7654,7 @@ const StreamedContent = ({ botData }) => {
|
|
|
7431
7654
|
data: {
|
|
7432
7655
|
data: {
|
|
7433
7656
|
data: [textResponseTobeParsed, ...finalData],
|
|
7657
|
+
session_id: messageToStoreRef.current.sessionId || "",
|
|
7434
7658
|
},
|
|
7435
7659
|
},
|
|
7436
7660
|
};
|
|
@@ -7851,7 +8075,11 @@ const AgentResponse = ({ children }) => {
|
|
|
7851
8075
|
return (jsx("div", { className: classes.agentResponseContainer, children: children }));
|
|
7852
8076
|
};
|
|
7853
8077
|
|
|
7854
|
-
|
|
8078
|
+
// Module-level counter and active instance tracker.
|
|
8079
|
+
// Only the active instance should process stepFormStreamData from Redux.
|
|
8080
|
+
let instanceCounter = 0;
|
|
8081
|
+
let activeTabularInstanceId = null;
|
|
8082
|
+
const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "" }) => {
|
|
7855
8083
|
const dispatch = useDispatch();
|
|
7856
8084
|
const stepFormStreamData = useSelector((state) => state.smartBotReducer.stepFormStreamData);
|
|
7857
8085
|
const [tabValue, setTabValue] = useState(currentTabValue);
|
|
@@ -7875,6 +8103,12 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7875
8103
|
const [stepFormSubmitted, setStepFormSubmitted] = useState(false);
|
|
7876
8104
|
const [hasNewStepFormFromRestream, setHasNewStepFormFromRestream] = useState(false);
|
|
7877
8105
|
const [activeFormIntent, setActiveFormIntent] = useState(null);
|
|
8106
|
+
// Stable unique instance ID for this TabularContent mount
|
|
8107
|
+
const instanceIdRef = useRef(null);
|
|
8108
|
+
if (instanceIdRef.current === null) {
|
|
8109
|
+
instanceCounter += 1;
|
|
8110
|
+
instanceIdRef.current = instanceCounter;
|
|
8111
|
+
}
|
|
7878
8112
|
// Refs for accumulating state during streaming (avoids stale closures)
|
|
7879
8113
|
const stepsRef = useRef(stepsState);
|
|
7880
8114
|
const questionsRef = useRef(questionsState);
|
|
@@ -7916,10 +8150,21 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
7916
8150
|
return null;
|
|
7917
8151
|
}
|
|
7918
8152
|
};
|
|
8153
|
+
// Register as active instance when this TabularContent has an active step form
|
|
8154
|
+
useEffect(() => {
|
|
8155
|
+
const hasActiveForm = Object.keys(initialStepFormDataMap).length > 0;
|
|
8156
|
+
if (hasActiveForm) {
|
|
8157
|
+
activeTabularInstanceId = instanceIdRef.current;
|
|
8158
|
+
}
|
|
8159
|
+
}, [initialStepFormDataMap]);
|
|
7919
8160
|
// Watch Redux for batched SSE chunks dispatched by ButtonContent
|
|
7920
8161
|
useEffect(() => {
|
|
7921
8162
|
if (!stepFormStreamData)
|
|
7922
8163
|
return;
|
|
8164
|
+
// Only the active instance should process stepFormStreamData
|
|
8165
|
+
if (activeTabularInstanceId !== null && activeTabularInstanceId !== instanceIdRef.current) {
|
|
8166
|
+
return;
|
|
8167
|
+
}
|
|
7923
8168
|
const payload = stepFormStreamData;
|
|
7924
8169
|
// Clear Redux immediately
|
|
7925
8170
|
dispatch(setStepFormStreamData(null));
|
|
@@ -8073,6 +8318,8 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
8073
8318
|
setStepFormSubmitted(false);
|
|
8074
8319
|
setHasNewStepFormFromRestream(true);
|
|
8075
8320
|
setActiveFormIntent(latestIntent || null);
|
|
8321
|
+
// Re-register as active instance since this TabularContent now owns the new form
|
|
8322
|
+
activeTabularInstanceId = instanceIdRef.current;
|
|
8076
8323
|
// Clear stale persisted form values and context so the new form starts fresh
|
|
8077
8324
|
dispatch(clearPersistedFormValues());
|
|
8078
8325
|
dispatch(setChatbotContext({}));
|
|
@@ -8097,6 +8344,10 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
|
|
|
8097
8344
|
jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets }))] }),
|
|
8098
8345
|
], value: tabValue }) }));
|
|
8099
8346
|
};
|
|
8347
|
+
/** Reset the active instance tracker (call when a new conversation starts from the input field) */
|
|
8348
|
+
const resetActiveTabularInstance = () => {
|
|
8349
|
+
activeTabularInstanceId = null;
|
|
8350
|
+
};
|
|
8100
8351
|
|
|
8101
8352
|
const CombinedContent = ({ botData, props }) => {
|
|
8102
8353
|
const isFormDisabled = botData?.isFormDisabled || false;
|
|
@@ -8165,7 +8416,7 @@ const CombinedContent = ({ botData, props }) => {
|
|
|
8165
8416
|
const validContent = renderedContent.filter(content => content !== null);
|
|
8166
8417
|
const renderCombinedContent = () => (jsx("div", { className: "combined-content-container", children: validContent.length > 0 ? (validContent.map((content, index) => (jsx("div", { className: "combined-content-item", children: content }, `wrapper-${index}`)))) : (jsx("div", { children: "No valid content to display" })) }));
|
|
8167
8418
|
if (isTabEnabled) {
|
|
8168
|
-
return (jsx(TabularContent, { steps: botData?.utilityData?.steps || [], currentTabValue: botData?.utilityData?.currentTabValue || "steps", questions: botData?.utilityData?.questions || [], questionsStepsMap: botData?.utilityData?.questionsStepsMap || {}, stepFormDataMap: botData?.utilityData?.stepFormDataMap || {}, isFormDisabled: isFormDisabled, children: renderCombinedContent() }));
|
|
8419
|
+
return (jsx(TabularContent, { steps: botData?.utilityData?.steps || [], currentTabValue: botData?.utilityData?.currentTabValue || "steps", questions: botData?.utilityData?.questions || [], questionsStepsMap: botData?.utilityData?.questionsStepsMap || {}, stepFormDataMap: botData?.utilityData?.stepFormDataMap || {}, isFormDisabled: isFormDisabled, sessionId: botData?.sessionId || "", children: renderCombinedContent() }));
|
|
8169
8420
|
}
|
|
8170
8421
|
return renderCombinedContent();
|
|
8171
8422
|
};
|
|
@@ -9580,7 +9831,7 @@ const useMentionState = () => {
|
|
|
9580
9831
|
};
|
|
9581
9832
|
|
|
9582
9833
|
const ChatbotInput = (props) => {
|
|
9583
|
-
const { newChatScreen, inputValue, setInputValue, isStopIcon, handleMicClick, handleRefresh, onSendIconClick, onStopIconClick, currentMode, filterOptions, onSaveClick, savedFilterSets, onFilterSetSelect, onTriggerRefresh, selectedFilterSet, onClearFilterSet, } = props;
|
|
9834
|
+
const { newChatScreen, inputValue, setInputValue, isStopIcon, handleMicClick, handleRefresh, onSendIconClick, onStopIconClick, currentMode, filterOptions, onSaveClick, savedFilterSets, onFilterSetSelect, onTriggerRefresh, selectedFilterSet, onClearFilterSet, answerMode, setAnswerMode, } = props;
|
|
9584
9835
|
const editorRef = useRef(null);
|
|
9585
9836
|
const selectRef = useRef(null);
|
|
9586
9837
|
const filterSetSelectRef = useRef(null);
|
|
@@ -9590,6 +9841,8 @@ const ChatbotInput = (props) => {
|
|
|
9590
9841
|
const chatInputContainerRef = useRef(null);
|
|
9591
9842
|
const [isFixed, setIsFixed] = useState(false);
|
|
9592
9843
|
const [height, setHeight] = useState("auto");
|
|
9844
|
+
const [showAnswerModeMenu, setShowAnswerModeMenu] = useState(false);
|
|
9845
|
+
const answerModeRef = useRef(null);
|
|
9593
9846
|
const [hasMentionsInEditor, setHasMentionsInEditor] = useState(false);
|
|
9594
9847
|
const isInsertingMentionRef = useRef(false);
|
|
9595
9848
|
const isTransitioningStageRef = useRef(false);
|
|
@@ -10590,44 +10843,9 @@ const ChatbotInput = (props) => {
|
|
|
10590
10843
|
// If a saved filter set is selected, merge its filters into userExplicitInput
|
|
10591
10844
|
// and textWithColumnNames in the same format as @ mentions
|
|
10592
10845
|
if (selectedFilterSet?.saved_filter_preference) {
|
|
10593
|
-
selectedFilterSet
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
return;
|
|
10597
|
-
// Extract all values from the filter's values array
|
|
10598
|
-
let filterValues = [];
|
|
10599
|
-
if (Array.isArray(filter.values)) {
|
|
10600
|
-
filter.values.forEach((v) => {
|
|
10601
|
-
if (v && Array.isArray(v.values)) {
|
|
10602
|
-
filterValues.push(...v.values.map(String));
|
|
10603
|
-
}
|
|
10604
|
-
else if (typeof v === "string" || typeof v === "number") {
|
|
10605
|
-
filterValues.push(String(v));
|
|
10606
|
-
}
|
|
10607
|
-
});
|
|
10608
|
-
}
|
|
10609
|
-
if (filterValues.length > 0) {
|
|
10610
|
-
// Merge into userExplicitInput (combine with existing @ mention values if any)
|
|
10611
|
-
if (userExplicitInput[attrName]) {
|
|
10612
|
-
userExplicitInput[attrName] = [
|
|
10613
|
-
...new Set([...userExplicitInput[attrName], ...filterValues]),
|
|
10614
|
-
];
|
|
10615
|
-
}
|
|
10616
|
-
else {
|
|
10617
|
-
userExplicitInput[attrName] = [...new Set(filterValues)];
|
|
10618
|
-
}
|
|
10619
|
-
// Build textWithColumnNames prefix from saved filter data
|
|
10620
|
-
const filterText = `${attrName}: ${filterValues.join(", ")}`;
|
|
10621
|
-
textWithColumnNames = textWithColumnNames
|
|
10622
|
-
? `${filterText} ${textWithColumnNames}`
|
|
10623
|
-
: `${filterText} ${formattedText}`;
|
|
10624
|
-
}
|
|
10625
|
-
});
|
|
10626
|
-
// If textWithColumnNames was not set by mentions but was set by saved filters,
|
|
10627
|
-
// ensure it ends with the user's text
|
|
10628
|
-
if (!textWithColumnNames.includes(formattedText) && formattedText.trim()) {
|
|
10629
|
-
textWithColumnNames = `${textWithColumnNames} ${formattedText}`.trim();
|
|
10630
|
-
}
|
|
10846
|
+
const filterData = extractSavedFilterData(selectedFilterSet, formattedText, userExplicitInput);
|
|
10847
|
+
Object.assign(userExplicitInput, filterData.userExplicitInput);
|
|
10848
|
+
textWithColumnNames = filterData.textWithColumnNames || textWithColumnNames;
|
|
10631
10849
|
}
|
|
10632
10850
|
setInputValue("");
|
|
10633
10851
|
if (editorRef.current) {
|
|
@@ -10887,6 +11105,25 @@ const ChatbotInput = (props) => {
|
|
|
10887
11105
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
10888
11106
|
};
|
|
10889
11107
|
}, [showFilterSetMenu]);
|
|
11108
|
+
// Click outside handler for answer mode dropdown
|
|
11109
|
+
useEffect(() => {
|
|
11110
|
+
const handleClickOutside = (event) => {
|
|
11111
|
+
if (answerModeRef.current && !answerModeRef.current.contains(event.target)) {
|
|
11112
|
+
setShowAnswerModeMenu(false);
|
|
11113
|
+
}
|
|
11114
|
+
};
|
|
11115
|
+
if (showAnswerModeMenu) {
|
|
11116
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
11117
|
+
}
|
|
11118
|
+
return () => {
|
|
11119
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
11120
|
+
};
|
|
11121
|
+
}, [showAnswerModeMenu]);
|
|
11122
|
+
const ANSWER_MODE_OPTIONS = [
|
|
11123
|
+
{ value: "fast", label: "Fast", description: "Speed over depth" },
|
|
11124
|
+
{ value: "auto", label: "Auto", description: "Adapts depth, detail, and visuals" },
|
|
11125
|
+
];
|
|
11126
|
+
const selectedModeOption = ANSWER_MODE_OPTIONS.find((opt) => opt.value === answerMode) || ANSWER_MODE_OPTIONS[1];
|
|
10890
11127
|
return (jsx("div", { className: "chat-input-container", ref: chatInputContainerRef, onClick: (e) => {
|
|
10891
11128
|
// Focus editor when clicking anywhere in the input container
|
|
10892
11129
|
// unless clicking on a button or interactive element
|
|
@@ -10897,7 +11134,8 @@ const ChatbotInput = (props) => {
|
|
|
10897
11134
|
!target.closest(".chat-actions") &&
|
|
10898
11135
|
!target.closest(".filter-set-trigger-wrapper") &&
|
|
10899
11136
|
!target.closest(".filter-set-chip-clear") &&
|
|
10900
|
-
!target.closest(".mention-select-wrapper")
|
|
11137
|
+
!target.closest(".mention-select-wrapper") &&
|
|
11138
|
+
!target.closest(".answer-mode-wrapper")) {
|
|
10901
11139
|
editorRef.current.focus();
|
|
10902
11140
|
}
|
|
10903
11141
|
}, children: jsxs("div", { className: `chat-input-wrapper ${isFixed ? "stacked" : ""} ${selectedFilterSet ? "has-filter-selected" : ""} ${(!isFixed || inputValue === "") && !newChatScreen && !selectedFilterSet ? "empty" : ""} ${!newChatScreen && !isFixed && !selectedFilterSet ? "single-line-textarea" : ""}`, style: { height }, children: [jsxs("div", { className: "chat-input-left-actions", children: [jsxs("div", { className: "filter-set-trigger-wrapper", ref: filterSetSelectRef, children: [jsx(Tooltip, { title: hasMentionsInEditor || showMentionSelect ? "Cannot use filter set while @ mentions are active" : "Add filter set", children: jsx("button", { type: "button", className: `filter-set-plus-btn${hasMentionsInEditor || showMentionSelect ? " disabled" : ""}`, onClick: () => {
|
|
@@ -10927,7 +11165,10 @@ const ChatbotInput = (props) => {
|
|
|
10927
11165
|
handleSendMessage();
|
|
10928
11166
|
}
|
|
10929
11167
|
}
|
|
10930
|
-
}, onClick: detectMention, onKeyUp: detectMention, suppressContentEditableWarning: true }), jsxs("div", { className: `chat-actions ${isFixed ? "fixed" : ""}`, children: [handleRefresh && (jsx(Button, { icon: jsx(SvgChatBotRefreshIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "url", onClick: handleRefresh })), handleMicClick && (jsx(Button, { icon: jsx(SvgChatBotMicIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "tertiary", onClick: handleMicClick })), onSaveClick && (jsx(Tooltip, { title: "Save Chat", children: jsx(Button, { icon: jsx(SaveOutlinedIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "tertiary", onClick: onSaveClick, id: "chat-input-save-button" }) })),
|
|
11168
|
+
}, onClick: detectMention, onKeyUp: detectMention, suppressContentEditableWarning: true }), jsxs("div", { className: `chat-actions ${isFixed ? "fixed" : ""}`, children: [handleRefresh && (jsx(Button, { icon: jsx(SvgChatBotRefreshIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "url", onClick: handleRefresh })), handleMicClick && (jsx(Button, { icon: jsx(SvgChatBotMicIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "tertiary", onClick: handleMicClick })), onSaveClick && (jsx(Tooltip, { title: "Save Chat", children: jsx(Button, { icon: jsx(SaveOutlinedIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "tertiary", onClick: onSaveClick, id: "chat-input-save-button" }) })), jsxs("div", { className: "answer-mode-wrapper", ref: answerModeRef, children: [jsxs("button", { type: "button", className: "answer-mode-trigger", onClick: () => setShowAnswerModeMenu(!showAnswerModeMenu), children: [jsx("span", { className: "answer-mode-trigger-label", children: selectedModeOption.label }), jsx("svg", { className: `answer-mode-trigger-chevron ${showAnswerModeMenu ? "open" : ""}`, width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", children: jsx("path", { d: "M3 7.5L6 4.5L9 7.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), showAnswerModeMenu && (jsx("div", { className: "answer-mode-dropdown", children: ANSWER_MODE_OPTIONS.map((option) => (jsxs("button", { type: "button", className: `answer-mode-option ${answerMode === option.value ? "selected" : ""}`, onClick: () => {
|
|
11169
|
+
setAnswerMode(option.value);
|
|
11170
|
+
setShowAnswerModeMenu(false);
|
|
11171
|
+
}, children: [jsx("div", { className: "answer-mode-option-check", children: answerMode === option.value && (jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: jsx("path", { d: "M2.5 7L5.5 10L11.5 4", stroke: "#5C6BC0", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })) }), jsxs("div", { className: "answer-mode-option-content", children: [jsx("span", { className: "answer-mode-option-label", children: option.label }), jsx("span", { className: "answer-mode-option-desc", children: option.description })] })] }, option.value))) }))] }), jsx(Button, { icon: !isStopIcon ? jsx(SvgChatBotSendIcon, {}) : jsx(SvgChatbotStopIcon, {}), iconPlacement: "left", size: "large", type: "default", variant: "primary", onClick: () => {
|
|
10931
11172
|
!isStopIcon ? handleSendMessage() : onStopIconClick();
|
|
10932
11173
|
}, id: "chat-input-send-button", className: isStopIcon ? "stop-icon-button" : "" })] }), showMentionSelect && (jsx("div", { className: "mention-select-wrapper", ref: selectRef, style: {
|
|
10933
11174
|
position: "fixed",
|
|
@@ -11692,7 +11933,7 @@ const useStyles = makeStyles({
|
|
|
11692
11933
|
});
|
|
11693
11934
|
const ChatbotSaveFilterComponent = (props) => {
|
|
11694
11935
|
const classes = useStyles();
|
|
11695
|
-
const { savedFilterSets, partialClose } = props;
|
|
11936
|
+
const { savedFilterSets, partialClose, chatBotWidth } = props;
|
|
11696
11937
|
const [showFilter, setShowFilter] = useState(!isEmpty$1(savedFilterSets));
|
|
11697
11938
|
/**
|
|
11698
11939
|
* onFilterDashboardClick function is called when we click the apply filter
|
|
@@ -11765,11 +12006,13 @@ const ChatbotSaveFilterComponent = (props) => {
|
|
|
11765
12006
|
}
|
|
11766
12007
|
const filterContainer = document.querySelector(".impact_drawer_filter_container.impact_drawer_filter_container_large");
|
|
11767
12008
|
if (filterContainer) {
|
|
11768
|
-
|
|
12009
|
+
const computedWidth = chatBotWidth ? `${chatBotWidth - 86}px` : "616px";
|
|
12010
|
+
filterContainer.style.setProperty("width", computedWidth);
|
|
11769
12011
|
}
|
|
11770
12012
|
const rightPanel = document.querySelector(".impact_drawer_filter_container .impact_drawer_filter_container_right_panel");
|
|
11771
12013
|
if (rightPanel) {
|
|
11772
12014
|
rightPanel.style.setProperty("height", "600px");
|
|
12015
|
+
rightPanel.style.setProperty("width", "100%");
|
|
11773
12016
|
}
|
|
11774
12017
|
const backdrop = document.querySelector(".MuiBackdrop-root.MuiModal-backdrop");
|
|
11775
12018
|
if (backdrop) {
|
|
@@ -11803,7 +12046,7 @@ const ChatbotSaveFilterComponent = (props) => {
|
|
|
11803
12046
|
const observer = new MutationObserver(patchDrawer);
|
|
11804
12047
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
11805
12048
|
return () => observer.disconnect();
|
|
11806
|
-
}, [showFilter]);
|
|
12049
|
+
}, [showFilter, chatBotWidth]);
|
|
11807
12050
|
return (jsx("div", { className: partialClose ? classes.hidden : undefined, children: !showFilter ?
|
|
11808
12051
|
jsxs("div", { className: classes.container, children: [jsx(NoFilterSetSavedIcon, { width: "189px", height: "126px", className: classes.icon }), jsx("p", { className: classes.title, children: "No filter set saved!" }), jsx("p", { className: classes.subtitle, children: "Create and save a filter set to use as your default scope or apply it anytime during a conversation" }), jsx("div", { className: classes.buttonWrapper, children: jsx(Button, { variant: "primary", onClick: () => setShowFilter(true), children: "Create A Filter Set" }) })] }) :
|
|
11809
12052
|
jsx("div", { children: jsx(CoreComponentScreen, { showPageHeader: false,
|
|
@@ -11837,6 +12080,7 @@ const SmartBot = (props) => {
|
|
|
11837
12080
|
// Per-mode conversation ID tracking — prevents cross-mode contamination when
|
|
11838
12081
|
// switching tabs while streams are pending.
|
|
11839
12082
|
useRef({});
|
|
12083
|
+
const activeConversationIdRef = useRef(activeConversationId);
|
|
11840
12084
|
const activeTab = useRef({
|
|
11841
12085
|
activeTab: "dashboard",
|
|
11842
12086
|
});
|
|
@@ -11855,6 +12099,8 @@ const SmartBot = (props) => {
|
|
|
11855
12099
|
const [filterOptions, setFilterOptions] = useState([]);
|
|
11856
12100
|
const [savedFilterSets, setSavedFilterSets$1] = useState([]);
|
|
11857
12101
|
const [selectedFilterSet, setSelectedFilterSet] = useState(null);
|
|
12102
|
+
const [answerMode, setAnswerMode] = useState("auto");
|
|
12103
|
+
const [chatBotWidth, setChatBotWidth] = useState(null);
|
|
11858
12104
|
useRef(0);
|
|
11859
12105
|
const { setUserFlow, setUserScreenAndFlow, fetchUserResultsFromQuery, getCurrentDateTimeString, setLink, } = useChatFlow(chatDataRef, setLoader, setFlowType, setScreenName, setUserInput, setQuestionIndex, setCurrentAppLink, flowType, screenName, questionIndex, userInput, dateFormat, currentMode, activeConversationId, setIsModuleChanged, chatBodyRef, filterReducerState, dispatch, navigate, setShowChatPlaceholder, baseUrl, setChatDataState, setCurrentSessionId, customChatConfig, chatDataInfoRef, chatbotContext, setInitValue, setSessionId, thinkingContent, setThinkingContent, isThinking, setIsThinking, chatId, setChatId, isStop, setIsStop, functionsRef, functionsState, setFunctionsState, thinkingHeaderMessage, setThinkingHeaderMessage, uniqueChatId, initValue, sessionId, fieldNumber, setFieldNumber, additionalArgs, setActiveConversationId, navSessionId, setNavSessionId);
|
|
11860
12106
|
const { parseSavedFlow, saveCurrentChanges, endCurrentSession, clearChatSession, initiateNewChat, hasUnsavedChanges, } = useChatSession(chatDataRef, setFlowType, setScreenName, setUserInput, setTemplateData, chatDataScreenLinkRef, setShowModal, setMinimizedMode, setSelectedModule, setChatDataState, currentMode, setUserFlow, getCurrentDateTimeString, setCurrentAppLink, selectedModule, fetchUserResultsFromQuery, props.closeBot, activeConversationId, setActiveConversationId, setShowChatPlaceholder);
|
|
@@ -11887,6 +12133,10 @@ const SmartBot = (props) => {
|
|
|
11887
12133
|
setFieldNumber,
|
|
11888
12134
|
setAdditionalArgs,
|
|
11889
12135
|
});
|
|
12136
|
+
// Keep activeConversationIdRef in sync so event handlers with [] deps can access the latest value
|
|
12137
|
+
useEffect(() => {
|
|
12138
|
+
activeConversationIdRef.current = activeConversationId;
|
|
12139
|
+
}, [activeConversationId]);
|
|
11890
12140
|
// Show/hide stop icon when step-form restream (second init API from ButtonContent) starts/ends.
|
|
11891
12141
|
// Must live here (SmartBot) because StreamedContent unmounts after the first stream completes.
|
|
11892
12142
|
useEffect(() => {
|
|
@@ -11908,6 +12158,23 @@ const SmartBot = (props) => {
|
|
|
11908
12158
|
};
|
|
11909
12159
|
const handleStepFormStreamEnd = () => {
|
|
11910
12160
|
setIsStop(false);
|
|
12161
|
+
// Update the timestamp on the last bot message to reflect when the restream completed
|
|
12162
|
+
try {
|
|
12163
|
+
const mode = localStorage.getItem("currentModeData") || "agent";
|
|
12164
|
+
const convId = activeConversationIdRef.current;
|
|
12165
|
+
const messages = chatDataInfoRef?.current?.[mode]?.conversations?.[convId]?.messages;
|
|
12166
|
+
if (messages && messages.length > 0) {
|
|
12167
|
+
const lastBotIdx = messages.reduce((lastIdx, msg, idx) => msg.userType === "bot" ? idx : lastIdx, -1);
|
|
12168
|
+
if (lastBotIdx !== -1) {
|
|
12169
|
+
messages[lastBotIdx].timeStamp = moment().format(dateFormat);
|
|
12170
|
+
// Trigger re-render so the UI reflects the updated timestamp
|
|
12171
|
+
setChatDataState((prev) => ({ ...prev }));
|
|
12172
|
+
}
|
|
12173
|
+
}
|
|
12174
|
+
}
|
|
12175
|
+
catch (e) {
|
|
12176
|
+
console.error("Error updating timestamp after step form stream:", e);
|
|
12177
|
+
}
|
|
11911
12178
|
};
|
|
11912
12179
|
window.addEventListener("stepFormStreamStart", handleStepFormStreamStart);
|
|
11913
12180
|
window.addEventListener("stepFormStreamEnd", handleStepFormStreamEnd);
|
|
@@ -12314,6 +12581,7 @@ const SmartBot = (props) => {
|
|
|
12314
12581
|
baseUrl: baseUrl,
|
|
12315
12582
|
userExplicitInput: userExplicitInput,
|
|
12316
12583
|
textWithColumnNames: textWithColumnNames,
|
|
12584
|
+
answerMode: answerMode,
|
|
12317
12585
|
};
|
|
12318
12586
|
// if(!isEmpty(userInput)) {
|
|
12319
12587
|
dispatch(setThinkingContext({
|
|
@@ -12344,6 +12612,9 @@ const SmartBot = (props) => {
|
|
|
12344
12612
|
};
|
|
12345
12613
|
const onSendIconClick = (params, params2) => {
|
|
12346
12614
|
try {
|
|
12615
|
+
// Reset step form stream state so old TabularContent instances don't process new data
|
|
12616
|
+
dispatch(setStepFormStreamData(null));
|
|
12617
|
+
resetActiveTabularInstance();
|
|
12347
12618
|
// dispatch(setChatbotContext({}));
|
|
12348
12619
|
setUserInput(params?.text);
|
|
12349
12620
|
handleSendMessage(params?.text, params?.userExplicitInput, params?.textWithColumnNames);
|
|
@@ -12493,7 +12764,9 @@ const SmartBot = (props) => {
|
|
|
12493
12764
|
}
|
|
12494
12765
|
fetchConversations(null, "agent");
|
|
12495
12766
|
}, [renameConversation, deleteConversation, fetchConversations]);
|
|
12496
|
-
return (jsxs("div", { className: `${classes.agentStyleOverride} ${partialClose ? classes.hideBotStyle : ""} `, children: [jsx(MemoryModal, { isModalOpen: isModalOpen, setIsModalOpen: setIsModalOpen, displaySnackMessages: displaySnackMessages }), jsx(UploadModal, { isUploadModalOpen: isUploadModalOpen, setIsUploadModalOpen: setIsUploadModalOpen, displaySnackMessages: displaySnackMessages }), jsx(ChatBotComponent, { isFullWidth: forceOpen, userName: userName, showHistoryPanel: false, customInputComponent: currentMode === "agent" && !showSavedFilters ? (jsx(ChatbotInput, { newChatScreen: newChatScreen, inputValue: userInput, setInputValue: setUserInput, isStopIcon: isStop, onSendIconClick: onSendIconClick, onStopIconClick: onStopIconClick, currentMode: currentMode, filterOptions: filterOptions,
|
|
12767
|
+
return (jsxs("div", { className: `${classes.agentStyleOverride} ${partialClose ? classes.hideBotStyle : ""} `, children: [jsx(MemoryModal, { isModalOpen: isModalOpen, setIsModalOpen: setIsModalOpen, displaySnackMessages: displaySnackMessages }), jsx(UploadModal, { isUploadModalOpen: isUploadModalOpen, setIsUploadModalOpen: setIsUploadModalOpen, displaySnackMessages: displaySnackMessages }), jsx(ChatBotComponent, { isFullWidth: forceOpen, userName: userName, showHistoryPanel: false, customInputComponent: currentMode === "agent" && !showSavedFilters ? (jsx(ChatbotInput, { newChatScreen: newChatScreen, inputValue: userInput, setInputValue: setUserInput, isStopIcon: isStop, onSendIconClick: onSendIconClick, onStopIconClick: onStopIconClick, currentMode: currentMode, filterOptions: filterOptions,
|
|
12768
|
+
// onSaveClick={saveCurrentChat}
|
|
12769
|
+
savedFilterSets: savedFilterSets, selectedFilterSet: selectedFilterSet, onFilterSetSelect: (filterSet) => setSelectedFilterSet(filterSet), onClearFilterSet: () => setSelectedFilterSet(null), onTriggerRefresh: triggerRefreshAction, answerMode: answerMode, setAnswerMode: setAnswerMode })) : showSavedFilters ? jsx(Fragment, {}) : null, isChatBotOpen: showModal || forceOpen, historyPanelData: historyPanelData, onHistorySearchChange: (params) => { console.log("History Search Change", params); }, onHistorySelectConversation: (params) => {
|
|
12497
12770
|
console.log("History Select Conversation", params);
|
|
12498
12771
|
setNewChatScreen(false);
|
|
12499
12772
|
setShowChatPlaceholder(false);
|
|
@@ -12510,6 +12783,8 @@ const SmartBot = (props) => {
|
|
|
12510
12783
|
localStorage.setItem("isStreaming", "false");
|
|
12511
12784
|
dispatch(setChatbotContext({}));
|
|
12512
12785
|
dispatch(clearPersistedFormValues());
|
|
12786
|
+
dispatch(setStepFormStreamData(null));
|
|
12787
|
+
resetActiveTabularInstance();
|
|
12513
12788
|
setConversation([]);
|
|
12514
12789
|
chatDataInfoRef.current[currentMode] = {
|
|
12515
12790
|
conversations: {},
|
|
@@ -12700,9 +12975,9 @@ const SmartBot = (props) => {
|
|
|
12700
12975
|
icon: jsx(SvgSaveFilterTab, {}),
|
|
12701
12976
|
},
|
|
12702
12977
|
], utilityList: utilityList, isAssistantThinking: false, isCustomScreen: showChatPlaceholder ? showChatPlaceholder : showSavedFilters, customScreenJsx: showChatPlaceholder ?
|
|
12703
|
-
jsx(ChatPlaceholder, { dateFormat: dateFormat, chatDataRef: chatDataRef, currentMode: currentMode, setShowChatPlaceholder: setShowChatPlaceholder, setLoader: setLoader, setCurrentAgentId: setCurrentAgentId, baseUrl: baseUrl, setBaseUrl: setBaseUrl, setCurrentSessionId: setCurrentSessionId, customChatConfig: customChatConfig, chatDataInfoRef: chatDataInfoRef, setChatDataState: setChatDataState, userInput: userInput, legacyAgentScreen: legacyAgentScreen, activeConversationId: activeConversationId, chatBodyRef: chatBodyRef, chatbotContext: chatbotContext, setInitValue: setInitValue, setSessionId: setSessionId, thinkingContent: thinkingContext?.thinkingContent, setThinkingContent: setThinkingContent, isThinking: isThinking, setIsThinking: setIsThinking, chatId: chatId, setChatId: setChatId, isStop: isStop, setIsStop: setIsStop, functionsRef: functionsRef, functionsState: functionsState, setFunctionsState: setFunctionsState, thinkingHeaderMessage: thinkingContext?.thinkingHeaderMessage, setThinkingHeaderMessage: setThinkingHeaderMessage, uniqueChatId: uniqueChatId, setUniqueChatId: setUniqueChatId, fieldNumber: fieldNumber, setFieldNumber: setFieldNumber, setAdditionalArgs: setAdditionalArgs, displayQuestions: displayQuestions, questions: questions, setActiveConversationId: setActiveConversationId })
|
|
12978
|
+
jsx(ChatPlaceholder, { dateFormat: dateFormat, chatDataRef: chatDataRef, currentMode: currentMode, setShowChatPlaceholder: setShowChatPlaceholder, setLoader: setLoader, setCurrentAgentId: setCurrentAgentId, baseUrl: baseUrl, setBaseUrl: setBaseUrl, setCurrentSessionId: setCurrentSessionId, customChatConfig: customChatConfig, chatDataInfoRef: chatDataInfoRef, setChatDataState: setChatDataState, userInput: userInput, legacyAgentScreen: legacyAgentScreen, activeConversationId: activeConversationId, chatBodyRef: chatBodyRef, chatbotContext: chatbotContext, setInitValue: setInitValue, setSessionId: setSessionId, thinkingContent: thinkingContext?.thinkingContent, setThinkingContent: setThinkingContent, isThinking: isThinking, setIsThinking: setIsThinking, chatId: chatId, setChatId: setChatId, isStop: isStop, setIsStop: setIsStop, functionsRef: functionsRef, functionsState: functionsState, setFunctionsState: setFunctionsState, thinkingHeaderMessage: thinkingContext?.thinkingHeaderMessage, setThinkingHeaderMessage: setThinkingHeaderMessage, uniqueChatId: uniqueChatId, setUniqueChatId: setUniqueChatId, fieldNumber: fieldNumber, setFieldNumber: setFieldNumber, setAdditionalArgs: setAdditionalArgs, displayQuestions: displayQuestions, questions: questions, setActiveConversationId: setActiveConversationId, selectedFilterSet: selectedFilterSet, answerMode: answerMode })
|
|
12704
12979
|
:
|
|
12705
|
-
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
12980
|
+
jsx(ChatbotSaveFilterComponent$1, { savedFilterSets: savedFilterSets, partialClose: partialClose, chatBotWidth: chatBotWidth }), inputText: userInput, threadList: ["Home"], hideMenuArrow: hideMenu, newChatScreen: newChatScreen, isModuleListLoading: modulesLoading, suggestionBanner: {
|
|
12706
12981
|
freeTextHeading: "Try adding more details :",
|
|
12707
12982
|
freeTextContent: "Alan works better when you provide more context and pointed questions",
|
|
12708
12983
|
}, isStopIcon: isStop, onStopIconClick: onStopIconClick, footerText: "AI-generated responses may contain errors\u2014please verify important information", showSuggestionBanner: showSavedFilters ? false : showSuggestionBanner, onCloseSuggestionBanner: () => {
|
|
@@ -12722,7 +12997,9 @@ const SmartBot = (props) => {
|
|
|
12722
12997
|
}, handleSaveChat: () => {
|
|
12723
12998
|
// Handle save chat logic here
|
|
12724
12999
|
saveCurrentChat();
|
|
12725
|
-
}
|
|
13000
|
+
}, onChatBotResize: (params) => {
|
|
13001
|
+
setChatBotWidth(params);
|
|
13002
|
+
}, onMinimiseChatBot: null })] }));
|
|
12726
13003
|
};
|
|
12727
13004
|
|
|
12728
13005
|
export { SmartBot as default };
|