impact-chatbot 2.3.88 → 2.3.89

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/index.esm.js CHANGED
@@ -542,6 +542,26 @@ const parseResponse = (data, type, agentId = "", currentMode = "", disableTimeAn
542
542
  paramName: data?.data?.param_name
543
543
  }
544
544
  };
545
+ case "checkboxGroup":
546
+ return {
547
+ ...data,
548
+ timeStamp: timeString,
549
+ userType: "bot",
550
+ userName: userName,
551
+ headerTitle: data?.data?.label || "",
552
+ bodyType: "checkboxGroup",
553
+ bodyText: {
554
+ label: data?.data?.label,
555
+ orientation: data?.data?.orientation,
556
+ options: data?.data?.options,
557
+ defaultSelected: data?.data?.defaultSelected,
558
+ minOptions: data?.data?.minOptions,
559
+ maxOptions: data?.data?.maxOptions,
560
+ isRequired: data?.data?.isRequired,
561
+ isDisabled: data?.data?.isDisabled,
562
+ paramName: data?.data?.param_name
563
+ }
564
+ };
545
565
  case "button":
546
566
  return {
547
567
  ...data,
@@ -7447,6 +7467,61 @@ const CheckboxContent = ({ bodyText, isFormDisabled = false, messageIndex }) =>
7447
7467
  return (jsx("div", { style: { width: '100%', marginTop: '10px' }, children: jsx(Checkbox, { label: label, checked: checked, required: required, disabled: disabled || isFormDisabled, onChange: (e) => handleChange(e), variant: "default" }) }));
7448
7468
  };
7449
7469
 
7470
+ const CheckboxGroupContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
7471
+ const formKey = `${messageIndex}_${bodyText?.paramName}`;
7472
+ const classes = useStyles$a();
7473
+ const { label, orientation, options = [], defaultSelected, minOptions, maxOptions, isRequired, isDisabled, } = bodyText || {};
7474
+ const min = minOptions ?? 1;
7475
+ const max = maxOptions ?? options.length;
7476
+ const chatbotContext = useSelector((state) => state.smartBotReducer.chatbotContext);
7477
+ const chatbotContextRef = useRef(chatbotContext);
7478
+ chatbotContextRef.current = chatbotContext;
7479
+ const persistedFormValues = useSelector((state) => state.smartBotReducer.persistedFormValues);
7480
+ const dispatch = useDispatch();
7481
+ const [selected, setSelected] = useState(() => {
7482
+ const persisted = persistedFormValues?.[formKey];
7483
+ if (Array.isArray(persisted))
7484
+ return persisted;
7485
+ return Array.isArray(defaultSelected) ? defaultSelected : [];
7486
+ });
7487
+ if (isEmpty$1(bodyText))
7488
+ return null;
7489
+ const groupDisabled = isDisabled || isFormDisabled;
7490
+ const dispatchSelection = (newValues) => {
7491
+ const latestContext = chatbotContextRef.current;
7492
+ dispatch(setChatbotContext({
7493
+ ...latestContext,
7494
+ [bodyText?.paramName]: {
7495
+ ...latestContext?.[bodyText?.paramName],
7496
+ [bodyText?.paramName]: newValues,
7497
+ updated: true,
7498
+ },
7499
+ }));
7500
+ dispatch(setPersistedFormValues({ [formKey]: newValues }));
7501
+ };
7502
+ const handleChange = (optionValue, isChecked) => {
7503
+ try {
7504
+ const newValues = isChecked
7505
+ ? [...selected, optionValue]
7506
+ : selected.filter((val) => val !== optionValue);
7507
+ setSelected(newValues);
7508
+ dispatchSelection(newValues);
7509
+ }
7510
+ catch (error) {
7511
+ console.error("Error in checkboxGroup handleChange", error);
7512
+ }
7513
+ };
7514
+ const isRow = orientation === "row";
7515
+ const overMax = selected.length > max;
7516
+ const belowMin = isRequired && selected.length < min;
7517
+ return (jsxs("div", { style: { width: "100%", marginTop: "10px" }, children: [label && (jsxs("p", { className: classes.radioGrpLabel, children: [label, isRequired ? " *" : ""] })), jsx("div", { style: {
7518
+ display: "flex",
7519
+ flexDirection: isRow ? "row" : "column",
7520
+ flexWrap: isRow ? "wrap" : "nowrap",
7521
+ gap: isRow ? "16px" : "8px",
7522
+ }, children: options.map((option) => (jsx(Checkbox, { label: option.label, checked: selected.includes(option.value), disabled: option.disabled || groupDisabled, onChange: (e) => handleChange(option.value, e?.currentTarget?.checked), variant: "default" }, option.value))) }), overMax && (jsx("p", { className: classes.radioGrpLabel, style: { margin: "8px 0 0 0", color: "red" }, children: `Select at most ${max} option${max > 1 ? "s" : ""}` })), !overMax && belowMin && (jsx("p", { className: classes.radioGrpLabel, style: { margin: "8px 0 0 0", color: "red" }, children: `Select at least ${min} option${min > 1 ? "s" : ""}` }))] }));
7523
+ };
7524
+
7450
7525
  const RadioContent = ({ bodyText, isFormDisabled = false, messageIndex }) => {
7451
7526
  const formKey = `${messageIndex}_${bodyText?.paramName}`;
7452
7527
  const classes = useStyles$a();
@@ -7730,6 +7805,38 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
7730
7805
  return false;
7731
7806
  });
