@agilant/toga-blox 1.0.59 → 1.0.61
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.d.ts +1 -1
- package/dist/components/SearchInput/SearchInput.js +2 -3
- package/dist/components/SearchInput/SearchInput.stories.js +20 -19
- package/dist/components/SearchInput/SearchInput.test.js +52 -52
- package/dist/components/SearchInput/SearchInput.types.d.ts +3 -2
- package/dist/components/SearchInput/SearchTextInput.d.ts +4 -9
- package/dist/components/SearchInput/SearchTextInput.js +59 -54
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { SearchInputProps } from "./SearchInput.types";
|
|
2
|
-
declare const SearchInput: <T extends object>({ bgColor, textHighlight, inputType, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter,
|
|
2
|
+
declare const SearchInput: <T extends object>({ bgColor, textHighlight, inputType, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, column, setSearchCriteria, setEditingHeader, }: SearchInputProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export default SearchInput;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
// SearchInput.tsx
|
|
3
2
|
import { useEffect, useRef } from "react";
|
|
4
3
|
import SearchTextInput from "./SearchTextInput";
|
|
5
4
|
import SearchNumberInput from "./SearchNumberInput";
|
|
@@ -9,7 +8,7 @@ const SearchInput = ({ bgColor = "bg-sky-500", textHighlight = "text-sky-500", i
|
|
|
9
8
|
name: "chevronDown",
|
|
10
9
|
weight: "bold",
|
|
11
10
|
iconClasses: "text-black",
|
|
12
|
-
}, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, toggleStatus = false, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter,
|
|
11
|
+
}, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, toggleStatus = false, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, column, setSearchCriteria, setEditingHeader, }) => {
|
|
13
12
|
const containerRef = useRef(null);
|
|
14
13
|
const inputRef = useRef(null);
|
|
15
14
|
useEffect(() => {
|
|
@@ -18,7 +17,7 @@ const SearchInput = ({ bgColor = "bg-sky-500", textHighlight = "text-sky-500", i
|
|
|
18
17
|
return (_jsx("div", { ref: containerRef, className: "", children: (() => {
|
|
19
18
|
switch (inputType) {
|
|
20
19
|
case "text":
|
|
21
|
-
return (_jsx(SearchTextInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, searchItems: searchItems, setSearchItems: setSearchItems, handleFilter: handleFilter, column: column,
|
|
20
|
+
return (_jsx(SearchTextInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, searchItems: searchItems, setSearchItems: setSearchItems, handleFilter: handleFilter, setSearchCriteria: setSearchCriteria, column: column, setEditingHeader: setEditingHeader }));
|
|
22
21
|
case "number":
|
|
23
22
|
return (_jsx(SearchNumberInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, handleFilter: handleFilter }));
|
|
24
23
|
case "multiSelect":
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import SearchInput from "./SearchInput";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
// Mock data for column
|
|
5
|
+
const mockColumn = {
|
|
6
|
+
id: "mockColumn",
|
|
7
|
+
Header: "Mock Column",
|
|
8
|
+
};
|
|
4
9
|
export default {
|
|
5
10
|
title: "Components/SearchInput",
|
|
6
11
|
component: SearchInput,
|
|
@@ -24,10 +29,6 @@ export default {
|
|
|
24
29
|
control: "text",
|
|
25
30
|
description: "Currently selected dropdown option",
|
|
26
31
|
},
|
|
27
|
-
onDropdownOptionSelect: {
|
|
28
|
-
action: "selected",
|
|
29
|
-
description: "Callback when dropdown option is selected",
|
|
30
|
-
},
|
|
31
32
|
searchItems: {
|
|
32
33
|
control: "array",
|
|
33
34
|
description: "Array of search items",
|
|
@@ -39,35 +40,35 @@ export default {
|
|
|
39
40
|
},
|
|
40
41
|
parameters: { layout: "centered" },
|
|
41
42
|
};
|
|
42
|
-
//
|
|
43
|
-
const mockColumn = {
|
|
44
|
-
id: "mockColumn",
|
|
45
|
-
Header: "Mock Column",
|
|
46
|
-
};
|
|
43
|
+
// Updated Template with state for searchCriteria and editingHeader
|
|
47
44
|
const Template = (args) => {
|
|
48
45
|
const [selectedOption, setSelectedOption] = useState(args.selectedDropdownOption);
|
|
49
46
|
const [searchItems, setSearchItems] = useState([]);
|
|
50
47
|
const [toggleStatus, setToggleStatus] = useState(false);
|
|
51
|
-
const [minValue, setMinValue] = useState();
|
|
52
|
-
const [maxValue, setMaxValue] = useState();
|
|
48
|
+
const [minValue, setMinValue] = useState(undefined);
|
|
49
|
+
const [maxValue, setMaxValue] = useState(undefined);
|
|
53
50
|
const [selectedValue, setSelectedValue] = useState(args.selectedValue || []);
|
|
54
51
|
// NEW: State for date control
|
|
55
52
|
const [selectedDate, setSelectedDate] = useState(args.selectedDate);
|
|
56
53
|
const [selectedStartDate, setSelectedStartDate] = useState(args.selectedStartDate);
|
|
57
54
|
const [selectedEndDate, setSelectedEndDate] = useState(args.selectedEndDate);
|
|
55
|
+
// NEW: State for searchCriteria and editingHeader
|
|
56
|
+
const [searchCriteria, setSearchCriteria] = useState([]);
|
|
57
|
+
const [editingHeader, setEditingHeader] = useState(null);
|
|
58
58
|
// Handle onChange from the multi-select
|
|
59
59
|
const handleOnChange = (newSelected) => {
|
|
60
60
|
setSelectedValue(newSelected);
|
|
61
|
-
// Call the original onChange if provided in the story args
|
|
62
61
|
args.onChange?.(newSelected);
|
|
63
62
|
console.log("Selected items:", newSelected);
|
|
64
63
|
};
|
|
65
|
-
return (_jsx(SearchInput, { ...args, selectedDropdownOption: selectedOption, onDropdownOptionSelect: (option) => setSelectedOption(option), searchItems: searchItems, setSearchItems: setSearchItems, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, onChange: handleOnChange, selectedValue: selectedValue, selectedDate: selectedDate, onDateSelect: setSelectedDate, selectedStartDate: selectedStartDate, onStartDateSelect: setSelectedStartDate, selectedEndDate: selectedEndDate, onEndDateSelect: setSelectedEndDate
|
|
64
|
+
return (_jsx(SearchInput, { ...args, column: mockColumn, selectedDropdownOption: selectedOption, onDropdownOptionSelect: (option) => setSelectedOption(option), searchItems: searchItems, setSearchItems: setSearchItems, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, onChange: handleOnChange, selectedValue: selectedValue, selectedDate: selectedDate, onDateSelect: setSelectedDate, selectedStartDate: selectedStartDate, onStartDateSelect: setSelectedStartDate, selectedEndDate: selectedEndDate, onEndDateSelect: setSelectedEndDate, setSearchCriteria: setSearchCriteria, setEditingHeader: setEditingHeader,
|
|
65
|
+
// Optionally pass in handleFilter, or use the default from args
|
|
66
|
+
handleFilter: args.handleFilter }));
|
|
66
67
|
};
|
|
67
68
|
export const Default = Template.bind({});
|
|
68
69
|
Default.args = {
|
|
69
70
|
inputType: "text",
|
|
70
|
-
handleFilter: () => console.log(
|
|
71
|
+
handleFilter: () => console.log("Filter applied"),
|
|
71
72
|
dropdownOptions: [
|
|
72
73
|
"Starts with",
|
|
73
74
|
"Ends with",
|
|
@@ -80,7 +81,7 @@ Default.args = {
|
|
|
80
81
|
export const TextInput = Template.bind({});
|
|
81
82
|
TextInput.args = {
|
|
82
83
|
inputType: "text",
|
|
83
|
-
handleFilter: () => console.log(
|
|
84
|
+
handleFilter: () => console.log("Filter applied"),
|
|
84
85
|
pillColor: "bg-sky-500",
|
|
85
86
|
textHighlight: "text-sky-500",
|
|
86
87
|
dropdownIconProp: {
|
|
@@ -100,7 +101,7 @@ TextInput.args = {
|
|
|
100
101
|
export const NumberInput = Template.bind({});
|
|
101
102
|
NumberInput.args = {
|
|
102
103
|
inputType: "number",
|
|
103
|
-
handleFilter: () => console.log(
|
|
104
|
+
handleFilter: () => console.log("Filter applied"),
|
|
104
105
|
dropdownIconProp: {
|
|
105
106
|
iconClasses: "text-sky-500",
|
|
106
107
|
name: "chevronDown",
|
|
@@ -112,7 +113,7 @@ NumberInput.args = {
|
|
|
112
113
|
export const DropdownInput = Template.bind({});
|
|
113
114
|
DropdownInput.args = {
|
|
114
115
|
inputType: "multiSelect",
|
|
115
|
-
handleFilter: () => console.log(
|
|
116
|
+
handleFilter: () => console.log("Filter applied"),
|
|
116
117
|
placeholder: "Search",
|
|
117
118
|
dropdownOptions: [
|
|
118
119
|
{ uuid: "1", name: "Option 1", value: "option1" },
|
|
@@ -129,7 +130,7 @@ DropdownInput.args = {
|
|
|
129
130
|
export const BooleanInput = Template.bind({});
|
|
130
131
|
BooleanInput.args = {
|
|
131
132
|
inputType: "multiSelect",
|
|
132
|
-
handleFilter: () => console.log(
|
|
133
|
+
handleFilter: () => console.log("Filter applied"),
|
|
133
134
|
placeholder: "Search",
|
|
134
135
|
dropdownOptions: [
|
|
135
136
|
{ uuid: "1", name: "True", value: "true" },
|
|
@@ -145,7 +146,7 @@ BooleanInput.args = {
|
|
|
145
146
|
export const DatePickerInput = Template.bind({});
|
|
146
147
|
DatePickerInput.args = {
|
|
147
148
|
inputType: "date",
|
|
148
|
-
handleFilter: () => console.log(
|
|
149
|
+
handleFilter: () => console.log("Filter applied"),
|
|
149
150
|
textHighlight: "text-sky-500",
|
|
150
151
|
dropdownOptions: ["Exactly", "Before", "After"],
|
|
151
152
|
selectedDropdownOption: "Exactly",
|
|
@@ -41,30 +41,30 @@ const defaultProps = {
|
|
|
41
41
|
describe("SearchInput Component", () => {
|
|
42
42
|
describe("Text Input", () => {
|
|
43
43
|
test("renders search input field", () => {
|
|
44
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
44
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
45
45
|
expect(screen.getByPlaceholderText("Search")).toBeInTheDocument();
|
|
46
46
|
});
|
|
47
47
|
test("updates input value on change", () => {
|
|
48
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
48
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
49
49
|
const input = screen.getByPlaceholderText("Search");
|
|
50
50
|
fireEvent.change(input, { target: { value: "Test Input" } });
|
|
51
51
|
expect(input).toHaveValue("Test Input");
|
|
52
52
|
});
|
|
53
53
|
test("does not add empty search input to search items on enter press", () => {
|
|
54
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
54
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
55
55
|
const input = screen.getByPlaceholderText("Search");
|
|
56
56
|
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
57
57
|
expect(mockSetSearchItems).toHaveBeenCalled();
|
|
58
58
|
});
|
|
59
59
|
test("adds valid input to search items on enter press", () => {
|
|
60
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
60
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
61
61
|
const input = screen.getByPlaceholderText("Search");
|
|
62
62
|
fireEvent.change(input, { target: { value: "New Search" } });
|
|
63
63
|
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
64
64
|
expect(mockSetSearchItems).toHaveBeenCalledWith(["New Search"]);
|
|
65
65
|
});
|
|
66
66
|
test("clears input when clear icon is clicked", () => {
|
|
67
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
67
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
68
68
|
const input = screen.getByPlaceholderText("Search");
|
|
69
69
|
fireEvent.change(input, { target: { value: "Clear me" } });
|
|
70
70
|
const clearIcon = screen.getByTestId("clear-icon");
|
|
@@ -72,18 +72,18 @@ describe("SearchInput Component", () => {
|
|
|
72
72
|
expect(input).toHaveValue("");
|
|
73
73
|
});
|
|
74
74
|
test("removes search criterion when delete icon is clicked", () => {
|
|
75
|
-
render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Test Item"] }));
|
|
75
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, searchItems: ["Test Item"] }));
|
|
76
76
|
fireEvent.click(screen.getByText("Test Item")); // Assuming clicking the item removes it
|
|
77
77
|
expect(mockSetSearchItems).toHaveBeenCalledWith([]);
|
|
78
78
|
});
|
|
79
79
|
test("renders dropdown with options", () => {
|
|
80
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
80
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
81
81
|
const dropdownTrigger = screen.getByText("Option 1"); // Default selected option
|
|
82
82
|
fireEvent.click(dropdownTrigger);
|
|
83
83
|
expect(screen.getByText("Option 2")).toBeInTheDocument();
|
|
84
84
|
});
|
|
85
85
|
test("calls dropdown selection handler when an option is clicked", () => {
|
|
86
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
86
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
87
87
|
const dropdownTrigger = screen.getByText("Option 1");
|
|
88
88
|
fireEvent.click(dropdownTrigger);
|
|
89
89
|
const option = screen.getByText("Option 2");
|
|
@@ -92,25 +92,25 @@ describe("SearchInput Component", () => {
|
|
|
92
92
|
expect(mockOnDropdownOptionSelect).toHaveBeenCalledWith("Option 2");
|
|
93
93
|
});
|
|
94
94
|
test("handles multiple items in search field", () => {
|
|
95
|
-
render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
95
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
96
96
|
expect(screen.getByText("Item 1")).toBeInTheDocument();
|
|
97
97
|
expect(screen.getByText("Item 2")).toBeInTheDocument();
|
|
98
98
|
});
|
|
99
99
|
test("removes individual search item when close icon is clicked", () => {
|
|
100
|
-
render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
100
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
101
101
|
const item1 = screen.getByText("Item 1");
|
|
102
102
|
fireEvent.click(item1);
|
|
103
103
|
expect(mockSetSearchItems).toHaveBeenCalledWith(["Item 2"]);
|
|
104
104
|
});
|
|
105
105
|
test("clears all search items when clicking on clear button", () => {
|
|
106
|
-
render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
106
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
|
|
107
107
|
const clearIcons = screen.getAllByTestId("item-clear-icon");
|
|
108
108
|
expect(clearIcons).toHaveLength(2);
|
|
109
109
|
clearIcons.forEach((icon) => fireEvent.click(icon));
|
|
110
110
|
expect(mockSetSearchItems).toHaveBeenCalled();
|
|
111
111
|
});
|
|
112
112
|
test("renders a different dropdown icon when dropdownIconProp is provided", () => {
|
|
113
|
-
render(_jsx(SearchInput, { ...defaultProps, dropdownIconProp: {
|
|
113
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, dropdownIconProp: {
|
|
114
114
|
iconClasses: "text-red-500",
|
|
115
115
|
name: "arrowDown",
|
|
116
116
|
weight: "bold",
|
|
@@ -120,7 +120,7 @@ describe("SearchInput Component", () => {
|
|
|
120
120
|
console.log(dropdownIconContainer.classList);
|
|
121
121
|
});
|
|
122
122
|
test("does not add input text to search items when non-Enter key is pressed", () => {
|
|
123
|
-
render(_jsx(SearchInput, { ...defaultProps }));
|
|
123
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps }));
|
|
124
124
|
const input = screen.getByPlaceholderText("Search");
|
|
125
125
|
fireEvent.change(input, { target: { value: "Test Input" } });
|
|
126
126
|
const initialCallCount = mockSetSearchItems.mock.calls.length;
|
|
@@ -131,45 +131,45 @@ describe("SearchInput Component", () => {
|
|
|
131
131
|
});
|
|
132
132
|
describe("Number Input", () => {
|
|
133
133
|
test("renders number input fields", () => {
|
|
134
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number" }));
|
|
134
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number" }));
|
|
135
135
|
expect(screen.getByPlaceholderText("Amount")).toBeInTheDocument();
|
|
136
136
|
});
|
|
137
137
|
test("shows min and max fields only when toggle is clicked", () => {
|
|
138
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: false }));
|
|
138
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", toggleStatus: false }));
|
|
139
139
|
const toggleCheckbox = screen.getByRole("checkbox");
|
|
140
140
|
expect(toggleCheckbox).toBeInTheDocument();
|
|
141
141
|
fireEvent.click(toggleCheckbox);
|
|
142
142
|
expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
|
|
143
143
|
// Re-render the component with the updated state
|
|
144
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
144
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
145
145
|
expect(screen.getByPlaceholderText("Min")).toBeInTheDocument();
|
|
146
146
|
expect(screen.getByPlaceholderText("Max")).toBeInTheDocument();
|
|
147
147
|
});
|
|
148
148
|
test("updates min value on change after toggle is clicked", () => {
|
|
149
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
149
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
150
150
|
const minInput = screen.getByPlaceholderText("Min");
|
|
151
151
|
fireEvent.change(minInput, { target: { value: "10" } });
|
|
152
152
|
expect(mockSetMinValue).toHaveBeenCalledWith("10");
|
|
153
153
|
});
|
|
154
154
|
test("updates max value on change after toggle is clicked", () => {
|
|
155
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
155
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
156
156
|
const maxInput = screen.getByPlaceholderText("Max");
|
|
157
157
|
fireEvent.change(maxInput, { target: { value: "100" } });
|
|
158
158
|
expect(mockSetMaxValue).toHaveBeenCalledWith("100");
|
|
159
159
|
});
|
|
160
160
|
test("Filter button should be present", () => {
|
|
161
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number" }));
|
|
161
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number" }));
|
|
162
162
|
const filterButton = screen.getByText("Filter");
|
|
163
163
|
expect(filterButton).toBeInTheDocument();
|
|
164
164
|
});
|
|
165
165
|
test("updates min value on input change", () => {
|
|
166
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
166
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", toggleStatus: true }));
|
|
167
167
|
const minInput = screen.getByPlaceholderText("Min");
|
|
168
168
|
fireEvent.change(minInput, { target: { value: "25" } });
|
|
169
169
|
expect(mockSetMinValue).toHaveBeenCalledWith("25");
|
|
170
170
|
});
|
|
171
171
|
test("renders a different dropdown icon when dropdownIconProp is provided", () => {
|
|
172
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "number", dropdownIconProp: {
|
|
172
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "number", dropdownIconProp: {
|
|
173
173
|
iconClasses: "text-red-500",
|
|
174
174
|
name: "arrowDown",
|
|
175
175
|
weight: "bold",
|
|
@@ -180,13 +180,13 @@ describe("SearchInput Component", () => {
|
|
|
180
180
|
});
|
|
181
181
|
describe("Dropdown Input", () => {
|
|
182
182
|
test("renders dropdown input with placeholder", () => {
|
|
183
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect" }));
|
|
183
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect" }));
|
|
184
184
|
// Ensure the dropdown renders with the placeholder "Search"
|
|
185
185
|
expect(screen.getByText("Search")).toBeInTheDocument();
|
|
186
186
|
});
|
|
187
187
|
test("opens dropdown and selects an option", async () => {
|
|
188
188
|
const mockOnChange = vi.fn();
|
|
189
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
189
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
190
190
|
{
|
|
191
191
|
uuid: "1",
|
|
192
192
|
name: "Option 1",
|
|
@@ -210,14 +210,14 @@ describe("SearchInput Component", () => {
|
|
|
210
210
|
expect(mockOnChange).toHaveBeenCalled();
|
|
211
211
|
});
|
|
212
212
|
test("clears all selections when Clear button is clicked", () => {
|
|
213
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", selectedValue: [{ name: "Option 1", value: "option1" }] }));
|
|
213
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", selectedValue: [{ name: "Option 1", value: "option1" }] }));
|
|
214
214
|
const clearButton = screen.getByRole("button", { name: /clear/i });
|
|
215
215
|
fireEvent.click(clearButton);
|
|
216
216
|
expect(mockOnChange).toHaveBeenCalledWith([]);
|
|
217
217
|
});
|
|
218
218
|
test("Clears when Clear button is clicked", async () => {
|
|
219
219
|
const mockOnChange = vi.fn();
|
|
220
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
220
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
221
221
|
{
|
|
222
222
|
uuid: "1",
|
|
223
223
|
name: "Option 1",
|
|
@@ -240,7 +240,7 @@ describe("SearchInput Component", () => {
|
|
|
240
240
|
test("calls handleFilter on Filter button click and stops propagation", async () => {
|
|
241
241
|
const mockHandleFilter = vi.fn();
|
|
242
242
|
const mockStopPropagation = vi.fn();
|
|
243
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", handleFilter: mockHandleFilter, dropdownOptions: [
|
|
243
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", handleFilter: mockHandleFilter, dropdownOptions: [
|
|
244
244
|
{
|
|
245
245
|
uuid: "1",
|
|
246
246
|
name: "Option 1",
|
|
@@ -264,7 +264,7 @@ describe("SearchInput Component", () => {
|
|
|
264
264
|
describe("Boolean Input", () => {
|
|
265
265
|
const mockOnChange = vi.fn();
|
|
266
266
|
test("renders boolean input with placeholder", () => {
|
|
267
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", dropdownOptions: [
|
|
267
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", dropdownOptions: [
|
|
268
268
|
{
|
|
269
269
|
uuid: "1",
|
|
270
270
|
name: "True",
|
|
@@ -281,7 +281,7 @@ describe("SearchInput Component", () => {
|
|
|
281
281
|
expect(screen.getByText(/Search/i)).toBeInTheDocument();
|
|
282
282
|
});
|
|
283
283
|
test("opens boolean dropdown and selects an option", async () => {
|
|
284
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
284
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
|
|
285
285
|
{
|
|
286
286
|
uuid: "1",
|
|
287
287
|
name: "True",
|
|
@@ -303,7 +303,7 @@ describe("SearchInput Component", () => {
|
|
|
303
303
|
expect(mockOnChange).toHaveBeenCalledWith(expect.arrayContaining([{ name: "True", value: "true" }]));
|
|
304
304
|
});
|
|
305
305
|
test("clears all selections when Clear button is clicked", async () => {
|
|
306
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", selectedValue: [{ uuid: "1", name: "True", value: "true" }], onChange: mockOnChange, dropdownOptions: [
|
|
306
|
+
render(_jsx(SearchInput, { column: undefined, setEditingHeader: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "multiSelect", selectedValue: [{ uuid: "1", name: "True", value: "true" }], onChange: mockOnChange, dropdownOptions: [
|
|
307
307
|
{
|
|
308
308
|
uuid: "1",
|
|
309
309
|
name: "True",
|
|
@@ -359,48 +359,48 @@ describe("SearchInput Component", () => {
|
|
|
359
359
|
value: [],
|
|
360
360
|
};
|
|
361
361
|
test("renders single date picker input inside SearchInput", () => {
|
|
362
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
362
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
363
363
|
expect(screen.getByText("Select Date")).toBeInTheDocument();
|
|
364
364
|
});
|
|
365
365
|
test("opens date picker when input is clicked", () => {
|
|
366
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
366
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
367
367
|
const dateInput = screen.getByText("Select Date");
|
|
368
368
|
fireEvent.click(dateInput);
|
|
369
369
|
expect(screen.getByRole("grid")).toBeInTheDocument(); // DayPicker should appear
|
|
370
370
|
});
|
|
371
371
|
test("selects a single date from the picker", () => {
|
|
372
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
372
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
373
373
|
fireEvent.click(screen.getByText("Select Date"));
|
|
374
374
|
const today = new Date().getDate();
|
|
375
375
|
fireEvent.click(screen.getByText(today.toString()));
|
|
376
376
|
expect(mockOnDateSelect).toHaveBeenCalled();
|
|
377
377
|
});
|
|
378
378
|
test("renders range date picker inputs when toggle is clicked", () => {
|
|
379
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
379
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
380
380
|
expect(screen.getByText("Start Date")).toBeInTheDocument();
|
|
381
381
|
expect(screen.getByText("End Date")).toBeInTheDocument();
|
|
382
382
|
});
|
|
383
383
|
test("opens start date picker when Start Date is clicked", () => {
|
|
384
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
384
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
385
385
|
const startDateInput = screen.getByText("Start Date");
|
|
386
386
|
fireEvent.click(startDateInput);
|
|
387
387
|
expect(screen.getByRole("grid")).toBeInTheDocument();
|
|
388
388
|
});
|
|
389
389
|
test("opens end date picker when End Date is clicked", () => {
|
|
390
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
390
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
391
391
|
const endDateInput = screen.getByText("End Date");
|
|
392
392
|
fireEvent.click(endDateInput);
|
|
393
393
|
expect(screen.getByRole("grid")).toBeInTheDocument();
|
|
394
394
|
});
|
|
395
395
|
test("selects a start date from the picker", () => {
|
|
396
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
396
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
397
397
|
fireEvent.click(screen.getByText("Start Date"));
|
|
398
398
|
const today = new Date().getDate();
|
|
399
399
|
fireEvent.click(screen.getByText(today.toString()));
|
|
400
400
|
expect(mockOnStartDateSelect).toHaveBeenCalled();
|
|
401
401
|
});
|
|
402
402
|
test("selects an end date from the picker", () => {
|
|
403
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
403
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
404
404
|
fireEvent.click(screen.getByText("End Date"));
|
|
405
405
|
const tomorrow = new Date();
|
|
406
406
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
@@ -408,7 +408,7 @@ describe("SearchInput Component", () => {
|
|
|
408
408
|
expect(mockOnEndDateSelect).toHaveBeenCalled();
|
|
409
409
|
});
|
|
410
410
|
test("closes date picker when clicking outside", () => {
|
|
411
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
411
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
412
412
|
const dateInput = screen.getByText("Select Date");
|
|
413
413
|
fireEvent.click(dateInput);
|
|
414
414
|
expect(screen.getByRole("grid")).toBeInTheDocument(); // Calendar is open
|
|
@@ -417,7 +417,7 @@ describe("SearchInput Component", () => {
|
|
|
417
417
|
expect(screen.queryByRole("grid")).not.toBeInTheDocument(); // Calendar should be closed
|
|
418
418
|
});
|
|
419
419
|
test("calls handleSubmitClick and closes date picker when Filter button is clicked", () => {
|
|
420
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
420
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
421
421
|
fireEvent.click(screen.getByText("Select Date")); // Open the calendar
|
|
422
422
|
expect(screen.getByRole("grid")).toBeInTheDocument();
|
|
423
423
|
fireEvent.click(screen.getByText("Filter")); // Click the filter button
|
|
@@ -425,7 +425,7 @@ describe("SearchInput Component", () => {
|
|
|
425
425
|
expect(screen.queryByRole("grid")).not.toBeInTheDocument(); // Ensure picker is closed
|
|
426
426
|
});
|
|
427
427
|
test("does not close date picker if clicking inside", () => {
|
|
428
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
428
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
429
429
|
fireEvent.click(screen.getByText("Select Date")); // Open the calendar
|
|
430
430
|
expect(screen.getByRole("grid")).toBeInTheDocument();
|
|
431
431
|
// Simulate clicking inside
|
|
@@ -433,7 +433,7 @@ describe("SearchInput Component", () => {
|
|
|
433
433
|
expect(screen.getByRole("grid")).toBeInTheDocument(); // Calendar should remain open
|
|
434
434
|
});
|
|
435
435
|
test("ensures handleSubmitClick closes the date picker and resets active input", () => {
|
|
436
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
436
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
437
437
|
fireEvent.click(screen.getByText("Select Date"));
|
|
438
438
|
expect(screen.getByRole("grid")).toBeInTheDocument();
|
|
439
439
|
fireEvent.click(screen.getByText("Filter"));
|
|
@@ -441,13 +441,13 @@ describe("SearchInput Component", () => {
|
|
|
441
441
|
expect(screen.queryByRole("grid")).not.toBeInTheDocument();
|
|
442
442
|
});
|
|
443
443
|
test("ensures clicking on dropdown opens dropdown options", () => {
|
|
444
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
444
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
445
445
|
const dropdownTrigger = screen.getByText("Option 1");
|
|
446
446
|
fireEvent.click(dropdownTrigger);
|
|
447
447
|
expect(screen.getByText("Option 2")).toBeInTheDocument();
|
|
448
448
|
});
|
|
449
449
|
test("ensures clicking on an option in dropdown selects it", () => {
|
|
450
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
450
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
451
451
|
const dropdownTrigger = screen.getByText("Option 1");
|
|
452
452
|
fireEvent.click(dropdownTrigger);
|
|
453
453
|
const option = screen.getByText("Option 2");
|
|
@@ -455,13 +455,13 @@ describe("SearchInput Component", () => {
|
|
|
455
455
|
expect(defaultProps.onDropdownOptionSelect).toHaveBeenCalledWith("Option 2");
|
|
456
456
|
});
|
|
457
457
|
test("ensures toggle button switches mode correctly", () => {
|
|
458
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
458
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
459
459
|
const toggleCheckbox = screen.getByRole("checkbox");
|
|
460
460
|
fireEvent.click(toggleCheckbox);
|
|
461
461
|
expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
|
|
462
462
|
});
|
|
463
463
|
test("ensures selecting a start and end date updates state", () => {
|
|
464
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
464
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
465
465
|
fireEvent.click(screen.getByText("Start Date"));
|
|
466
466
|
fireEvent.click(screen.getByText(new Date().getDate().toString()));
|
|
467
467
|
expect(mockOnStartDateSelect).toHaveBeenCalled();
|
|
@@ -470,20 +470,20 @@ describe("SearchInput Component", () => {
|
|
|
470
470
|
expect(mockOnEndDateSelect).toHaveBeenCalled();
|
|
471
471
|
});
|
|
472
472
|
test("toggles range mode when toggle button is clicked", () => {
|
|
473
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
473
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
474
474
|
const toggleCheckbox = screen.getByRole("checkbox");
|
|
475
475
|
fireEvent.click(toggleCheckbox);
|
|
476
476
|
expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
|
|
477
477
|
});
|
|
478
478
|
test("renders selectedStartDate if provided, otherwise shows default text", () => {
|
|
479
479
|
const mockStartDate = new Date(2023, 5, 15); // June 15, 2023
|
|
480
|
-
const { rerender } = render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: null }));
|
|
480
|
+
const { rerender } = render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: null }));
|
|
481
481
|
expect(screen.getByText("Start Date")).toBeInTheDocument();
|
|
482
|
-
rerender(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: mockStartDate }));
|
|
482
|
+
rerender(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: mockStartDate }));
|
|
483
483
|
expect(screen.getByText(mockStartDate.toLocaleDateString())).toBeInTheDocument();
|
|
484
484
|
});
|
|
485
485
|
test("calls onStartDateSelect when a start date is selected", () => {
|
|
486
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
486
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
487
487
|
// Open the Start Date Picker
|
|
488
488
|
fireEvent.click(screen.getByText("Start Date"));
|
|
489
489
|
// Pick a date (e.g., today's date)
|
|
@@ -493,7 +493,7 @@ describe("SearchInput Component", () => {
|
|
|
493
493
|
expect(mockOnStartDateSelect).toHaveBeenCalled();
|
|
494
494
|
});
|
|
495
495
|
test("calls onEndDateSelect when an end date is selected", () => {
|
|
496
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
496
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", toggleStatus: true }));
|
|
497
497
|
// Open the End Date Picker
|
|
498
498
|
fireEvent.click(screen.getByText("End Date"));
|
|
499
499
|
const tomorrow = new Date();
|
|
@@ -503,7 +503,7 @@ describe("SearchInput Component", () => {
|
|
|
503
503
|
expect(mockOnEndDateSelect).toHaveBeenCalled();
|
|
504
504
|
});
|
|
505
505
|
test("calls onDateSelect when a single date is selected", () => {
|
|
506
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
|
|
506
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date" }));
|
|
507
507
|
// Open the Date Picker
|
|
508
508
|
fireEvent.click(screen.getByText("Select Date"));
|
|
509
509
|
const today = new Date().getDate();
|
|
@@ -512,7 +512,7 @@ describe("SearchInput Component", () => {
|
|
|
512
512
|
expect(mockOnDateSelect).toHaveBeenCalled();
|
|
513
513
|
});
|
|
514
514
|
test("shows placeholder text when no date is selected", () => {
|
|
515
|
-
render(_jsx(SearchInput, { ...defaultProps, inputType: "date", selectedDate: null }));
|
|
515
|
+
render(_jsx(SearchInput, { column: undefined, setSearchCriteria: undefined, ...defaultProps, inputType: "date", selectedDate: null }));
|
|
516
516
|
expect(screen.getByText("Select Date")).toBeInTheDocument();
|
|
517
517
|
});
|
|
518
518
|
});
|
|
@@ -29,8 +29,9 @@ export type SearchInputProps<T extends object> = {
|
|
|
29
29
|
onStartDateSelect?: (date: Date) => void;
|
|
30
30
|
selectedEndDate?: Date;
|
|
31
31
|
onEndDateSelect?: (date: Date) => void;
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
column: any;
|
|
33
|
+
setEditingHeader: any;
|
|
34
|
+
setSearchCriteria: any;
|
|
34
35
|
};
|
|
35
36
|
export interface OptionType {
|
|
36
37
|
uuid: string;
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { ColumnInstance } from "react-table";
|
|
3
2
|
import { searchDropdownIconProps } from "./SearchInput.types";
|
|
4
|
-
export type SearchCriterion<T extends object> = {
|
|
5
|
-
searchColumn: ColumnInstance<T>;
|
|
6
|
-
submittedSearchText: string;
|
|
7
|
-
};
|
|
8
3
|
type SearchTextInputProps<T extends object> = {
|
|
9
4
|
pillColor?: string;
|
|
10
5
|
textHighlight?: string;
|
|
@@ -14,11 +9,11 @@ type SearchTextInputProps<T extends object> = {
|
|
|
14
9
|
dropdownOptions?: string[];
|
|
15
10
|
searchItems?: string[];
|
|
16
11
|
setSearchItems?: React.Dispatch<React.SetStateAction<string[]>>;
|
|
17
|
-
searchCriteria?: SearchCriterion<T>[];
|
|
18
|
-
setSearchCriteria?: React.Dispatch<React.SetStateAction<SearchCriterion<T>[]>>;
|
|
19
|
-
column: ColumnInstance<T>;
|
|
20
12
|
handleFilter?: () => void;
|
|
13
|
+
setSearchCriteria: React.Dispatch<React.SetStateAction<any[]>>;
|
|
14
|
+
column: any;
|
|
15
|
+
setEditingHeader: React.Dispatch<React.SetStateAction<any>>;
|
|
21
16
|
localStorageKey?: string;
|
|
22
17
|
};
|
|
23
|
-
declare const SearchTextInput: <T extends object>({ pillColor, textHighlight, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect,
|
|
18
|
+
declare const SearchTextInput: <T extends object>({ pillColor, textHighlight, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, handleFilter, setSearchCriteria, column, setEditingHeader, localStorageKey, }: SearchTextInputProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
24
19
|
export default SearchTextInput;
|
|
@@ -2,89 +2,94 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { AnimatePresence, motion } from "framer-motion";
|
|
4
4
|
import { Input } from "../Input";
|
|
5
|
+
import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
|
|
5
6
|
import Dropdown from "../Dropdown/Dropdown";
|
|
6
7
|
import Badge from "../Badge/Badge";
|
|
7
8
|
import Text from "../Text";
|
|
8
|
-
import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
|
|
9
9
|
const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-500", dropdownIconProp = {
|
|
10
10
|
iconClasses: textHighlight,
|
|
11
11
|
name: "chevronDown",
|
|
12
12
|
weight: "solid",
|
|
13
|
-
}, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect,
|
|
13
|
+
}, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEditingHeader, localStorageKey = "searchCriteria", }) => {
|
|
14
14
|
const containerRef = useRef(null);
|
|
15
15
|
const [localSearchText, setLocalSearchText] = useState("");
|
|
16
16
|
const inputRef = useRef(null);
|
|
17
|
-
// On mount,
|
|
17
|
+
// On mount, load any persisted search criteria from local storage using the provided key
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
inputRef.current?.focus();
|
|
20
20
|
const stored = localStorage.getItem(localStorageKey);
|
|
21
|
-
if (stored
|
|
21
|
+
if (stored) {
|
|
22
22
|
try {
|
|
23
23
|
const parsed = JSON.parse(stored);
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const existing = parsed.find((criterion) => criterion.searchColumn.id === column.id);
|
|
25
|
+
if (existing) {
|
|
26
|
+
setLocalSearchText(existing.submittedSearchText);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
catch (
|
|
29
|
-
console.error("Error parsing
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error("Error parsing stored search criteria:", error);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
}, [
|
|
33
|
+
}, [column.id, localStorageKey]);
|
|
34
|
+
// Helper to update local storage using the dynamic key
|
|
35
|
+
const updateLocalStorage = (criteria) => {
|
|
36
|
+
localStorage.setItem(localStorageKey, JSON.stringify(criteria));
|
|
37
|
+
};
|
|
33
38
|
const handleInputChange = (event) => {
|
|
34
39
|
setLocalSearchText(event.target.value);
|
|
35
40
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
version: 0,
|
|
41
|
-
}));
|
|
42
|
-
};
|
|
43
|
-
const handleSubmit = () => {
|
|
44
|
-
const trimmed = localSearchText.trim();
|
|
45
|
-
if (!trimmed)
|
|
46
|
-
return;
|
|
47
|
-
let newCriteria;
|
|
48
|
-
if (searchCriteria.some((c) => c.searchColumn.id === column.id)) {
|
|
49
|
-
newCriteria = searchCriteria.map((c) => c.searchColumn.id === column.id
|
|
50
|
-
? { searchColumn: column, submittedSearchText: trimmed }
|
|
51
|
-
: c);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
newCriteria = [
|
|
55
|
-
...searchCriteria,
|
|
56
|
-
{ searchColumn: column, submittedSearchText: trimmed },
|
|
57
|
-
];
|
|
58
|
-
}
|
|
59
|
-
if (setSearchCriteria) {
|
|
60
|
-
setSearchCriteria(newCriteria);
|
|
61
|
-
}
|
|
62
|
-
updateLocalStorage(newCriteria);
|
|
63
|
-
setLocalSearchText("");
|
|
64
|
-
if (handleFilter) {
|
|
65
|
-
handleFilter();
|
|
66
|
-
}
|
|
41
|
+
const handleSearchBadgeClick = (item) => {
|
|
42
|
+
// Remove criterion
|
|
43
|
+
const filteredItems = searchItems.filter((ele) => ele !== item);
|
|
44
|
+
setSearchItems && setSearchItems(filteredItems);
|
|
67
45
|
};
|
|
68
46
|
const handleKeyDown = (e) => {
|
|
69
|
-
if (e.key === "Enter") {
|
|
47
|
+
if (e.key === "Enter" && localSearchText.length > 0) {
|
|
70
48
|
e.preventDefault();
|
|
49
|
+
setSearchItems && setSearchItems([...searchItems, localSearchText]);
|
|
50
|
+
handleFilter && handleFilter();
|
|
71
51
|
handleSubmit();
|
|
72
52
|
}
|
|
73
53
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
54
|
+
const handleSubmit = () => {
|
|
55
|
+
const trimmed = localSearchText.trim();
|
|
56
|
+
if (!trimmed) {
|
|
57
|
+
setSearchCriteria((prev) => {
|
|
58
|
+
const updated = prev.filter((c) => c.searchColumn.id !== column.id);
|
|
59
|
+
updateLocalStorage(updated);
|
|
60
|
+
return updated;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setSearchCriteria((prev) => {
|
|
65
|
+
const existingIndex = prev.findIndex((c) => c.searchColumn.id === column.id);
|
|
66
|
+
let updated;
|
|
67
|
+
if (existingIndex >= 0) {
|
|
68
|
+
updated = [...prev];
|
|
69
|
+
updated[existingIndex] = {
|
|
70
|
+
searchColumn: column,
|
|
71
|
+
submittedSearchText: trimmed,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
updated = [
|
|
76
|
+
...prev,
|
|
77
|
+
{
|
|
78
|
+
searchColumn: column,
|
|
79
|
+
submittedSearchText: trimmed,
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
updateLocalStorage(updated);
|
|
84
|
+
return updated;
|
|
85
|
+
});
|
|
79
86
|
}
|
|
80
|
-
|
|
81
|
-
setLocalSearchText("");
|
|
87
|
+
setEditingHeader(null);
|
|
82
88
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.map((criterion, 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: criterion.submittedSearchText, onClick: handleClearCriterion, text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: criterion.submittedSearchText }), badgeContainerClasses: pillClassnames, type: "span" }, index))) }))] }) }));
|
|
89
|
+
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, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 py-1 h-full flex items-center", menuClasses: "bg-white min-w-32", 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", 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: () => {
|
|
90
|
+
setLocalSearchText("");
|
|
91
|
+
}, "data-testid": "clear-icon", children: getFontAwesomeIcon("xmark", "regular") }), _jsx("div", { className: `${textHighlight} text-sm hover:text-primary`, children: getFontAwesomeIcon("search", "solid") })] })) }) }), onIconClick: () => {
|
|
92
|
+
setLocalSearchText("");
|
|
93
|
+
} })] }), 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] }) }));
|
|
89
94
|
};
|
|
90
95
|
export default SearchTextInput;
|