@agilant/toga-blox 1.0.119 → 1.0.120

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.
@@ -1,34 +1,34 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // ===================== SearchDropdownInput.tsx =====================
3
2
  import { useEffect, useState } from "react";
4
3
  import MultiSelectInput from "../MultiSelect/MultiSelect";
5
4
  import updateLocalStorage from "../../utils/updateLocalStorage";
6
5
  const DEFAULT_STORAGE_KEY = "searchCriteria";
7
6
  const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, placeholder = "Select", disabled = false, hasSelectAll = true, bgColor = "bg-sky-500", textHighlight = "text-sky-700", handleFilter, searchItems = [], setSearchItems, setSearchCriteria, column, setEditingHeader, clearText = "Clear", clearTextColor = "text-sky-500", buttonText = "Filter", buttonColor = "bg-sky-500", localStorageKey = DEFAULT_STORAGE_KEY, isBoolean = false, isSearchable, fontFamily, pillColor, ...rest }) => {
8
7
  const canStore = !!column?.id && !!setSearchCriteria;
9
- // We'll track how many items are visible in the child, for the "Filter" footer
10
8
  const [filteredCount, setFilteredCount] = useState(0);
11
9
  // --------------------------------------------------------------------
12
- // [NEW FIX] On mount, read from localStorage, parse the selected values
10
+ // On mount, read from localStorage to see previously selected items
13
11
  // --------------------------------------------------------------------
14
12
  useEffect(() => {
15
13
  if (!canStore)
16
- return; // we need column.id + setSearchCriteria
14
+ return;
17
15
  const stored = localStorage.getItem(localStorageKey);
18
16
  if (!stored)
19
17
  return;
20
18
  try {
21
19
  const parsed = JSON.parse(stored);
20
+ // see if there's a criterion for this specific column ID
22
21
  const existing = parsed.find((c) => c.searchColumn?.id === column?.id);
23
22
  if (existing && setSearchItems) {
23
+ // e.g. "fulfilled,pendingApproval"
24
24
  const raw = existing.submittedSearchText;
25
- setSearchItems([raw]); // e.g. "fulfilled,canceled"
26
- // We assume it's stored with commas
27
- // If you might have colons, handle that too:
25
+ setSearchItems([raw]);
26
+ // Split by comma. If you sometimes store colons, handle that:
28
27
  const delimiter = raw.includes(":") ? ":" : ",";
29
28
  const storedValues = raw.split(delimiter).map((s) => s.trim());
30
- // Now find matching options
29
+ // Match them to your full list of options
31
30
  const matched = options.filter((o) => storedValues.includes(o.value));
31
+ // Re-check these items
32
32
  onChange(matched);
33
33
  }
34
34
  }
@@ -39,15 +39,15 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
39
39
  canStore,
40
40
  column?.id,
41
41
  localStorageKey,
42
- setSearchItems,
43
- onChange,
44
42
  options,
43
+ onChange,
44
+ setSearchItems,
45
45
  ]);
46
- // Called when user clicks the "Filter" button in the footer
46
+ // Called when user clicks the Filter button in the multiSelect footer
47
47
  const handleFooterFilter = () => {
48
- // remove any special "footer" options
48
+ // We skip any special "footer" or "Select All" item
49
49
  const actualSelections = selectedValue.filter((opt) => opt.value !== "__footer__" && opt.label !== "Select All");
50
- // store them as comma-joined
50
+ // Store them in localStorage as a comma-joined string
51
51
  const selectedLabels = actualSelections
52
52
  .map((opt) => opt.value)
53
53
  .join(",");
@@ -57,7 +57,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
57
57
  return;
58
58
  }
59
59
  if (isEmpty) {
60
- // Remove from local storage
60
+ // user cleared everything, remove from localStorage
61
61
  setSearchCriteria?.((prev) => {
62
62
  const newCriteria = prev.filter((c) => c.searchColumn.id !== column?.id);
63
63
  updateLocalStorage(newCriteria, localStorageKey);
@@ -65,16 +65,14 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
65
65
  });
66
66
  }
67
67
  else {
68
- // Store to local storage
68
+ // store new criterion
69
69
  setSearchCriteria?.((prev) => {
70
70
  const filtered = prev.filter((c) => c.searchColumn.id !== column?.id);
71
- const newCriteria = [
72
- ...filtered,
73
- {
74
- searchColumn: column,
75
- submittedSearchText: selectedLabels, // e.g. "fulfilled,canceled"
76
- },
77
- ];
71
+ const newCriterion = {
72
+ searchColumn: column,
73
+ submittedSearchText: selectedLabels, // e.g. "fulfilled,pendingApproval"
74
+ };
75
+ const newCriteria = [...filtered, newCriterion];
78
76
  updateLocalStorage(newCriteria, localStorageKey);
79
77
  return newCriteria;
80
78
  });
@@ -82,7 +80,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
82
80
  setEditingHeader?.(null);
83
81
  handleFilter?.();
84
82
  };
85
- // Called when user clicks Clear
83
+ // Called when user clicks "Clear"
86
84
  const handleClear = () => {
87
85
  onChange([]);
88
86
  if (canStore) {
@@ -95,18 +93,18 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
95
93
  setEditingHeader?.(null);
96
94
  }
97
95
  };
98
- // Insert a footer pseudo-option
96
+ // We add a "footer" pseudo-option so we can place a Filter button, etc. at the bottom
99
97
  const footerOption = [{ name: "", value: "__footer__" }];
100
98
  const extendedOptions = [...options, ...footerOption];
101
- // Custom item renderer for multiSelect
99
+ // Provide a custom item renderer so we can handle the "Footer" row
102
100
  const itemRenderer = ({ option, checked, disabled, onClick }) => {
103
101
  if (option.value === "__footer__") {
104
- return (_jsxs("div", { className: "footer px-4 py-2 flex justify-between items-center text-gray-300 border-t border-gray-300", children: [filteredCount === 0 ? (_jsx("div", { onClick: handleClear, className: `${textHighlight} cursor-pointer`, children: clearText })) : (_jsxs("div", { children: [filteredCount, " Results"] })), _jsx("button", { type: "button", className: `${bgColor} ${fontFamily} text-white px-3 py-1 rounded-full`, onClick: (e) => {
102
+ return (_jsxs("div", { className: "\n footer\n px-4 py-2\n flex justify-between items-center\n text-gray-300\n border-t border-gray-300\n ", children: [filteredCount === 0 ? (_jsx("div", { onClick: handleClear, className: `${textHighlight} cursor-pointer`, children: clearText })) : (_jsxs("div", { children: [filteredCount, " Results"] })), _jsx("button", { type: "button", className: `${bgColor} ${fontFamily} text-white px-3 py-1 rounded-full`, onClick: (e) => {
105
103
  e.stopPropagation();
106
104
  handleFooterFilter();
107
105
  }, children: buttonText })] }));
108
106
  }
109
- // Another example: "Select All" row
107
+ // "Select All" if you want to implement that
110
108
  if (option.label === "Select All") {
111
109
  // ...
112
110
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agilant/toga-blox",
3
3
  "private": false,
4
- "version": "1.0.119",
4
+ "version": "1.0.120",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",