7732
7807
  }, [formData, chatbotContext, persistedFormValues, messageIndex]);
7808
+ // Validate checkboxGroup fields against their minOptions/maxOptions bounds.
7809
+ // A required group must have selectedCount within [min, max]; any group (even
7810
+ // non-required) must not exceed max. Blocks submit when out of bounds.
7811
+ const checkboxGroupsValid = useMemo(() => {
7812
+ if (!formData || !Array.isArray(formData))
7813
+ return true;
7814
+ const groups = formData.filter((item) => item?.type === "checkboxGroup");
7815
+ return groups.every((item) => {
7816
+ const data = item.data || {};
7817
+ const param = data.param_name;
7818
+ const options = data.options || [];
7819
+ const min = data.minOptions ?? 1;
7820
+ const max = data.maxOptions ?? options.length;
7821
+ // Resolve current selection: chatbotContext first, then persistedFormValues
7822
+ let selectedValues = [];
7823
+ const ctx = chatbotContext?.[param];
7824
+ if (ctx && ctx.updated && Array.isArray(ctx[param])) {
7825
+ selectedValues = ctx[param];
7826
+ }
7827
+ else {
7828
+ const persisted = persistedFormValues?.[`${messageIndex}_${param}`];
7829
+ if (Array.isArray(persisted))
7830
+ selectedValues = persisted;
7831
+ }
7832
+ const count = selectedValues.length;
7833
+ if (count > max)
7834
+ return false;
7835
+ if (data.isRequired && count < min)
7836
+ return false;
7837
+ return true;
7838
+ });
7839
+ }, [formData, chatbotContext, persistedFormValues, messageIndex]);
7733
7840
  // Extract select-type filter configs from formData for cross-filter cascading
7734
7841
  // and sort them based on the filters_hierarchy_order from tenant config
