impact-chatbot 2.3.9 → 2.3.11

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.
@@ -18,7 +18,10 @@ export declare const buildFilterOptionsPayload: (filterConfig: any, existingFilt
18
18
  filter_type: string;
19
19
  dimension: any;
20
20
  display_type: any;
21
- check_configuration: any[];
21
+ check_configuration: {
22
+ checkAll: boolean;
23
+ meta: {};
24
+ }[];
22
25
  is_mandatory: any;
23
26
  extra: {};
24
27
  values: any;
@@ -35,7 +35,7 @@ export declare const findTextNodeAtPosition: (editorRef: any, position: any) =>
35
35
  * @param {boolean} isStage1 - Whether this is stage 1 (filter only) or stage 2 (with values)
36
36
  * @returns {HTMLSpanElement} Mention span element
37
37
  */
38
- export declare const createMentionSpan: (text: any, filterName: any, values: any, groupId: any, isStage1?: boolean) => HTMLSpanElement;
38
+ export declare const createMentionSpan: (text: any, filterName: any, values: any, groupId: any, isStage1?: boolean, checkAll?: boolean) => HTMLSpanElement;
39
39
  /**
40
40
  * Create +N count badge
41
41
  * @param {number} count - Hidden count
@@ -68,6 +68,7 @@ export declare const getAllMentions: (editorRef: any) => {
68
68
  filterName: any;
69
69
  stage: any;
70
70
  values: any;
71
+ checkAll: boolean;
71
72
  text: any;
72
73
  }[];
73
74
  /**
package/dist/index.cjs.js CHANGED
@@ -6426,12 +6426,11 @@ const StreamedContent = ({ botData }) => {
6426
6426
  sourceRef.current.close();
6427
6427
  setIsStreaming(false);
6428
6428
  setIsStreamingDone(true);
6429
- // Clean up stream state in module-level Map
6430
- const abortState = streamStateMap.get(streamKey);
6431
- if (abortState) {
6432
- abortState.completed = true;
6433
- abortState.source = null;
6434
- }
6429
+ // Delete module-level Map entry immediately on abort.
6430
+ // This ensures if the component unmounts before the isStreamingDone effect runs
6431
+ // (e.g. handleNewChatClick clears conversation), the next mount with the same
6432
+ // streamKey starts a fresh stream instead of restoring the aborted one.
6433
+ streamStateMap.delete(streamKey);
6435
6434
  // Stop the agent flow on the backend
6436
6435
  if (messageToStoreRef.current.sessionId) {
6437
6436
  chatbotServices.stopAgentFlow({ session_id: messageToStoreRef.current.sessionId }, baseUrl);
@@ -7911,10 +7910,10 @@ const buildFilterOptionsPayload = (filterConfig, existingFilters = [], filterOpt
7911
7910
  filter_type: "cascaded",
7912
7911
  dimension: fullFilterConfig?.dimension || "product",
7913
7912
  display_type: fullFilterConfig?.display_type || "dropdown",
7914
- check_configuration: [],
7913
+ check_configuration: mention.checkAll ? [{ checkAll: true, meta: {} }] : [],
7915
7914
  is_mandatory: fullFilterConfig?.is_mandatory || false,
7916
7915
  extra: {},
7917
- values: mention.values || [],
7916
+ values: mention.checkAll ? [] : (mention.values || []),
7918
7917
  attribute_name: attributeName,
7919
7918
  operator: "in",
7920
7919
  display_order: fullFilterConfig?.display_order || 0,
@@ -8064,7 +8063,7 @@ const findTextNodeAtPosition = (editorRef, position) => {
8064
8063
  * @param {boolean} isStage1 - Whether this is stage 1 (filter only) or stage 2 (with values)
8065
8064
  * @returns {HTMLSpanElement} Mention span element
8066
8065
  */
8067
- const createMentionSpan = (text, filterName, values, groupId, isStage1 = false) => {
8066
+ const createMentionSpan = (text, filterName, values, groupId, isStage1 = false, checkAll = false) => {
8068
8067
  const mentionSpan = document.createElement("span");
8069
8068
  mentionSpan.className = "mention-highlight";
8070
8069
  mentionSpan.contentEditable = "false";
@@ -8074,6 +8073,9 @@ const createMentionSpan = (text, filterName, values, groupId, isStage1 = false)
8074
8073
  if (values && values.length > 0) {
8075
8074
  mentionSpan.setAttribute("data-values", JSON.stringify(values));
8076
8075
  }
8076
+ if (checkAll) {
8077
+ mentionSpan.setAttribute("data-check-all", "true");
8078
+ }
8077
8079
  mentionSpan.textContent = text;
8078
8080
  return mentionSpan;
8079
8081
  };
@@ -8175,6 +8177,7 @@ const getAllMentions = (editorRef) => {
8175
8177
  filterName: span.getAttribute("data-filter-name"),
8176
8178
  stage: span.getAttribute("data-stage"),
8177
8179
  values: JSON.parse(span.getAttribute("data-values") || "[]"),
8180
+ checkAll: span.getAttribute("data-check-all") === "true",
8178
8181
  text: span.textContent,
8179
8182
  }));
