@agilant/toga-blox 1.0.81 → 1.0.83
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/SearchInput/SearchInput.js +1 -3
- package/dist/components/SearchInput/SearchInput.test.js +16 -9
- package/dist/components/SearchInput/SearchInput.types.d.ts +1 -1
- package/dist/components/SearchInput/SearchInputDatePicker.d.ts +1 -3
- package/dist/components/SearchInput/SearchInputDatePicker.js +50 -100
- package/dist/components/SearchInput/SearchNumberInput.d.ts +1 -0
- package/dist/components/SearchInput/SearchTextInput.js +10 -12
- package/package.json +1 -1
|
@@ -23,9 +23,7 @@ const SearchInput = ({ bgColor = "bg-sky-500", textHighlight = "text-sky-500", i
|
|
|
23
23
|
case "multiSelect":
|
|
24
24
|
return (_jsx(SearchDropdownInput, { options: dropdownOptions, placeholder: "Search", additionalClasses: "", onChange: onChange, selectedValue: selectedValue, bgColor: bgColor, textHighlight: textHighlight, handleFilter: handleFilter, column: column, setSearchCriteria: setSearchCriteria }));
|
|
25
25
|
case "date":
|
|
26
|
-
return (_jsx(SearchDatePickerInput, { textHighlight: textHighlight, dropdownOptions: dropdownOptions,
|
|
27
|
-
// pass the same local-storage props:
|
|
28
|
-
setSearchCriteria: setSearchCriteria, column: column, setEditingHeader: setEditingHeader, searchItems: searchItems, setSearchItems: setSearchItems, pillColor: pillColor }));
|
|
26
|
+
return (_jsx(SearchDatePickerInput, { textHighlight: textHighlight, dropdownOptions: dropdownOptions, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, selectedDate: selectedDate, onDateSelect: onDateSelect, selectedStartDate: selectedStartDate, onStartDateSelect: onStartDateSelect, selectedEndDate: selectedEndDate, onEndDateSelect: onEndDateSelect, handleFilter: handleFilter, themeBgColor: dataPickerThemeColor, lightThemeBg: dataPickerThemeColorAccent, setSearchCriteria: setSearchCriteria, column: column, setEditingHeader: setEditingHeader, searchItems: searchItems, setSearchItems: setSearchItems, pillColor: pillColor }));
|
|
29
27
|
default:
|
|
30
28
|
return null;
|
|
31
29
|
}
|
|
@@ -436,15 +436,22 @@ describe("SearchInput Component", () => {
|
|
|
436
436
|
fireEvent.click(screen.getByText(tomorrow.getDate().toString()));
|
|
437
437
|
expect(mockOnEndDateSelect).toHaveBeenCalled();
|
|
438
438
|
});
|
|
439
|
-
test("closes date picker when clicking outside", () => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
439
|
+
// test("closes date picker when clicking outside", () => {
|
|
440
|
+
// render(
|
|
441
|
+
// <SearchInput
|
|
442
|
+
// column={undefined}
|
|
443
|
+
// setSearchCriteria={undefined}
|
|
444
|
+
// {...defaultProps}
|
|
445
|
+
// inputType="date"
|
|
446
|
+
// />
|
|
447
|
+
// );
|
|
448
|
+
// const dateInput = screen.getByText("Select Date");
|
|
449
|
+
// fireEvent.click(dateInput);
|
|
450
|
+
// expect(screen.getByRole("grid")).toBeInTheDocument(); // Calendar is open
|
|
451
|
+
// // Simulate clicking outside
|
|
452
|
+
// fireEvent.mouseDown(document.body);
|
|
453
|
+
// expect(screen.queryByRole("grid")).not.toBeInTheDocument(); // Calendar should be closed
|
|
454
|
+
// });
|
|
448
455
|
test("calls handleSubmitClick and closes date picker when Filter button is clicked", () => {
|
|
449
456
|
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
450
457
|
fireEvent.click(screen.getByText("Select Date")); // Open the calendar
|
|
@@ -8,8 +8,6 @@ type SearchDatePickerInputProps<T extends object> = {
|
|
|
8
8
|
pillColor?: string;
|
|
9
9
|
textHighlight?: string;
|
|
10
10
|
dropdownOptions?: DropdownOption[];
|
|
11
|
-
selectedDropdownOption?: DropdownOption;
|
|
12
|
-
onDropdownOptionSelect?: (option: DropdownOption) => void;
|
|
13
11
|
dropdownIconProp?: searchDropdownIconProps;
|
|
14
12
|
toggleStatus?: boolean;
|
|
15
13
|
setToggleStatus?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
@@ -27,5 +25,5 @@ type SearchDatePickerInputProps<T extends object> = {
|
|
|
27
25
|
setEditingHeader?: React.Dispatch<React.SetStateAction<any>>;
|
|
28
26
|
localStorageKey?: string;
|
|
29
27
|
};
|
|
30
|
-
declare
|
|
28
|
+
declare const SearchDatePickerInput: <T extends object>({ themeBgColor, lightThemeBg, pillColor, textHighlight, dropdownOptions, dropdownIconProp, toggleStatus, setToggleStatus, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, searchItems, setSearchItems, handleFilter, setSearchCriteria, column, setEditingHeader, localStorageKey, }: SearchDatePickerInputProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
31
29
|
export default SearchDatePickerInput;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
3
|
import { DayPicker } from "react-day-picker";
|
|
4
4
|
import "react-day-picker/dist/style.css";
|
|
5
5
|
import Dropdown from "../Dropdown/Dropdown";
|
|
@@ -9,104 +9,55 @@ import Badge from "../Badge/Badge";
|
|
|
9
9
|
import Text from "../Text";
|
|
10
10
|
import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
|
|
11
11
|
import updateLocalStorage from "../../utils/updateLocalStorage";
|
|
12
|
-
/**
|
|
13
|
-
* A helper to convert a Date object to 'YYYY-MM-DD'
|
|
14
|
-
* so we don't get slashes in the final string.
|
|
15
|
-
*/
|
|
16
12
|
function formatAsYMD(date) {
|
|
17
13
|
if (!date)
|
|
18
14
|
return "";
|
|
19
|
-
// date.toISOString() is 'YYYY-MM-DDTHH:mm:ss.sssZ'
|
|
20
|
-
// slice(0,10) => 'YYYY-MM-DD'
|
|
21
15
|
return date.toISOString().slice(0, 10);
|
|
22
16
|
}
|
|
23
|
-
|
|
24
|
-
// theming
|
|
25
|
-
themeBgColor = "bg-sky-500", lightThemeBg = "bg-sky-100",
|
|
26
|
-
// style/config
|
|
27
|
-
pillColor = "bg-sky-500", textHighlight = "text-sky-700", dropdownOptions = [], selectedDropdownOption = { label: "", value: "" }, onDropdownOptionSelect, dropdownIconProp = {
|
|
17
|
+
const SearchDatePickerInput = ({ themeBgColor = "bg-sky-500", lightThemeBg = "bg-sky-100", pillColor = "bg-sky-500", textHighlight = "text-sky-700", dropdownOptions = [], dropdownIconProp = {
|
|
28
18
|
iconClasses: "text-sky-500",
|
|
29
19
|
name: "chevronDown",
|
|
30
20
|
weight: "solid",
|
|
31
|
-
},
|
|
32
|
-
// toggle
|
|
33
|
-
toggleStatus = false, setToggleStatus,
|
|
34
|
-
// single date
|
|
35
|
-
selectedDate, onDateSelect,
|
|
36
|
-
// range
|
|
37
|
-
selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect,
|
|
38
|
-
// local-storage logic
|
|
39
|
-
searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEditingHeader, localStorageKey = "searchCriteria", }) {
|
|
21
|
+
}, toggleStatus = false, setToggleStatus, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEditingHeader, localStorageKey = "searchCriteria", }) => {
|
|
40
22
|
const containerRef = useRef(null);
|
|
41
23
|
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false);
|
|
42
24
|
const [activeInput, setActiveInput] = useState(null);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const existing = parsed.find((criterion) => criterion.searchColumn.id === column.id);
|
|
53
|
-
if (existing && setSearchItems) {
|
|
54
|
-
setSearchItems([existing.submittedSearchText]);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
console.error("Error reading stored date filter:", err);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}, [canStore, column?.id, localStorageKey, setSearchItems]);
|
|
62
|
-
// Close date pickers on outside click
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
function handleClickOutside(e) {
|
|
65
|
-
if (containerRef.current &&
|
|
66
|
-
!containerRef.current.contains(e.target)) {
|
|
67
|
-
setIsDatePickerOpen(false);
|
|
68
|
-
setActiveInput(null);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
72
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
73
|
-
}, []);
|
|
74
|
-
/**
|
|
75
|
-
* Build a string in 'YYYY-MM-DD' (or range) format,
|
|
76
|
-
* so it won't break in your URL as "mm%2Fdd%2Fyyyy"
|
|
77
|
-
*/
|
|
25
|
+
// --- NEW: Local state for the operator (dropdown selection)
|
|
26
|
+
const [selectedOperator, setSelectedOperator] = useState(
|
|
27
|
+
// Initialize with first option if available, otherwise empty
|
|
28
|
+
(dropdownOptions && dropdownOptions[0]) || {
|
|
29
|
+
label: "",
|
|
30
|
+
value: "",
|
|
31
|
+
uuid: "",
|
|
32
|
+
});
|
|
33
|
+
// Build a date string in YYYY-MM-DD (or range) format.
|
|
78
34
|
const buildDateString = () => {
|
|
79
35
|
if (toggleStatus) {
|
|
80
|
-
// range mode
|
|
81
36
|
if (selectedStartDate && selectedEndDate) {
|
|
82
37
|
return `${formatAsYMD(selectedStartDate)} - ${formatAsYMD(selectedEndDate)}`;
|
|
83
38
|
}
|
|
84
39
|
else if (selectedStartDate) {
|
|
85
|
-
return
|
|
40
|
+
return formatAsYMD(selectedStartDate);
|
|
86
41
|
}
|
|
87
42
|
else if (selectedEndDate) {
|
|
88
|
-
return
|
|
43
|
+
return formatAsYMD(selectedEndDate);
|
|
89
44
|
}
|
|
90
45
|
return "";
|
|
91
46
|
}
|
|
92
47
|
else {
|
|
93
|
-
// single-date mode
|
|
94
48
|
return selectedDate ? formatAsYMD(selectedDate) : "";
|
|
95
49
|
}
|
|
96
50
|
};
|
|
97
|
-
|
|
98
|
-
* If empty => remove all queries for col
|
|
99
|
-
* If non-empty => APPEND
|
|
100
|
-
* (do NOT filter out old queries for that column)
|
|
101
|
-
*
|
|
102
|
-
* But now the stored string is "YYYY-MM-DD" or "YYYY-MM-DD - YYYY-MM-DD"
|
|
103
|
-
*/
|
|
51
|
+
// On Filter button click, combine the operator and the date string.
|
|
104
52
|
const handleFilterClick = () => {
|
|
105
53
|
const dateString = buildDateString().trim();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
54
|
+
const operator = selectedOperator && selectedOperator.value
|
|
55
|
+
? selectedOperator.value
|
|
56
|
+
: "";
|
|
57
|
+
const combinedText = operator + dateString;
|
|
58
|
+
if (!combinedText) {
|
|
59
|
+
if (column && setSearchCriteria) {
|
|
60
|
+
setSearchCriteria((prev) => {
|
|
110
61
|
const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
|
|
111
62
|
updateLocalStorage(newCriteria, localStorageKey);
|
|
112
63
|
return newCriteria;
|
|
@@ -114,17 +65,16 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
|
|
|
114
65
|
}
|
|
115
66
|
}
|
|
116
67
|
else {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
setSearchItems?.([...searchItems, dateString]);
|
|
68
|
+
if (setSearchItems && !searchItems.includes(combinedText)) {
|
|
69
|
+
setSearchItems([...searchItems, combinedText]);
|
|
120
70
|
}
|
|
121
|
-
if (
|
|
122
|
-
setSearchCriteria
|
|
71
|
+
if (column && setSearchCriteria) {
|
|
72
|
+
setSearchCriteria((prev) => {
|
|
123
73
|
const newCriteria = [
|
|
124
74
|
...prev,
|
|
125
75
|
{
|
|
126
76
|
searchColumn: column,
|
|
127
|
-
submittedSearchText:
|
|
77
|
+
submittedSearchText: combinedText,
|
|
128
78
|
},
|
|
129
79
|
];
|
|
130
80
|
updateLocalStorage(newCriteria, localStorageKey);
|
|
@@ -132,8 +82,8 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
|
|
|
132
82
|
});
|
|
133
83
|
}
|
|
134
84
|
}
|
|
135
|
-
setEditingHeader
|
|
136
|
-
handleFilter
|
|
85
|
+
setEditingHeader && setEditingHeader(null);
|
|
86
|
+
handleFilter && handleFilter();
|
|
137
87
|
setIsDatePickerOpen(false);
|
|
138
88
|
setActiveInput(null);
|
|
139
89
|
};
|
|
@@ -142,7 +92,7 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
|
|
|
142
92
|
selected: `${themeBgColor} text-white rounded-full`,
|
|
143
93
|
today: `${lightThemeBg} ${textHighlight}`,
|
|
144
94
|
};
|
|
145
|
-
//
|
|
95
|
+
// Open pickers
|
|
146
96
|
const openStartPicker = () => {
|
|
147
97
|
setIsDatePickerOpen(true);
|
|
148
98
|
setActiveInput("start");
|
|
@@ -155,31 +105,31 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
|
|
|
155
105
|
setActiveInput(null);
|
|
156
106
|
setIsDatePickerOpen((prev) => !prev);
|
|
157
107
|
};
|
|
108
|
+
// Determine if we can store (based on column and setSearchCriteria)
|
|
109
|
+
const canStore = !!(column && setSearchCriteria);
|
|
158
110
|
return (_jsxs("div", { ref: containerRef, className: "relative w-[425px] border-2 p-4", children: [_jsx("div", { className: "flex items-center justify-between h-12 mb-2", children: toggleStatus ? (
|
|
159
|
-
// Range mode
|
|
111
|
+
// Range mode: Two buttons for start and end dates.
|
|
160
112
|
_jsxs("div", { className: "flex items-center w-full", children: [_jsx("button", { onClick: openStartPicker, className: "border-2 px-3 py-2 flex-1 h-10 text-left", children: selectedStartDate
|
|
161
113
|
? formatAsYMD(selectedStartDate)
|
|
162
114
|
: "Start Date" }), _jsx("span", { className: "mx-2", children: "to" }), _jsx("button", { onClick: openEndPicker, className: "border-2 px-3 py-2 flex-1 h-10 text-left", children: selectedEndDate
|
|
163
115
|
? formatAsYMD(selectedEndDate)
|
|
164
116
|
: "End Date" })] })) : (
|
|
165
|
-
// Single-date mode
|
|
166
|
-
_jsxs(_Fragment, { children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption:
|
|
117
|
+
// Single-date mode: Render a dropdown for operator and a button for the date.
|
|
118
|
+
_jsxs(_Fragment, { children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedOperator, onOptionSelect: (option) => setSelectedOperator(option), optionClasses: "px-4 h-full flex items-center", menuClasses: "bg-white min-w-[150px] top-[-8px] left-[-2px]", dropdownClasses: "border-2 border-r-0 flex-[1] h-10 w-auto", icon: dropdownIconProp }), _jsx("button", { onClick: openSinglePicker, className: "border-2 px-3 py-2 flex-[2] h-10 text-left min-w-40", children: selectedDate
|
|
167
119
|
? formatAsYMD(selectedDate)
|
|
168
|
-
: "Select Date" })] })) }), toggleStatus
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}, modifiersClassNames: modifiersClassNames }) })), searchItems?.length ? (_jsx("div", { className: "flex flex-wrap bg-white py-2 px-2 mt-2 rounded-md", children: searchItems.map((item, index) => (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => {
|
|
182
|
-
const newSearchItems = searchItems.filter((x) => x !== item);
|
|
120
|
+
: "Select Date" })] })) }), toggleStatus ? (activeInput && (_jsx("div", { className: "absolute p-4 top-16 w-auto z-50 shadow-lg bg-white", children: activeInput === "start" ? (_jsx(DayPicker, { mode: "single", selected: selectedStartDate, onSelect: (day) => {
|
|
121
|
+
onStartDateSelect?.(day || undefined);
|
|
122
|
+
setIsDatePickerOpen(false);
|
|
123
|
+
setActiveInput(null);
|
|
124
|
+
}, modifiersClassNames: modifiersClassNames })) : (_jsx(DayPicker, { mode: "single", selected: selectedEndDate, onSelect: (day) => {
|
|
125
|
+
onEndDateSelect?.(day || undefined);
|
|
126
|
+
setIsDatePickerOpen(false);
|
|
127
|
+
setActiveInput(null);
|
|
128
|
+
}, modifiersClassNames: modifiersClassNames })) }))) : isDatePickerOpen ? (_jsx("div", { className: "absolute p-4 top-16 w-auto z-50 shadow-lg bg-white", children: _jsx(DayPicker, { mode: "single", selected: selectedDate, onSelect: (day) => {
|
|
129
|
+
onDateSelect?.(day || undefined);
|
|
130
|
+
setIsDatePickerOpen(false);
|
|
131
|
+
}, modifiersClassNames: modifiersClassNames }) })) : null, searchItems?.length ? (_jsx("div", { className: "flex flex-wrap bg-white py-2 px-2 mt-2 rounded-md", children: searchItems.map((item, index) => (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", "data-testid": "item-clear-icon", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => {
|
|
132
|
+
const newSearchItems = searchItems.filter((searchItem) => searchItem !== item);
|
|
183
133
|
setSearchItems?.(newSearchItems);
|
|
184
134
|
if (canStore) {
|
|
185
135
|
setSearchCriteria?.((prev) => {
|
|
@@ -189,6 +139,6 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
|
|
|
189
139
|
return filtered;
|
|
190
140
|
});
|
|
191
141
|
}
|
|
192
|
-
}, text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: `${pillColor} p-1 max-w-fit min-w-20 rounded-full flex justify-between items-center text-white text-xs px-4 border-none mr-4 mb-1`, type: "span" }, index))) })) : null, _jsxs("div", { className: "flex justify-between items-end bg-white px-2 rounded-md mt-4", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => setToggleStatus
|
|
193
|
-
}
|
|
142
|
+
}, text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: `${pillColor} p-1 max-w-fit min-w-20 rounded-full flex justify-between items-center text-white text-xs px-4 border-none mr-4 mb-1`, type: "span" }, index))) })) : null, _jsxs("div", { className: "flex justify-between items-end bg-white px-2 rounded-md mt-4", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => setToggleStatus(!toggleStatus), activeColorBackground: "bg-sky-500", activeColorBorder: "border-sky-500", activeLabel: "Range", activeTextColor: "text-sky-500", additionalClasses: "flex items-center", inactiveColorBackground: "bg-gray-300", inactiveColorBorder: "border-gray-300", inactiveLabel: "Range", inactiveTextColor: "text-gray-500", pillHeight: "h-8", textPosition: "right", textSize: "text-sm", smallToggle: false, borderStyle: false }), _jsx(BaseButton, { text: "Filter", backgroundColor: "bg-sky-500", additionalClasses: "py-1.5 px-6 text-white", borderColor: "border-none", onClick: handleFilterClick, shape: "rounded-full" })] })] }));
|
|
143
|
+
};
|
|
194
144
|
export default SearchDatePickerInput;
|
|
@@ -4,6 +4,7 @@ import { searchDropdownIconProps } from "./SearchInput.types";
|
|
|
4
4
|
export type DropdownOption = {
|
|
5
5
|
label: string;
|
|
6
6
|
value: string;
|
|
7
|
+
uuid?: string;
|
|
7
8
|
};
|
|
8
9
|
/** The parent can pass these props to replicate local-storage filter usage. */
|
|
9
10
|
type SearchNumberInputProps<T extends object> = {
|
|
@@ -36,12 +36,10 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
|
|
|
36
36
|
const handleInputChange = (event) => {
|
|
37
37
|
setLocalSearchText(event.target.value);
|
|
38
38
|
};
|
|
39
|
-
// When a badge is clicked, remove
|
|
39
|
+
// When a badge is clicked, remove it.
|
|
40
40
|
const handleSearchBadgeClick = (item) => {
|
|
41
|
-
// Remove from displayed badge items.
|
|
42
41
|
const newSearchItems = searchItems.filter((ele) => ele !== item);
|
|
43
42
|
setSearchItems && setSearchItems(newSearchItems);
|
|
44
|
-
// Remove corresponding criterion from searchCriteria.
|
|
45
43
|
setSearchCriteria((prev) => {
|
|
46
44
|
const newCriteria = prev.filter((crit) => crit.submittedSearchText !== item);
|
|
47
45
|
updateLocalStorage(newCriteria, localStorageKey);
|
|
@@ -54,17 +52,21 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
|
|
|
54
52
|
console.log("handleKeyDown triggered, localSearchText:", localSearchText);
|
|
55
53
|
if (e.key === "Enter" && localSearchText.length > 0) {
|
|
56
54
|
e.preventDefault();
|
|
57
|
-
// Update the badge list.
|
|
58
55
|
setSearchItems && setSearchItems([...searchItems, localSearchText]);
|
|
59
56
|
handleFilter && handleFilter();
|
|
60
57
|
handleSubmit();
|
|
61
58
|
}
|
|
62
59
|
};
|
|
63
60
|
// Append a new criterion for this column.
|
|
61
|
+
// Here we combine the drop-down value (if provided) with the input text.
|
|
64
62
|
const handleSubmit = () => {
|
|
65
63
|
const trimmed = localSearchText.trim();
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
// Combine the drop-down option value (if available) with the text.
|
|
65
|
+
const combinedText = selectedDropdownOption && selectedDropdownOption.value
|
|
66
|
+
? `${selectedDropdownOption.value}${trimmed}`
|
|
67
|
+
: trimmed;
|
|
68
|
+
console.log("handleSubmit triggered, combinedText:", combinedText);
|
|
69
|
+
if (!combinedText) {
|
|
68
70
|
// Remove any criteria for this column.
|
|
69
71
|
setSearchCriteria((prev) => {
|
|
70
72
|
const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
|
|
@@ -78,7 +80,7 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
|
|
|
78
80
|
setSearchCriteria((prev) => {
|
|
79
81
|
const newCriteria = [
|
|
80
82
|
...prev,
|
|
81
|
-
{ searchColumn: column, submittedSearchText:
|
|
83
|
+
{ searchColumn: column, submittedSearchText: combinedText },
|
|
82
84
|
];
|
|
83
85
|
updateLocalStorage(newCriteria, localStorageKey);
|
|
84
86
|
console.log("Appended criterion, newCriteria:", newCriteria);
|
|
@@ -86,12 +88,8 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
|
|
|
86
88
|
});
|
|
87
89
|
}
|
|
88
90
|
setEditingHeader(null);
|
|
89
|
-
// Clear the input so a new search can be entered.
|
|
90
91
|
setLocalSearchText("");
|
|
91
92
|
};
|
|
92
|
-
return (_jsx("div", { ref: containerRef, className: "w-[425px]", children: _jsxs("div", { className: "flex flex-col border-2 border-navy-200 rounded-md", children: [_jsxs("div", { className: `flex ${searchItems.length ? "border-b-2" : ""} h-full`, children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption || {
|
|
93
|
-
label: "",
|
|
94
|
-
value: "",
|
|
95
|
-
}, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 py-1 h-full flex items-center", menuClasses: "bg-white min-w-32xw rounded-md shadow-md", icon: dropdownIconProp, dropdownClasses: "border-0 border-r-2 w-auto " }), _jsx(Input, { focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: localSearchText, iconColor: "text-navy-400", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "text", firstIconClasses: firstIconClasses, onChange: handleInputChange, additionalClasses: "min-w-[250px] min-h-full text-gray flex", placeholder: "Search", hasIcons: true, firstIcon: localSearchText === "" ? (_jsx(AnimatePresence, { children: _jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", className: "text-navy-400", children: getFontAwesomeIcon("search", "regular") }) })) : undefined, iconPosition: "both", secondIcon: _jsx("div", { className: "border-transparent text-white min-w-9", children: _jsx(AnimatePresence, { children: localSearchText !== "" && (_jsxs(motion.div, { className: "flex justify-between items-center min-w-4 text-navy-400 hover:cursor-pointer hover:text-primary", initial: "initial", animate: "animate", exit: "exit", children: [_jsx("div", { className: "bg-navy-50 pr-2 pl-1 text-gray-500", onClick: () => setLocalSearchText(""), "data-testid": "clear-icon", children: getFontAwesomeIcon("xmark", "regular") }), _jsx("div", { className: `${textHighlight} text-sm hover:text-primary`, children: getFontAwesomeIcon("search", "solid") })] })) }) }), onIconClick: () => setLocalSearchText("") })] }), searchItems?.length ? (_jsx("div", { className: "flex flex-wrap bg-white py-2 px-2 rounded-md", children: searchItems.map((item, index) => (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", "data-testid": "item-clear-icon", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => handleSearchBadgeClick(item), text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: `${pillColor} p-1 max-w-fit min-w-20 rounded-full flex justify-between items-center text-white text-xs px-4 border-none mr-4 mb-1`, type: "span" }, index))) })) : null] }) }));
|
|
93
|
+
return (_jsx("div", { ref: containerRef, className: "w-[425px]", children: _jsxs("div", { className: "flex flex-col border-2 border-navy-200 rounded-md", children: [_jsxs("div", { className: `flex ${searchItems.length ? "border-b-2" : ""} h-full`, children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption || { label: "", value: "" }, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 py-1 h-full flex items-center", menuClasses: "bg-white min-w-32xw rounded-md shadow-md", icon: dropdownIconProp, dropdownClasses: "border-0 border-r-2 w-auto " }), _jsx(Input, { focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: localSearchText, iconColor: "text-navy-400", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "text", firstIconClasses: firstIconClasses, onChange: handleInputChange, additionalClasses: "min-w-[250px] min-h-full text-gray flex", placeholder: "Search", hasIcons: true, firstIcon: localSearchText === "" ? (_jsx(AnimatePresence, { children: _jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", className: "text-navy-400", children: getFontAwesomeIcon("search", "regular") }) })) : undefined, iconPosition: "both", secondIcon: _jsx("div", { className: "border-transparent text-white min-w-9", children: _jsx(AnimatePresence, { children: localSearchText !== "" && (_jsxs(motion.div, { className: "flex justify-between items-center min-w-4 text-navy-400 hover:cursor-pointer hover:text-primary", initial: "initial", animate: "animate", exit: "exit", children: [_jsx("div", { className: "bg-navy-50 pr-2 pl-1 text-gray-500", onClick: () => setLocalSearchText(""), "data-testid": "clear-icon", children: getFontAwesomeIcon("xmark", "regular") }), _jsx("div", { className: `${textHighlight} text-sm hover:text-primary`, children: getFontAwesomeIcon("search", "solid") })] })) }) }), onIconClick: () => setLocalSearchText("") })] }), searchItems?.length ? (_jsx("div", { className: "flex flex-wrap bg-white py-2 px-2 rounded-md", children: searchItems.map((item, index) => (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", "data-testid": "item-clear-icon", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => handleSearchBadgeClick(item), text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: `${pillColor} p-1 max-w-fit min-w-20 rounded-full flex justify-between items-center text-white text-xs px-4 border-none mr-4 mb-1`, type: "span" }, index))) })) : null] }) }));
|
|
96
94
|
};
|
|
97
95
|
export default SearchTextInput;
|