7735
7842
  const crossFilterConfigs = useMemo(() => {
@@ -7838,10 +7945,12 @@ const StepFormContent = ({ formData, messageIndex = 0, isFormDisabled = false, s
7838
7945
  return jsx(DateRangePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: formFieldsDisabled, messageIndex: messageIndex }, key);
7839
7946
  case "checkbox":
7840
7947
  return jsx(CheckboxContent, { bodyText: parsedData.bodyText, isFormDisabled: formFieldsDisabled, messageIndex: messageIndex }, key);
7948
+ case "checkboxGroup":
7949
+ return jsx(CheckboxGroupContent, { bodyText: parsedData.bodyText, isFormDisabled: formFieldsDisabled, messageIndex: messageIndex }, key);
7841
7950
  case "radio":
7842
7951
  return jsx(RadioContent, { bodyText: parsedData.bodyText, isFormDisabled: formFieldsDisabled, messageIndex: messageIndex }, key);
7843
7952
  case "button":
7844
- return jsx(ButtonContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled || isFormSubmitted || isTimedOut, isStepFormSubmit: true, isFormValid: requiredFieldsFilled, formParamNames: formParamNames, messageIndex: messageIndex }, key);
7953
+ return jsx(ButtonContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled || isFormSubmitted || isTimedOut, isStepFormSubmit: true, isFormValid: requiredFieldsFilled && checkboxGroupsValid, formParamNames: formParamNames, messageIndex: messageIndex }, key);
7845
7954
  case "input":
7846
7955
  return jsx(InputContent, { bodyText: parsedData.bodyText, isFormDisabled: formFieldsDisabled, messageIndex: messageIndex }, key);
7847
7956
  case "image":
@@ -8237,7 +8346,7 @@ const getQuestionStatus$1 = (questionSteps) => {
8237
8346
  /**
8238
8347
  * Renders a single progress bar item (main point + sub-items)
8239
8348
  */
8240
- const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, preSelectedFilters = null, isFormDisabled, onAllSubItemsAnimated = undefined, botProps = null, currentMode = "", agentId = "", sessionId = "" }) => {
8349
+ const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData, showSavedFilters = true, preSelectedFilters = null, isFormDisabled, onAllSubItemsAnimated = undefined, botProps = null, currentMode = "", agentId = "", sessionId = "", index = 0, chatSessionId = "" }) => {
8241
8350
  const status = getQuestionStatus$1(questionSteps);
8242
8351
  const animatedCountRef = useRef(0);
8243
8352
  const [isExpanded, setIsExpanded] = useState(true);
@@ -8271,9 +8380,9 @@ const ProgressBarItem$1 = ({ question, questionSteps, isLast, classes, formData,
8271
8380
  if (animatedCountRef.current >= arr.length && onAllSubItemsAnimated) {
8272
8381
  onAllSubItemsAnimated();
8273
8382
  }
8274
- } }) }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, botProps: botProps, currentMode: currentMode, agentId: agentId, sessionId: sessionId }) }))] })] }));
8383
+ } }) }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, botProps: botProps, currentMode: currentMode, agentId: agentId, sessionId: sessionId, messageIndex: `${String(chatSessionId)}_${index}` }) }))] })] }));
8275
8384
  };