8180
8183
  };
@@ -8220,13 +8223,10 @@ const formatMentionDisplay = (filterName, values, maxVisible = 3) => {
8220
8223
  return `@${filterName}::`;
8221
8224
  }
8222
8225
  const visibleValues = values.slice(0, maxVisible);
8223
- const hiddenCount = values.length - maxVisible;
8226
+ values.length - maxVisible;
8224
8227
  // Decode any special character codes for display purposes only.
8225
8228
  const displayVisibleValues = visibleValues.map((v) => replaceSpecialCharacter(String(v)));
8226
8229
  let display = `@${filterName}::${displayVisibleValues.join(",")}`;
8227
- if (hiddenCount > 0) {
8228
- display += `,+${hiddenCount}`;
8229
- }
8230
8230
  return display;
8231
8231
  };
8232
8232
  /**
@@ -8375,6 +8375,10 @@ const ChatbotInput = (props) => {
8375
8375
  const isInsertingMentionRef = React.useRef(false);
8376
8376
  const isTransitioningStageRef = React.useRef(false);
8377
8377
  const shouldClearCacheRef = React.useRef(false);
8378
+ const allFilterValuesRef = React.useRef([]);
8379
+ const windowStartRef = React.useRef(0);
8380
+ const INITIAL_DISPLAY_COUNT = 500;
8381
+ const LOAD_MORE_COUNT = 100;
8378
8382
  const chatbotContext = reactRedux.useSelector((state) => state.smartBotReducer.chatbotContext);
8379
8383
  // Date range picker state
8380
8384
  const [showDateRangePicker, setShowDateRangePicker] = React.useState(false);
@@ -8864,6 +8868,7 @@ const ChatbotInput = (props) => {
8864
8868
  filterConfig?.name ||
8865
8869
  mention.filterName,
8866
8870
  values: mention.values,
8871
+ checkAll: mention.checkAll || false,
8867
8872
  };
8868
8873
  });
8869
8874
  };
@@ -8937,7 +8942,16 @@ const ChatbotInput = (props) => {
8937
8942
  // Fetch values for Stage 2 (with existing filters for cascading)
8938
8943
  fetchFilterValues(filterConfig, existingFilters, filterOptions).then((valueOptions) => {
8939
8944
  setIsLoadingValues(false);
8940
- setCurrentOptions(valueOptions || []);
8945
+ const allValues = valueOptions || [];
8946
+ windowStartRef.current = 0;
8947
+ if (allValues.length > 2000) {
8948
+ allFilterValuesRef.current = allValues;
8949
+ setCurrentOptions(allValues.slice(0, INITIAL_DISPLAY_COUNT));
8950
+ }
8951
+ else {
8952
+ allFilterValuesRef.current = [];
8953
+ setCurrentOptions(allValues);
8954
+ }
8941
8955
  // Update dropdown position again after values are loaded (DOM might have shifted)
8942
8956
  if (mentionStartPos !== null) {
8943
8957
  updateDropdownPosition(mentionStartPos);
@@ -9030,6 +9044,7 @@ const ChatbotInput = (props) => {
9030
9044
  }
9031
9045
  // Determine if this filter is multi-select
9032
9046
  selectedFilter.isMulti !== false; // Default to true
9047
+ const isCheckAll = isAllSelected && allFilterValuesRef.current.length > 0;
9033
9048
  // Format mention text (decoded for display only)
9034
9049
  const mentionText = formatMentionDisplay(filterName, values, MAX_VISIBLE);
9035
9050
  // Create fragment
@@ -9037,12 +9052,15 @@ const ChatbotInput = (props) => {
9037
9052
  // Create mention span
9038
9053
  values.slice(0, MAX_VISIBLE);
9039
9054
  const hiddenValues = values.slice(MAX_VISIBLE);
9040
- const mentionSpan = createMentionSpan(mentionText, filterName, values, currentMentionGroupId, false // Stage 2
9041
- );
9055
+ const mentionSpan = createMentionSpan(mentionText, filterName, values, currentMentionGroupId, false, // Stage 2
9056
+ isCheckAll);
9042
9057
  fragment.appendChild(mentionSpan);
9043
9058
  // Add count badge if needed
9044
9059
  if (hiddenValues.length > 0) {
9045
- const countBadge = createCountBadge(hiddenValues.length, hiddenValues, currentMentionGroupId);
9060
+ const badgeCount = isCheckAll
9061
+ ? allFilterValuesRef.current.length - MAX_VISIBLE
9062
+ : hiddenValues.length;
9063
+ const countBadge = createCountBadge(badgeCount, hiddenValues, currentMentionGroupId);
9046
9064
  fragment.appendChild(countBadge);
9047
9065
  }
9048
9066
  // Add space to fragment
@@ -9627,7 +9645,28 @@ const ChatbotInput = (props) => {
9627
9645
  // Stage 2: Value selection with dropdown - use Select
9628
9646
  jsxRuntime.jsx(impactUiV3.Select, { currentOptions: currentOptions.length > 0 ? currentOptions : [], setCurrentOptions: setCurrentOptions, initialOptions: currentOptions.length > 0 ? currentOptions : [], placeholder: isLoadingValues
9629
9647
  ? "Loading values..."
9630
- : "Select values...", handleChange: handleMentionSelect, isOpen: isSelectOpen, setIsOpen: setIsSelectOpen, selectedOptions: selectedOptions, setSelectedOptions: setSelectedOptions, isCloseWhenClickOutside: false, isWithSearch: true, isSelectAll: !isLoadingValues ? isAllSelected : false, setIsSelectAll: setIsAllSelected, toggleSelectAll: !isLoadingValues, isMulti: selectedFilter?.is_multiple_selection !== false, disabled: isLoadingValues, isLoading: isLoadingValues, emptyMessage: isLoadingValues ? "Loading values..." : "No options available" })) })), showDateRangePicker && (jsxRuntime.jsx("div", { className: "mention-select-wrapper", ref: dateRangePickerRef, style: {
9648
+ : "Select values...", handleChange: handleMentionSelect, isOpen: isSelectOpen, setIsOpen: setIsSelectOpen, selectedOptions: selectedOptions, setSelectedOptions: setSelectedOptions, isCloseWhenClickOutside: false, isWithSearch: true, onMenuScrollToBottom: () => {
9649
+ const allValues = allFilterValuesRef.current;
9650
+ if (allValues.length > 0 && currentOptions.length < allValues.length) {
9651
+ const nextCount = Math.min(currentOptions.length + LOAD_MORE_COUNT, allValues.length);
9652
+ const nextOptions = allValues.slice(0, nextCount);
9653
+ setCurrentOptions(nextOptions);
9654
+ if (isAllSelected) {
9655
+ setSelectedOptions(nextOptions);
9656
+ }
9657
+ }
9658
+ }, onSelectAll: (e) => {
9659
+ if (e && e.target.checked) {
9660
+ setSelectedOptions([...currentOptions]);
9661
+ setIsAllSelected(true);
9662
+ }
9663
+ else {
9664
+ setSelectedOptions([]);
9665
+ setIsAllSelected(false);
9666
+ }
9667
+ }, customPlaceholderAfterSelect: isAllSelected && allFilterValuesRef.current.length > 0
9668
+ ? allFilterValuesRef.current.length
9669
+ : null, isSelectAll: !isLoadingValues ? isAllSelected : false, setIsSelectAll: setIsAllSelected, toggleSelectAll: !isLoadingValues, isMulti: selectedFilter?.is_multiple_selection !== false, disabled: isLoadingValues, isLoading: isLoadingValues, emptyMessage: isLoadingValues ? "Loading values..." : "No options available" })) })), showDateRangePicker && (jsxRuntime.jsx("div", { className: "mention-select-wrapper", ref: dateRangePickerRef, style: {
9631
9670
  position: "fixed",
9632
9671
  top: `680px`,
9633
9672
  left: `${dropdownPosition.left}px`,