8276
- const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, setFinalStepDone, stepChange, currentMode, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, botProps = null, agentId = "", sessionId = "", }) => {
8385
+ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, setFinalStepDone, stepChange, currentMode, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, botProps = null, agentId = "", sessionId = "", chatSessionId = "", }) => {
8277
8386
  const classes = useStyles$4();
8278
8387
  useState(false);
8279
8388
  const [showThinking, setShowThinking] = useState(false);
@@ -8356,7 +8465,7 @@ const Steps$1 = ({ steps, setSteps, done, setTabValue, setDone, finalStepDone, s
8356
8465
  const showSavedFilters = formEntry && !Array.isArray(formEntry) ? formEntry.showSavedFilters : true;
8357
8466
  const preSelectedFilters = formEntry && !Array.isArray(formEntry) ? formEntry.preSelectedFilters : null;
8358
8467
  const isLast = index === questions.length - 1;
8359
- return (jsx(ProgressBarItem$1, { question: question, questionSteps: questionSteps, isLast: isLast && !showThinking, classes: classes, formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, botProps: botProps, currentMode: currentMode, agentId: agentId, sessionId: sessionId, onAllSubItemsAnimated: isLast && lastQuestionCompleted && !done
8468
+ return (jsx(ProgressBarItem$1, { question: question, questionSteps: questionSteps, isLast: isLast && !showThinking, classes: classes, formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, botProps: botProps, currentMode: currentMode, agentId: agentId, sessionId: sessionId, index: index, chatSessionId: chatSessionId, onAllSubItemsAnimated: isLast && lastQuestionCompleted && !done
8360
8469
  ? () => setShowThinking(true)
8361
8470
  : undefined }, index));
8362
8471
  }), showThinking && !done && (jsx("div", { style: {
@@ -8384,6 +8493,8 @@ const renderWidgetItem = (item, index, isFormDisabled) => {
8384
8493
  return jsx(RadioContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8385
8494
  case "checkbox":
8386
8495
  return jsx(CheckboxContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8496
+ case "checkboxGroup":
8497
+ return jsx(CheckboxGroupContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8387
8498
  case "select":
8388
8499
  return jsx(SelectContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled }, key);
8389
8500
  case "slider":
@@ -8418,7 +8529,7 @@ const AgentResponse$1 = (props) => {
8418
8529
  };
8419
8530
 
8420
8531
  const StepsResponseTab = (props) => {
8421
- const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, isRetrying, botProps, agentId, sessionId, } = props;
8532
+ const { steps, setSteps, stepsDone, setStepsDone, finalStepDone, setFinalStepDone, content, isStreaming, stepChange, currentMode, questions, questionsStepsMap, stepFormDataMap, isFormDisabled, streamingWidgetData, isRetrying, botProps, agentId, sessionId, chatSessionId, } = props;
8422
8533
  const dispatch = useDispatch();
8423
8534
  const thinkingContext = useSelector((state) => state.smartBotReducer.thinkingContext);
8424
8535
  const streamStartTimeRef = useRef(thinkingContext?.streamStartTime);
@@ -8482,7 +8593,7 @@ const StepsResponseTab = (props) => {
8482
8593
  icon: jsx(PsychologyOutlinedIcon, { fontSize: "large" }),
8483
8594
  },
8484
8595
  ], tabPanels: [
8485
- jsx(Steps$1, { steps: steps, setSteps: setSteps, done: stepsDone, setDone: setStepsDone, setTabValue: setTabValue, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, stepChange: stepChange, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: isFormDisabled || isTimedOut, botProps: botProps, agentId: agentId, sessionId: sessionId }),
8596
+ jsx(Steps$1, { steps: steps, setSteps: setSteps, done: stepsDone, setDone: setStepsDone, setTabValue: setTabValue, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, stepChange: stepChange, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: isFormDisabled || isTimedOut, botProps: botProps, agentId: agentId, sessionId: sessionId, chatSessionId: chatSessionId }),
8486
8597
  jsxs(Fragment, { children: [jsx(AgentResponse$1, { content: content, isStreaming: isStreaming, streamingWidgetData: streamingWidgetData, isFormDisabled: isFormDisabled || isTimedOut }), timeoutMessage && (jsx("div", { style: { marginTop: "8px", padding: "0 8px" }, children: jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
8487
8598
  ], value: tabValue }) }));
8488
8599
  };
@@ -10054,7 +10165,7 @@ const StreamedContent = ({ botData, botProps }) => {
10054
10165
  * @returns {JSX.Element} Rendered content with optional blinking cursor
10055
10166
  */
10056
10167
  const renderContent = () => {
10057
- return (jsxs("div", { className: classes.streamContainer, children: [jsx(StepsResponseTab, { steps: steps, stepChange: stepChange, setSteps: setSteps, stepsDone: stepsDone, setStepsDone: setStepsDone, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, content: content, isStreaming: isStreaming, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: botData?.isFormDisabled || false, streamingWidgetData: streamingWidgetData, isRetrying: isRetrying, botProps: botProps, agentId: botData?.inputBody?.agent_id || "", sessionId: messageToStoreRef.current?.sessionId || "" }), isRetrying && (jsx("div", { className: classes.retryContainer, children: jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) }))] }));
10168
+ return (jsxs("div", { className: classes.streamContainer, children: [jsx(StepsResponseTab, { steps: steps, stepChange: stepChange, setSteps: setSteps, stepsDone: stepsDone, setStepsDone: setStepsDone, finalStepDone: finalStepDone, setFinalStepDone: setFinalStepDone, content: content, isStreaming: isStreaming, currentMode: currentMode, questions: questions, questionsStepsMap: questionsStepsMap, stepFormDataMap: stepFormDataMap, isFormDisabled: botData?.isFormDisabled || false, streamingWidgetData: streamingWidgetData, isRetrying: isRetrying, botProps: botProps, agentId: botData?.inputBody?.agent_id || "", sessionId: messageToStoreRef.current?.sessionId || "", chatSessionId: messageToStoreRef.current?.chatSessionId || botData?.chatSessionId || "" }), isRetrying && (jsx("div", { className: classes.retryContainer, children: jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) }))] }));
10058
10169
  };
10059
10170
  if (currentMode === "agent") {
10060
10171
  return renderContent();
@@ -10250,7 +10361,7 @@ const getQuestionStatus = (questionSteps) => {
10250
10361
  /**
10251
10362
  * Renders a single progress bar item (main point + sub-items)
10252
10363
  */
10253
- const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, isFormDisabled, isRestreaming = false, showSavedFilters = true, preSelectedFilters = null }) => {
10364
+ const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, isFormDisabled, isRestreaming = false, showSavedFilters = true, preSelectedFilters = null, sessionId = "", index = 0, chatSessionId = "" }) => {
10254
10365
  const baseStatus = getQuestionStatus(questionSteps);
10255
10366
  // When restreaming and this is the last item, show as in-progress
10256
10367
  const status = (isRestreaming && isLast) ? "in-progress" : baseStatus;
@@ -10280,9 +10391,9 @@ const ProgressBarItem = ({ question, questionSteps, isLast, classes, formData, i
10280
10391
  setIsExpanded(true);
10281
10392
  }
10282
10393
  }, [status, formData]);
10283
- return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Working on the next step..."] })), hasSubItems && isExpanded && !isProcessingRequest && (jsx("div", { className: classes.progressSubItems, style: { maxHeight: isExpanded ? "500px" : "0", opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsx("div", { className: classes.progressSubItem, children: jsx(SubStepRenderer, { text: `${step.header}${step.sub_header ? ` - ${step.sub_header}` : ""}` }) }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters }) }))] })] }));
10394
+ return (jsxs("div", { className: classes.progressItem, children: [jsxs("div", { className: classes.progressTrack, children: [jsx("div", { className: `${classes.progressDot} ${dotClass}` }), !isLast && jsx("div", { className: `${classes.progressLine} ${lineClass}` })] }), jsxs("div", { className: classes.progressContent, children: [jsxs("div", { className: classes.progressHeader, onClick: handleToggle, children: [jsx("span", { className: `${classes.progressHeaderText} ${textClass}`, children: question }), hasSubItems && (jsx(ChevronRightIcon$1, { className: `${classes.progressChevron} ${textClass} ${isExpanded ? "expanded" : ""}` }))] }), hasSubItems && isExpanded && status === "in-progress" && (jsxs("div", { className: classes.reasoningLabel, children: [jsx(SvgReasoningIcon, {}), "Working on the next step..."] })), hasSubItems && isExpanded && !isProcessingRequest && (jsx("div", { className: classes.progressSubItems, style: { maxHeight: isExpanded ? "500px" : "0", opacity: isExpanded ? 1 : 0 }, children: questionSteps.map((step, idx) => (jsx("div", { className: classes.progressSubItem, children: jsx(SubStepRenderer, { text: `${step.header}${step.sub_header ? ` - ${step.sub_header}` : ""}` }) }, idx))) })), formData && isExpanded && (jsx("div", { className: classes.stepFormContainer, children: jsx(StepFormContent, { formData: formData, isFormDisabled: isFormDisabled, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, messageIndex: `${String(chatSessionId)}_${index}` }) }))] })] }));
10284
10395
  };
10285
- const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, activeFormIntent = null, isRestreaming = false }) => {
10396
+ const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap = {}, isFormDisabled = false, activeFormIntent = null, isRestreaming = false, sessionId = "", chatSessionId = "" }) => {
10286
10397
  const classes = useStyles$3();
10287
10398
  useState(false);
10288
10399
  const hasQuestions = questions.length > 0;
@@ -10311,7 +10422,7 @@ const Steps = ({ steps, questions = [], questionsStepsMap = {}, stepFormDataMap
10311
10422
  const formDisabledForThis = activeFormIntent
10312
10423
  ? question !== activeFormIntent
10313
10424
  : isFormDisabled;
10314
- return (jsx(ProgressBarItem, { question: question, questionSteps: questionSteps, isLast: index === questions.length - 1, classes: classes, formData: formData, isFormDisabled: formDisabledForThis, isRestreaming: isRestreaming, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters }, index));
10425
+ return (jsx(ProgressBarItem, { question: question, questionSteps: questionSteps, isLast: index === questions.length - 1, classes: classes, formData: formData, isFormDisabled: formDisabledForThis, isRestreaming: isRestreaming, showSavedFilters: showSavedFilters, preSelectedFilters: preSelectedFilters, sessionId: sessionId, index: index, chatSessionId: chatSessionId }, index));
10315
10426
  }) }));
10316
10427
  };
10317
10428
 
@@ -10324,7 +10435,7 @@ const AgentResponse = ({ children }) => {
10324
10435
  // Only the active instance should process stepFormStreamData from Redux.
10325
10436
  let instanceCounter = 0;
10326
10437
  let activeTabularInstanceId = null;
10327
- const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "", botProps = null, currentMode = "", agentId = "" }) => {
10438
+ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questions: initialQuestions = [], questionsStepsMap: initialQuestionsStepsMap = {}, stepFormDataMap: initialStepFormDataMap = {}, isFormDisabled = false, sessionId: propSessionId = "", chatSessionId = "", botProps = null, currentMode = "", agentId = "" }) => {
10328
10439
  const dispatch = useDispatch();
10329
10440
  const stepFormStreamData = useSelector((state) => state.smartBotReducer.stepFormStreamData);
10330
10441
  const thinkingContext = useSelector((state) => state.smartBotReducer.thinkingContext);
@@ -10805,7 +10916,7 @@ const TabularContent = ({ steps: initialSteps, currentTabValue, children, questi
10805
10916
  icon: jsx(PsychologyOutlinedIcon, { fontSize: "large" }),
10806
10917
  },
10807
10918
  ], tabPanels: [
10808
- jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted || isTimedOut, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming }),
10919
+ jsx(Steps, { steps: stepsState, questions: questionsState, questionsStepsMap: questionsStepsMapState, stepFormDataMap: stepFormDataMapState, isFormDisabled: (isFormDisabled && !isRestreaming) || stepFormSubmitted || isTimedOut, activeFormIntent: hasNewStepFormFromRestream ? activeFormIntent : null, isRestreaming: isRestreaming, sessionId: propSessionId, chatSessionId: chatSessionId, agentId: agentId }),
10809
10920
  jsxs(AgentResponse, { children: [children, renderedWidgets.length > 0 && (jsx("div", { className: "restream-widget-content", children: renderedWidgets })), retryCountdown > 0 && (jsx("div", { style: { marginTop: "8px" }, children: jsx(TextRenderer, { text: `Auto re-trying in ${retryCountdown}s`, thinking: "" }) })), timeoutMessage && (jsx("div", { style: { marginTop: "8px" }, children: jsx(TextRenderer, { text: timeoutMessage, thinking: "" }) }))] }),
10810
10921
  ], value: tabValue }) }));
10811
10922
  };
@@ -10848,6 +10959,8 @@ const CombinedContent = ({ botData, props }) => {
10848
10959
  return jsx(DateRangePickerContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled, messageIndex: botData.messageIndex }, key);
10849
10960
  case "checkbox":
10850
10961
  return jsx(CheckboxContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled, messageIndex: botData.messageIndex }, key);
10962
+ case "checkboxGroup":
10963
+ return jsx(CheckboxGroupContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled, messageIndex: botData.messageIndex }, key);
10851
10964
  case "radio":
10852
10965
  return jsx(RadioContent, { bodyText: parsedData.bodyText, isFormDisabled: isFormDisabled, messageIndex: botData.messageIndex }, key);
10853
10966
  case "button":
@@ -10883,7 +10996,7 @@ const CombinedContent = ({ botData, props }) => {
10883
10996
  const validContent = renderedContent.filter(content => content !== null);
10884
10997
  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" })) }));
10885
10998
  if (isTabEnabled) {
10886
- 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 || "", botProps: props, currentMode: botData?.currentMode || "", agentId: botData?.agentId || "", children: renderCombinedContent() }));
10999
+ 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 || "", chatSessionId: botData?.chatSessionId || "", botProps: props, currentMode: botData?.currentMode || "", agentId: botData?.agentId || "", children: renderCombinedContent() }));
10887
11000
  }
10888
11001
  return renderCombinedContent();
10889
11002
  };
@@ -10946,6 +11059,8 @@ const BotMessage = ({ botData, state, handleLikeDislike, props }) => {
10946
11059
  return jsx(DateRangePickerContent, { bodyText: botData.bodyText, isFormDisabled: botData.isFormDisabled, messageIndex: botData.messageIndex });
10947
11060
  case "checkbox":
10948
11061
  return jsx(CheckboxContent, { bodyText: botData.bodyText, isFormDisabled: botData.isFormDisabled, messageIndex: botData.messageIndex });
11062
+ case "checkboxGroup":
11063
+ return jsx(CheckboxGroupContent, { bodyText: botData.bodyText, isFormDisabled: botData.isFormDisabled, messageIndex: botData.messageIndex });
10949
11064
  case "radio":
10950
11065
  return jsx(RadioContent, { bodyText: botData.bodyText, isFormDisabled: botData.isFormDisabled, messageIndex: botData.messageIndex });
10951
11066
  case "button":
@@ -16081,10 +16196,50 @@ const SmartBot = (props) => {
16081
16196
  }
16082
16197
  fetchConversations(null, "agent");
16083
16198
  }, [renameConversation, deleteConversation, fetchConversations]);
16199
+ // Ref to the SmartBot wrapper so we can scope outside-click detection and the
16200
+ // collapse-button query to this (local) chatbot instance only.
16201
+ const smartBotWrapperRef = useRef(null);
16202
+ // Collapse the expanded/docked chatbot into the small draggable panel by
16203
+ // triggering impact-ui's header "Collapse chatbot" control. That button is
16204
+ // only present while expanded (its label becomes "Expand chatbot" once
16205
+ // collapsed), so this is a safe no-op when already collapsed.
16206
+ const collapseChatBotIfExpanded = useCallback(() => {
16207
+ const root = smartBotWrapperRef.current;
16208
+ if (!root)
16209
+ return;
16210
+ const collapseBtn = root.querySelector('button[aria-label="Collapse chatbot"]');
16211
+ if (collapseBtn)
16212
+ collapseBtn.click();
16213
+ }, []);
16214
+ // Auto-collapse to draggable mode when the user interacts outside the bot.
16215
+ useEffect(() => {
16216
+ const handleOutsideInteraction = (e) => {
16217
+ const root = smartBotWrapperRef.current;
16218
+ if (!root)
16219
+ return;
16220
+ if (root.contains(e.target))
16221
+ return; // interaction inside the bot → ignore
16222
+ collapseChatBotIfExpanded();
16223
+ };
16224
+ document.addEventListener("mousedown", handleOutsideInteraction, true);
16225
+ return () => {
16226
+ document.removeEventListener("mousedown", handleOutsideInteraction, true);
16227
+ };
16228
+ }, [collapseChatBotIfExpanded]);
16229
+ // Auto-collapse on route changes (skip the initial mount so freshly opening
16230
+ // the bot doesn't immediately collapse it).
16231
+ const hasMountedForCollapseRef = useRef(false);
16232
+ useEffect(() => {
16233
+ if (!hasMountedForCollapseRef.current) {
16234
+ hasMountedForCollapseRef.current = true;
16235
+ return;
16236
+ }
16237
+ collapseChatBotIfExpanded();
16238
+ }, [location.pathname, collapseChatBotIfExpanded]);
16084
16239
  return (jsxs(Fragment, { children: [partialClose && (minimizedStreamData?.isStreaming || minimizedStreamData?.stepStatus === "step_form") && (jsx(MinimizedChatWidget, { onExpand: () => {
16085
16240
  setShowModal(true);
16086
16241
  setPartialClose(false);
16087
- } })), 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,
16242
+ } })), jsxs("div", { ref: smartBotWrapperRef, 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,
16088
16243
  // onSaveClick={saveCurrentChat}
16089
16244
  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) => {
16090
16245
  console.log("History Select Conversation", params);