@agilant/toga-blox 1.0.32 → 1.0.34
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/Dropdown/Dropdown.d.ts +4 -0
- package/dist/components/Dropdown/Dropdown.js +20 -0
- package/dist/components/Dropdown/Dropdown.stories.d.ts +8 -0
- package/dist/components/Dropdown/Dropdown.stories.js +110 -0
- package/dist/components/Dropdown/Dropdown.test.d.ts +1 -0
- package/dist/components/Dropdown/Dropdown.test.js +43 -0
- package/dist/components/Dropdown/Dropdown.types.d.ts +15 -0
- package/dist/components/Dropdown/Dropdown.types.js +1 -0
- package/dist/components/GenericList/GenericList.d.ts +2 -15
- package/dist/components/GenericList/GenericList.js +64 -51
- package/dist/components/GenericList/GenericList.stories.d.ts +8 -35
- package/dist/components/GenericList/GenericList.stories.js +46 -78
- package/dist/components/GenericList/GenericList.test.d.ts +1 -1
- package/dist/components/GenericList/GenericList.test.js +112 -22
- package/dist/components/GenericList/index.d.ts +2 -0
- package/dist/components/GenericList/index.js +2 -0
- package/dist/components/GenericList/types.d.ts +16 -0
- package/dist/components/GenericList/types.js +1 -0
- package/dist/components/Header/Header.stories.js +2 -4
- package/dist/components/Input/Input.d.ts +30 -3
- package/dist/components/Input/Input.js +70 -48
- package/dist/components/Input/Input.stories.js +3 -4
- package/dist/components/Input/Input.test.js +74 -42
- package/dist/components/InputAndCheck/InputAndCheck.d.ts +47 -0
- package/dist/components/InputAndCheck/InputAndCheck.js +74 -0
- package/dist/components/InputAndCheck/InputAndCheck.stories.d.ts +9 -0
- package/dist/components/InputAndCheck/InputAndCheck.stories.js +201 -0
- package/dist/components/InputAndCheck/InputAndCheck.test.d.ts +1 -0
- package/dist/components/InputAndCheck/InputAndCheck.test.js +307 -0
- package/dist/components/InputAndCheck/index.d.ts +0 -0
- package/dist/components/InputAndCheck/index.js +0 -0
- package/dist/components/InputAndCheck/types.d.ts +35 -0
- package/dist/components/InputAndCheck/types.js +1 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.d.ts +4 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.js +60 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.d.ts +9 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.js +72 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.test.d.ts +1 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.test.js +101 -0
- package/dist/components/MagnifyingIcon/index.d.ts +2 -0
- package/dist/components/MagnifyingIcon/index.js +2 -0
- package/dist/components/MagnifyingIcon/types.d.ts +20 -0
- package/dist/components/MagnifyingIcon/types.js +2 -0
- package/dist/components/MultiSelect/MultiSelect.d.ts +4 -0
- package/dist/components/MultiSelect/MultiSelect.js +30 -0
- package/dist/components/MultiSelect/MultiSelect.stories.d.ts +10 -0
- package/dist/components/MultiSelect/MultiSelect.stories.js +162 -0
- package/dist/components/MultiSelect/MultiSelect.test.d.ts +1 -0
- package/dist/components/MultiSelect/MultiSelect.test.js +107 -0
- package/dist/components/MultiSelect/MultiSelect.types.d.ts +28 -0
- package/dist/components/MultiSelect/MultiSelect.types.js +1 -0
- package/dist/components/Page/ViewPageTemplate.stories.js +2 -3
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.d.ts +3 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.js +72 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.d.ts +4 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.js +99 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.d.ts +1 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.js +124 -0
- package/dist/components/PrimaryTableHeader/index.d.ts +0 -0
- package/dist/components/PrimaryTableHeader/index.js +0 -0
- package/dist/components/PrimaryTableHeader/types.d.ts +35 -0
- package/dist/components/PrimaryTableHeader/types.js +2 -0
- package/dist/components/SearchInput/SearchInput.d.ts +1 -2
- package/dist/components/SearchInput/SearchInput.js +61 -11
- package/dist/components/SearchInput/SearchInput.stories.d.ts +2 -4
- package/dist/components/SearchInput/SearchInput.stories.js +80 -93
- package/dist/components/SearchInput/SearchInput.types.d.ts +37 -24
- package/dist/components/SearchInput/SearchNumberInput.d.ts +31 -0
- package/dist/components/SearchInput/SearchNumberInput.js +60 -0
- package/dist/components/SearchInput/SearchTextInput.d.ts +24 -0
- package/dist/components/SearchInput/SearchTextInput.js +65 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.d.ts +4 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.js +12 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.stories.d.ts +17 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.stories.js +77 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.test.d.ts +1 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.test.js +44 -0
- package/dist/components/SortArrowIcon/index.d.ts +2 -0
- package/dist/components/SortArrowIcon/index.js +2 -0
- package/dist/components/SortArrowIcon/types.d.ts +15 -0
- package/dist/components/SortArrowIcon/types.js +1 -0
- package/dist/components/SortArrows/SortArrows.d.ts +3 -0
- package/dist/components/SortArrows/SortArrows.js +33 -0
- package/dist/components/SortArrows/SortArrows.stories.d.ts +7 -0
- package/dist/components/SortArrows/SortArrows.stories.js +41 -0
- package/dist/components/SortArrows/SortArrows.test.d.ts +1 -0
- package/dist/components/SortArrows/SortArrows.test.js +150 -0
- package/dist/components/SortArrows/index.d.ts +2 -0
- package/dist/components/SortArrows/index.js +2 -0
- package/dist/components/SortArrows/types.d.ts +21 -0
- package/dist/components/SortArrows/types.js +1 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.d.ts +30 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.js +114 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.test.d.ts +1 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.test.js +100 -0
- package/dist/components/TableCell/TableCell.d.ts +3 -0
- package/dist/components/TableCell/TableCell.js +13 -0
- package/dist/components/TableCell/TableCell.stories.d.ts +16 -0
- package/dist/components/TableCell/TableCell.stories.js +99 -0
- package/dist/components/TableCell/TableCell.test.d.ts +1 -0
- package/dist/components/TableCell/TableCell.test.js +84 -0
- package/dist/components/TableCell/index.d.ts +2 -0
- package/dist/components/TableCell/index.js +2 -0
- package/dist/components/TableCell/types.d.ts +12 -0
- package/dist/components/TableCell/types.js +1 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.d.ts +3 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.js +5 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.stories.d.ts +6 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.stories.js +62 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.test.d.ts +1 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.test.js +41 -0
- package/dist/components/TableHeaderContent/index.d.ts +0 -0
- package/dist/components/TableHeaderContent/index.js +0 -0
- package/dist/components/TableHeaderContent/types.d.ts +5 -0
- package/dist/components/TableHeaderContent/types.js +1 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.d.ts +3 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.js +80 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.stories.d.ts +10 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.stories.js +82 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.test.d.ts +1 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.test.js +84 -0
- package/dist/components/TableHeaderInput/index.d.ts +1 -0
- package/dist/components/TableHeaderInput/index.js +1 -0
- package/dist/components/TableHeaderInput/types.d.ts +30 -0
- package/dist/components/TableHeaderInput/types.js +1 -0
- package/dist/components/TableRow/TableRow.d.ts +15 -0
- package/dist/components/TableRow/TableRow.js +21 -0
- package/dist/components/TableRow/TableRow.stories.d.ts +9 -0
- package/dist/components/TableRow/TableRow.stories.js +195 -0
- package/dist/components/TableRow/TableRow.test.d.ts +1 -0
- package/dist/components/TableRow/TableRow.test.js +44 -0
- package/dist/components/TableRow/index.d.ts +2 -0
- package/dist/components/TableRow/index.js +2 -0
- package/dist/components/TableRow/types.d.ts +11 -0
- package/dist/components/TableRow/types.js +1 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts +4 -0
- package/dist/components/ToggleButton/ToggleButton.js +41 -0
- package/dist/components/ToggleButton/ToggleButton.stories.d.ts +11 -0
- package/dist/components/ToggleButton/ToggleButton.stories.js +111 -0
- package/dist/components/ToggleButton/ToggleButton.test.d.ts +1 -0
- package/dist/components/ToggleButton/ToggleButton.test.js +106 -0
- package/dist/components/ToggleButton/ToggleButton.types.d.ts +22 -0
- package/dist/components/ToggleButton/ToggleButton.types.js +1 -0
- package/package.json +11 -4
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// src/components/InputAndCheck/InputAndCheck.tsx
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
|
|
5
|
+
import Badge from "../Badge";
|
|
6
|
+
import TableHeaderInput from "../TableHeaderInput";
|
|
7
|
+
/**
|
|
8
|
+
* Renders an input field for column-based searching,
|
|
9
|
+
* maintaining local text and updating searchCriteria on submit.
|
|
10
|
+
*/
|
|
11
|
+
function InputAndCheck({ closeOutSearch, setResetSearch, setEditingHeader, column, searchCriteria, setSearchCriteria, badgeColor = "bg-blue-400", badgeIcon = { icon: "x", weight: "regular" }, cancelIcon = { icon: "xmark", weight: "regular" }, iconBadgeContainerClasses = "mr-2 rounded-full p-2 text-white cursor-pointer my-2 text-sm", searchIcon = { icon: "search", weight: "regular" }, searchIconClasses = " text-md absolute right-3 top-2 text-gray-400 hover:cursor-pointer hover:text-blue-500 ", additionalInputClasses = "min-w-[300px] max-w-[250px] border-b border-t-0 border-r-0 rounded-tl-none rounded-tr-lg bg-gray-50 text-gray-800 flex", secondIconClasses = "flex absolute right-6 top-0.5 items-center text-gray-400 hover:cursor-pointer hover:text-blue-400", initialIcon = { icon: "search", weight: "regular" }, initialIconClasses = "text-gray-400", }) {
|
|
12
|
+
const containerRef = useRef(null);
|
|
13
|
+
const [localSearchText, setLocalSearchText] = useState("");
|
|
14
|
+
// On mount/update, see if we already have a search criterion for this column
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const existing = searchCriteria.find((criterion) => criterion.searchColumn.id === column.id);
|
|
17
|
+
if (existing) {
|
|
18
|
+
setLocalSearchText(existing.submittedSearchText);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
setLocalSearchText("");
|
|
22
|
+
}
|
|
23
|
+
}, [searchCriteria, column.id]);
|
|
24
|
+
// Update local text as user types
|
|
25
|
+
const handleInputChange = (e) => {
|
|
26
|
+
setLocalSearchText(e.target.value);
|
|
27
|
+
};
|
|
28
|
+
// Submit the final text to searchCriteria
|
|
29
|
+
const handleSubmit = () => {
|
|
30
|
+
const trimmed = localSearchText.trim();
|
|
31
|
+
if (!trimmed) {
|
|
32
|
+
// Clear from search criteria if empty
|
|
33
|
+
setSearchCriteria((prev) => prev.filter((c) => c.searchColumn.id !== column.id));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Insert or update existing
|
|
37
|
+
setSearchCriteria((prev) => {
|
|
38
|
+
const existingIndex = prev.findIndex((c) => c.searchColumn.id === column.id);
|
|
39
|
+
if (existingIndex >= 0) {
|
|
40
|
+
const updated = [...prev];
|
|
41
|
+
updated[existingIndex] = {
|
|
42
|
+
searchColumn: column,
|
|
43
|
+
submittedSearchText: trimmed,
|
|
44
|
+
};
|
|
45
|
+
return updated;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return [
|
|
49
|
+
...prev,
|
|
50
|
+
{ searchColumn: column, submittedSearchText: trimmed },
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Close out
|
|
56
|
+
setEditingHeader(null);
|
|
57
|
+
};
|
|
58
|
+
// Clears search from parent's state
|
|
59
|
+
const handleClearSearch = () => {
|
|
60
|
+
setSearchCriteria((prev) => prev.filter((c) => c.searchColumn.id !== column.id));
|
|
61
|
+
setLocalSearchText("");
|
|
62
|
+
setResetSearch((prev) => !prev);
|
|
63
|
+
closeOutSearch(null);
|
|
64
|
+
};
|
|
65
|
+
// Let user press Enter
|
|
66
|
+
const handleKeyDown = (e) => {
|
|
67
|
+
if (e.key === "Enter") {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
handleSubmit();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return (_jsxs("div", { ref: containerRef, className: "relative", "data-testid": "icon-search-regular", children: [_jsxs("div", { className: "flex flex-col border rounded-md shadow-md", children: [_jsx("div", { className: "flex", children: _jsx(TableHeaderInput, { hasAutoFocus: true, value: localSearchText, onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "text", onChange: handleInputChange, additionalClasses: additionalInputClasses, placeholder: "Search", hasIcons: true, firstIcon: localSearchText === "" ? (_jsx("span", { className: initialIconClasses, children: getFontAwesomeIcon(initialIcon.icon, initialIcon.weight) })) : undefined, iconPosition: "both", secondIcon: localSearchText !== "" && (_jsx("div", { className: secondIconClasses, onClick: handleClearSearch, children: getFontAwesomeIcon(cancelIcon.icon, cancelIcon.weight) })) }) }), localSearchText && (_jsx("div", { className: "bg-white flex flex-start px-2", children: _jsx(Badge, { text: localSearchText, type: "span", cursorPointer: true, onClick: handleClearSearch, hasRightIcon: true, backgroundColor: badgeColor, badgeContainerClasses: iconBadgeContainerClasses, icon: getFontAwesomeIcon(badgeIcon.icon, badgeIcon.weight) }) }))] }), localSearchText && (_jsx("div", { onClick: handleSubmit, className: searchIconClasses, children: getFontAwesomeIcon(searchIcon.icon, searchIcon.weight) }))] }));
|
|
73
|
+
}
|
|
74
|
+
export default InputAndCheck;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Meta } from "@storybook/react";
|
|
2
|
+
/**
|
|
3
|
+
* Default export for Storybook.
|
|
4
|
+
*/
|
|
5
|
+
declare const _default: Meta;
|
|
6
|
+
export default _default;
|
|
7
|
+
export declare const Default: any;
|
|
8
|
+
export declare const WithInitialSearch: any;
|
|
9
|
+
export declare const UpdateLocalStorage: any;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// InputAndCheck.stories.tsx
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import InputAndCheck from "./InputAndCheck";
|
|
5
|
+
/**
|
|
6
|
+
* Mock column from react-table.
|
|
7
|
+
*/
|
|
8
|
+
const mockColumn = {
|
|
9
|
+
id: "name",
|
|
10
|
+
// Add other ColumnInstance properties as needed
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Default export for Storybook.
|
|
14
|
+
*/
|
|
15
|
+
export default {
|
|
16
|
+
title: "Components/InputAndCheck",
|
|
17
|
+
component: InputAndCheck,
|
|
18
|
+
tags: ["autodocs"],
|
|
19
|
+
argTypes: {
|
|
20
|
+
pillColor: {
|
|
21
|
+
control: "text",
|
|
22
|
+
description: "Tailwind class(es) to set the pill background color.",
|
|
23
|
+
defaultValue: "bg-blue-600",
|
|
24
|
+
table: {
|
|
25
|
+
type: { summary: "string" },
|
|
26
|
+
defaultValue: { summary: "bg-blue-600" },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
closeOutSearch: {
|
|
30
|
+
control: false,
|
|
31
|
+
description: "Callback triggered when search is closed/cleared.",
|
|
32
|
+
table: {
|
|
33
|
+
category: "Callbacks",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
setResetSearch: {
|
|
37
|
+
control: false,
|
|
38
|
+
description: "Parent’s setter for toggling reset logic.",
|
|
39
|
+
table: {
|
|
40
|
+
category: "Callbacks",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
setEditingHeader: {
|
|
44
|
+
control: false,
|
|
45
|
+
description: "Parent’s setter used to toggle input editing mode.",
|
|
46
|
+
table: {
|
|
47
|
+
category: "Callbacks",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
column: {
|
|
51
|
+
control: false,
|
|
52
|
+
description: "A react-table ColumnInstance for identifying this input.",
|
|
53
|
+
table: {
|
|
54
|
+
category: "Data",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
searchCriteria: {
|
|
58
|
+
control: false,
|
|
59
|
+
description: "Array of existing search criteria for this table.",
|
|
60
|
+
table: {
|
|
61
|
+
category: "Data",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
setSearchCriteria: {
|
|
65
|
+
control: false,
|
|
66
|
+
description: "Setter to update the parent’s search criteria array.",
|
|
67
|
+
table: {
|
|
68
|
+
category: "Callbacks",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* ----------------------------------------------------------------------------
|
|
75
|
+
* BASIC TEMPLATE WITH LOCAL STORAGE SYNC
|
|
76
|
+
* ----------------------------------------------------------------------------
|
|
77
|
+
*/
|
|
78
|
+
const Template = (args) => {
|
|
79
|
+
const storageKey = "storybook-inputandcheck-search-criteria";
|
|
80
|
+
// Initialize searchCriteria from localStorage
|
|
81
|
+
const [searchCriteria, setSearchCriteria] = useState(() => {
|
|
82
|
+
try {
|
|
83
|
+
const saved = window.localStorage.getItem(storageKey);
|
|
84
|
+
return saved ? JSON.parse(saved) : [];
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error("Failed to parse search criteria from localStorage:", error);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const [resetSearch, setResetSearch] = useState(false);
|
|
92
|
+
const [editingHeader, setEditingHeader] = useState(null);
|
|
93
|
+
// Sync searchCriteria to localStorage
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
try {
|
|
96
|
+
window.localStorage.setItem(storageKey, JSON.stringify(searchCriteria));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error("Failed to save search criteria to localStorage:", error);
|
|
100
|
+
}
|
|
101
|
+
}, [searchCriteria, storageKey]);
|
|
102
|
+
// Optionally, clear localStorage when the story unmounts to prevent side effects
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
return () => {
|
|
105
|
+
window.localStorage.removeItem(storageKey);
|
|
106
|
+
};
|
|
107
|
+
}, [storageKey]);
|
|
108
|
+
const handleCloseOutSearch = (val) => {
|
|
109
|
+
console.log("closeOutSearch called with:", val);
|
|
110
|
+
// Implement any additional logic here
|
|
111
|
+
};
|
|
112
|
+
return (_jsxs("div", { style: { width: 300 }, children: [_jsx(InputAndCheck, { ...args, closeOutSearch: handleCloseOutSearch, setResetSearch: setResetSearch, setEditingHeader: setEditingHeader, column: mockColumn, searchCriteria: searchCriteria, setSearchCriteria: setSearchCriteria }), _jsxs("div", { style: { marginTop: 10 }, children: [_jsx("strong", { children: "Current State:" }), _jsxs("pre", { children: ["searchCriteria: ", JSON.stringify(searchCriteria, null, 2)] }), _jsxs("p", { children: ["resetSearch: ", String(resetSearch)] }), _jsxs("p", { children: ["editingHeader: ", String(editingHeader)] })] })] }));
|
|
113
|
+
};
|
|
114
|
+
export const Default = Template.bind({});
|
|
115
|
+
Default.args = {
|
|
116
|
+
pillColor: "bg-blue-600",
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* ----------------------------------------------------------------------------
|
|
120
|
+
* WITH INITIAL SEARCH
|
|
121
|
+
* ----------------------------------------------------------------------------
|
|
122
|
+
* Demonstrates having an initial search text for the column.
|
|
123
|
+
* We'll define a separate template that sets the state up front.
|
|
124
|
+
*/
|
|
125
|
+
const TemplateWithInitialSearch = (args) => {
|
|
126
|
+
const storageKey = "storybook-inputandcheck-search-criteria-initial";
|
|
127
|
+
const [searchCriteria, setSearchCriteria] = useState([
|
|
128
|
+
{
|
|
129
|
+
searchColumn: mockColumn,
|
|
130
|
+
submittedSearchText: "Initial text",
|
|
131
|
+
},
|
|
132
|
+
]);
|
|
133
|
+
const [resetSearch, setResetSearch] = useState(false);
|
|
134
|
+
const [editingHeader, setEditingHeader] = useState(null);
|
|
135
|
+
// Sync searchCriteria to localStorage
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
try {
|
|
138
|
+
window.localStorage.setItem(storageKey, JSON.stringify(searchCriteria));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error("Failed to save search criteria to localStorage:", error);
|
|
142
|
+
}
|
|
143
|
+
}, [searchCriteria, storageKey]);
|
|
144
|
+
// Optionally, clear localStorage when the story unmounts
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
return () => {
|
|
147
|
+
window.localStorage.removeItem(storageKey);
|
|
148
|
+
};
|
|
149
|
+
}, [storageKey]);
|
|
150
|
+
const handleCloseOutSearch = (val) => {
|
|
151
|
+
console.log("closeOutSearch called with:", val);
|
|
152
|
+
// Implement any additional logic here
|
|
153
|
+
};
|
|
154
|
+
return (_jsxs("div", { style: { width: 300 }, children: [_jsx(InputAndCheck, { ...args, closeOutSearch: handleCloseOutSearch, setResetSearch: setResetSearch, setEditingHeader: setEditingHeader, column: mockColumn, searchCriteria: searchCriteria, setSearchCriteria: setSearchCriteria }), _jsxs("div", { style: { marginTop: 10 }, children: [_jsx("strong", { children: "Current State:" }), _jsxs("pre", { children: ["searchCriteria: ", JSON.stringify(searchCriteria, null, 2)] }), _jsxs("p", { children: ["resetSearch: ", String(resetSearch)] }), _jsxs("p", { children: ["editingHeader: ", String(editingHeader)] })] })] }));
|
|
155
|
+
};
|
|
156
|
+
export const WithInitialSearch = TemplateWithInitialSearch.bind({});
|
|
157
|
+
WithInitialSearch.args = {
|
|
158
|
+
pillColor: "bg-blue-600",
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* ----------------------------------------------------------------------------
|
|
162
|
+
* UPDATE LOCAL STORAGE EXAMPLE
|
|
163
|
+
* ----------------------------------------------------------------------------
|
|
164
|
+
* Demonstrates updating search criteria and syncing it with localStorage.
|
|
165
|
+
*/
|
|
166
|
+
const TemplateUpdateLocalStorage = (args) => {
|
|
167
|
+
const storageKey = "storybook-inputandcheck-update-localstorage";
|
|
168
|
+
// Initialize searchCriteria from localStorage
|
|
169
|
+
const [searchCriteria, setSearchCriteria] = useState(() => {
|
|
170
|
+
try {
|
|
171
|
+
const saved = window.localStorage.getItem(storageKey);
|
|
172
|
+
return saved ? JSON.parse(saved) : [];
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
console.error("Failed to parse search criteria from localStorage:", error);
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const [resetSearch, setResetSearch] = useState(false);
|
|
180
|
+
const [editingHeader, setEditingHeader] = useState(null);
|
|
181
|
+
// Sync searchCriteria to localStorage
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
try {
|
|
184
|
+
window.localStorage.setItem(storageKey, JSON.stringify(searchCriteria));
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.error("Failed to save search criteria to localStorage:", error);
|
|
188
|
+
}
|
|
189
|
+
}, [searchCriteria, storageKey]);
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
return () => {
|
|
192
|
+
window.localStorage.removeItem(storageKey);
|
|
193
|
+
};
|
|
194
|
+
}, [storageKey]);
|
|
195
|
+
const handleCloseOutSearch = (val) => {
|
|
196
|
+
console.log("closeOutSearch called with:", val);
|
|
197
|
+
};
|
|
198
|
+
return (_jsxs("div", { style: { width: 300 }, children: [_jsx(InputAndCheck, { ...args, closeOutSearch: handleCloseOutSearch, setResetSearch: setResetSearch, setEditingHeader: setEditingHeader, column: mockColumn, searchCriteria: searchCriteria, setSearchCriteria: setSearchCriteria }), _jsxs("div", { style: { marginTop: 10 }, children: [_jsx("strong", { children: "Current State:" }), _jsxs("pre", { children: ["searchCriteria: ", JSON.stringify(searchCriteria, null, 2)] }), _jsxs("p", { children: ["resetSearch: ", String(resetSearch)] }), _jsxs("p", { children: ["editingHeader: ", String(editingHeader)] })] })] }));
|
|
199
|
+
};
|
|
200
|
+
export const UpdateLocalStorage = TemplateUpdateLocalStorage.bind({});
|
|
201
|
+
UpdateLocalStorage.storyName = "Update Local Storage (inspect localStorage)";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { render, screen, fireEvent } from "@testing-library/react";
|
|
3
|
+
import InputAndCheck from "./InputAndCheck";
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
5
|
+
// Mock the getFontAwesomeIcon utility
|
|
6
|
+
vi.mock("../../utils/getFontAwesomeIcon", () => ({
|
|
7
|
+
getFontAwesomeIcon: (iconName, style) => (_jsx("span", { "data-testid": `icon-${iconName}-${style}`, children: iconName })),
|
|
8
|
+
}));
|
|
9
|
+
// Mock Badge component
|
|
10
|
+
vi.mock("../Badge", () => ({
|
|
11
|
+
default: ({ text, onClick }) => (_jsxs("span", { "data-testid": "badge", onClick: onClick, children: [text, _jsx("span", { "data-testid": "badge-clear", children: "x" })] })),
|
|
12
|
+
}));
|
|
13
|
+
// Mock TableHeaderInput component
|
|
14
|
+
vi.mock("../TableHeaderInput", () => ({
|
|
15
|
+
default: ({ value, onChange, onKeyDown, onClick, placeholder, }) => (_jsx("input", { "data-testid": "table-header-input", value: value, onChange: onChange, onKeyDown: onKeyDown, placeholder: placeholder, onClick: onClick })),
|
|
16
|
+
}));
|
|
17
|
+
describe("InputAndCheck Component", () => {
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
let mockCloseOutSearch;
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
let mockSetResetSearch;
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
let mockSetEditingHeader;
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
let mockSetSearchCriteria;
|
|
26
|
+
let mockColumn;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
// Reset mocks before each test
|
|
29
|
+
mockCloseOutSearch = vi.fn();
|
|
30
|
+
mockSetResetSearch = vi.fn();
|
|
31
|
+
mockSetEditingHeader = vi.fn();
|
|
32
|
+
mockSetSearchCriteria = vi.fn();
|
|
33
|
+
mockColumn = {
|
|
34
|
+
id: "name",
|
|
35
|
+
// Add other necessary properties if required
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
vi.resetAllMocks();
|
|
40
|
+
window.localStorage.clear(); // Clear localStorage after each test
|
|
41
|
+
});
|
|
42
|
+
it("renders correctly with no initial search criteria", () => {
|
|
43
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: [], setSearchCriteria: mockSetSearchCriteria }));
|
|
44
|
+
// Check if input is rendered and empty
|
|
45
|
+
const input = screen.getByTestId("table-header-input");
|
|
46
|
+
expect(input).toBeInTheDocument();
|
|
47
|
+
expect(input.value).toBe("");
|
|
48
|
+
// Check that badge is not rendered
|
|
49
|
+
const badge = screen.queryByTestId("badge");
|
|
50
|
+
expect(badge).not.toBeInTheDocument();
|
|
51
|
+
// Check that the first icon (search icon) is rendered
|
|
52
|
+
const searchIcon = screen.getByTestId("icon-search-regular");
|
|
53
|
+
expect(searchIcon).toBeInTheDocument();
|
|
54
|
+
});
|
|
55
|
+
it("renders correctly with initial search criteria", () => {
|
|
56
|
+
const initialCriteria = [
|
|
57
|
+
{
|
|
58
|
+
searchColumn: mockColumn,
|
|
59
|
+
submittedSearchText: "Initial search",
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
63
|
+
// Check if input has the initial search text
|
|
64
|
+
const input = screen.getByTestId("table-header-input");
|
|
65
|
+
expect(input.value).toBe("Initial search");
|
|
66
|
+
// Check that badge is rendered with the initial search text
|
|
67
|
+
const badge = screen.getByTestId("badge");
|
|
68
|
+
expect(badge).toBeInTheDocument();
|
|
69
|
+
expect(badge).toHaveTextContent("Initial search");
|
|
70
|
+
// Check that the badge's clear button is rendered
|
|
71
|
+
const badgeClear = screen.getByTestId("badge-clear");
|
|
72
|
+
expect(badgeClear).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
it("updates localSearchText when searchCriteria prop changes", () => {
|
|
75
|
+
const { rerender } = render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: [], setSearchCriteria: mockSetSearchCriteria }));
|
|
76
|
+
const input = screen.getByTestId("table-header-input");
|
|
77
|
+
expect(input.value).toBe("");
|
|
78
|
+
// Update searchCriteria prop
|
|
79
|
+
const updatedCriteria = [
|
|
80
|
+
{
|
|
81
|
+
searchColumn: mockColumn,
|
|
82
|
+
submittedSearchText: "Updated search",
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
rerender(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: updatedCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
86
|
+
// Check if input value updated
|
|
87
|
+
expect(input.value).toBe("Updated search");
|
|
88
|
+
// Check that badge is rendered
|
|
89
|
+
const badge = screen.getByTestId("badge");
|
|
90
|
+
expect(badge).toBeInTheDocument();
|
|
91
|
+
expect(badge).toHaveTextContent("Updated search");
|
|
92
|
+
});
|
|
93
|
+
it("handles input change correctly", () => {
|
|
94
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: [], setSearchCriteria: mockSetSearchCriteria }));
|
|
95
|
+
const input = screen.getByTestId("table-header-input");
|
|
96
|
+
// Simulate typing
|
|
97
|
+
fireEvent.change(input, { target: { value: "Test search" } });
|
|
98
|
+
expect(input.value).toBe("Test search");
|
|
99
|
+
// Verify that badge appears
|
|
100
|
+
const badge = screen.getByTestId("badge");
|
|
101
|
+
expect(badge).toBeInTheDocument();
|
|
102
|
+
expect(badge).toHaveTextContent("Test search");
|
|
103
|
+
});
|
|
104
|
+
it("submits search via Enter key", () => {
|
|
105
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: [], setSearchCriteria: mockSetSearchCriteria }));
|
|
106
|
+
const input = screen.getByTestId("table-header-input");
|
|
107
|
+
// Simulate typing
|
|
108
|
+
fireEvent.change(input, { target: { value: "Enter search" } });
|
|
109
|
+
expect(input.value).toBe("Enter search");
|
|
110
|
+
// Simulate pressing Enter
|
|
111
|
+
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
112
|
+
// Verify that setSearchCriteria was called to add the new criterion
|
|
113
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
114
|
+
// Simulate the updater function behavior
|
|
115
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
116
|
+
const newSearchCriteria = updaterFn([]);
|
|
117
|
+
expect(newSearchCriteria).toEqual([
|
|
118
|
+
{
|
|
119
|
+
searchColumn: mockColumn,
|
|
120
|
+
submittedSearchText: "Enter search",
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
// Verify that setEditingHeader was called with null
|
|
124
|
+
expect(mockSetEditingHeader).toHaveBeenCalledWith(null);
|
|
125
|
+
});
|
|
126
|
+
// it("submits search via search icon click", () => {
|
|
127
|
+
// render(
|
|
128
|
+
// <InputAndCheck<MyDataType>
|
|
129
|
+
// closeOutSearch={mockCloseOutSearch}
|
|
130
|
+
// setResetSearch={mockSetResetSearch}
|
|
131
|
+
// setEditingHeader={mockSetEditingHeader}
|
|
132
|
+
// column={mockColumn}
|
|
133
|
+
// searchCriteria={[]}
|
|
134
|
+
// setSearchCriteria={mockSetSearchCriteria}
|
|
135
|
+
// />
|
|
136
|
+
// );
|
|
137
|
+
// const input = screen.getByTestId(
|
|
138
|
+
// "table-header-input"
|
|
139
|
+
// ) as HTMLInputElement;
|
|
140
|
+
// // Simulate typing
|
|
141
|
+
// fireEvent.change(input, { target: { value: "Icon search" } });
|
|
142
|
+
// expect(input.value).toBe("Icon search");
|
|
143
|
+
// // Find the search icon (assuming it's rendered as a span with a data-testid)
|
|
144
|
+
// const searchIcon = screen.getByTestId("icon-search-solid");
|
|
145
|
+
// // Simulate clicking the search icon
|
|
146
|
+
// fireEvent.click(searchIcon);
|
|
147
|
+
// // Verify that setSearchCriteria was called to add the new criterion
|
|
148
|
+
// expect(mockSetSearchCriteria).toHaveBeenCalledWith(
|
|
149
|
+
// expect.any(Function)
|
|
150
|
+
// );
|
|
151
|
+
// // Simulate the updater function behavior
|
|
152
|
+
// const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
153
|
+
// const newSearchCriteria = updaterFn([]);
|
|
154
|
+
// expect(newSearchCriteria).toEqual([
|
|
155
|
+
// {
|
|
156
|
+
// searchColumn: mockColumn,
|
|
157
|
+
// submittedSearchText: "Icon search",
|
|
158
|
+
// },
|
|
159
|
+
// ]);
|
|
160
|
+
// // Verify that setEditingHeader was called with null
|
|
161
|
+
// expect(mockSetEditingHeader).toHaveBeenCalledWith(null);
|
|
162
|
+
// });
|
|
163
|
+
it('clears search via "X" icon click', () => {
|
|
164
|
+
const initialCriteria = [
|
|
165
|
+
{
|
|
166
|
+
searchColumn: mockColumn,
|
|
167
|
+
submittedSearchText: "Initial search",
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
171
|
+
// Check that the badge is rendered
|
|
172
|
+
const badge = screen.getByTestId("badge");
|
|
173
|
+
expect(badge).toBeInTheDocument();
|
|
174
|
+
// Find the badge's clear button
|
|
175
|
+
const badgeClear = screen.getByTestId("badge-clear");
|
|
176
|
+
// Simulate clicking the clear button
|
|
177
|
+
fireEvent.click(badgeClear);
|
|
178
|
+
// Verify that setSearchCriteria was called to remove the criterion
|
|
179
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
180
|
+
// Simulate the updater function behavior
|
|
181
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
182
|
+
const newSearchCriteria = updaterFn(initialCriteria);
|
|
183
|
+
expect(newSearchCriteria).toEqual([]);
|
|
184
|
+
// Verify that setResetSearch was called
|
|
185
|
+
expect(mockSetResetSearch).toHaveBeenCalledWith(expect.any(Function));
|
|
186
|
+
// Simulate the updater function behavior for setResetSearch
|
|
187
|
+
const resetFn = mockSetResetSearch.mock.calls[0][0];
|
|
188
|
+
const newResetSearch = resetFn(false);
|
|
189
|
+
expect(newResetSearch).toBe(true);
|
|
190
|
+
// Verify that closeOutSearch was called with null
|
|
191
|
+
expect(mockCloseOutSearch).toHaveBeenCalledWith(null);
|
|
192
|
+
});
|
|
193
|
+
it("clears search via badge click", () => {
|
|
194
|
+
const initialCriteria = [
|
|
195
|
+
{
|
|
196
|
+
searchColumn: mockColumn,
|
|
197
|
+
submittedSearchText: "Badge search",
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
201
|
+
// Check that the badge is rendered
|
|
202
|
+
const badge = screen.getByTestId("badge");
|
|
203
|
+
expect(badge).toBeInTheDocument();
|
|
204
|
+
// Simulate clicking the badge to clear the search
|
|
205
|
+
fireEvent.click(badge);
|
|
206
|
+
// Verify that setSearchCriteria was called to remove the criterion
|
|
207
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
208
|
+
// Simulate the updater function behavior
|
|
209
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
210
|
+
const newSearchCriteria = updaterFn(initialCriteria);
|
|
211
|
+
expect(newSearchCriteria).toEqual([]);
|
|
212
|
+
// Verify that setResetSearch was called
|
|
213
|
+
expect(mockSetResetSearch).toHaveBeenCalledWith(expect.any(Function));
|
|
214
|
+
// Simulate the updater function behavior for setResetSearch
|
|
215
|
+
const resetFn = mockSetResetSearch.mock.calls[0][0];
|
|
216
|
+
const newResetSearch = resetFn(false);
|
|
217
|
+
expect(newResetSearch).toBe(true);
|
|
218
|
+
// Verify that closeOutSearch was called with null
|
|
219
|
+
expect(mockCloseOutSearch).toHaveBeenCalledWith(null);
|
|
220
|
+
});
|
|
221
|
+
it("removes search criterion when submitting empty text", () => {
|
|
222
|
+
const initialCriteria = [
|
|
223
|
+
{
|
|
224
|
+
searchColumn: mockColumn,
|
|
225
|
+
submittedSearchText: "Initial search",
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
229
|
+
const input = screen.getByTestId("table-header-input");
|
|
230
|
+
// Simulate clearing the input
|
|
231
|
+
fireEvent.change(input, { target: { value: " " } }); // Spaces to trim to empty
|
|
232
|
+
// Simulate pressing Enter to submit
|
|
233
|
+
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
234
|
+
// Verify that setSearchCriteria was called to remove the criterion
|
|
235
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
236
|
+
// Simulate the updater function behavior
|
|
237
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
238
|
+
const newSearchCriteria = updaterFn(initialCriteria);
|
|
239
|
+
expect(newSearchCriteria).toEqual([]);
|
|
240
|
+
// Verify that setEditingHeader was called with null
|
|
241
|
+
expect(mockSetEditingHeader).toHaveBeenCalledWith(null);
|
|
242
|
+
});
|
|
243
|
+
it("does not add duplicate search criteria", () => {
|
|
244
|
+
const initialCriteria = [
|
|
245
|
+
{
|
|
246
|
+
searchColumn: mockColumn,
|
|
247
|
+
submittedSearchText: "Initial search",
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
251
|
+
const input = screen.getByTestId("table-header-input");
|
|
252
|
+
// Simulate changing the input to a new search term
|
|
253
|
+
fireEvent.change(input, { target: { value: "Updated search" } });
|
|
254
|
+
expect(input.value).toBe("Updated search");
|
|
255
|
+
// Simulate pressing Enter to submit
|
|
256
|
+
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
257
|
+
// Verify that setSearchCriteria was called to update the existing criterion
|
|
258
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
259
|
+
// Simulate the updater function behavior
|
|
260
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
261
|
+
const newSearchCriteria = updaterFn(initialCriteria);
|
|
262
|
+
expect(newSearchCriteria).toEqual([
|
|
263
|
+
{
|
|
264
|
+
searchColumn: mockColumn,
|
|
265
|
+
submittedSearchText: "Updated search",
|
|
266
|
+
},
|
|
267
|
+
]);
|
|
268
|
+
});
|
|
269
|
+
it("handles multiple search criteria correctly", () => {
|
|
270
|
+
const anotherColumn = {
|
|
271
|
+
id: "id",
|
|
272
|
+
// Add other properties as needed
|
|
273
|
+
};
|
|
274
|
+
const initialCriteria = [
|
|
275
|
+
{
|
|
276
|
+
searchColumn: mockColumn,
|
|
277
|
+
submittedSearchText: "Name search",
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
searchColumn: anotherColumn,
|
|
281
|
+
submittedSearchText: "ID search",
|
|
282
|
+
},
|
|
283
|
+
];
|
|
284
|
+
render(_jsx(InputAndCheck, { closeOutSearch: mockCloseOutSearch, setResetSearch: mockSetResetSearch, setEditingHeader: mockSetEditingHeader, column: mockColumn, searchCriteria: initialCriteria, setSearchCriteria: mockSetSearchCriteria }));
|
|
285
|
+
const input = screen.getByTestId("table-header-input");
|
|
286
|
+
// Simulate changing the input to update the existing criterion
|
|
287
|
+
fireEvent.change(input, { target: { value: "Updated name search" } });
|
|
288
|
+
expect(input.value).toBe("Updated name search");
|
|
289
|
+
// Simulate pressing Enter to submit
|
|
290
|
+
fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
|
|
291
|
+
// Verify that setSearchCriteria was called to update the existing name search
|
|
292
|
+
expect(mockSetSearchCriteria).toHaveBeenCalledWith(expect.any(Function));
|
|
293
|
+
// Simulate the updater function behavior
|
|
294
|
+
const updaterFn = mockSetSearchCriteria.mock.calls[0][0];
|
|
295
|
+
const newSearchCriteria = updaterFn(initialCriteria);
|
|
296
|
+
expect(newSearchCriteria).toEqual([
|
|
297
|
+
{
|
|
298
|
+
searchColumn: mockColumn,
|
|
299
|
+
submittedSearchText: "Updated name search",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
searchColumn: anotherColumn,
|
|
303
|
+
submittedSearchText: "ID search",
|
|
304
|
+
},
|
|
305
|
+
]);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ColumnInstance } from "react-table";
|
|
2
|
+
export type SearchCriterion<T extends object> = {
|
|
3
|
+
searchColumn: ColumnInstance<T>;
|
|
4
|
+
submittedSearchText: string;
|
|
5
|
+
};
|
|
6
|
+
export type InputAndCheckProps<T extends object> = {
|
|
7
|
+
closeOutSearch: (value: number | null) => void;
|
|
8
|
+
setResetSearch: React.Dispatch<React.SetStateAction<boolean>>;
|
|
9
|
+
setEditingHeader: (value: number | null) => void;
|
|
10
|
+
column: ColumnInstance<T>;
|
|
11
|
+
searchCriteria: SearchCriterion<T>[];
|
|
12
|
+
setSearchCriteria: React.Dispatch<React.SetStateAction<SearchCriterion<T>[]>>;
|
|
13
|
+
badgeColor?: string;
|
|
14
|
+
badgeIcon?: {
|
|
15
|
+
icon: string;
|
|
16
|
+
weight: string;
|
|
17
|
+
};
|
|
18
|
+
iconBadgeContainerClasses?: string;
|
|
19
|
+
searchIcon?: {
|
|
20
|
+
icon: string;
|
|
21
|
+
weight: string;
|
|
22
|
+
};
|
|
23
|
+
cancelIcon?: {
|
|
24
|
+
icon: string;
|
|
25
|
+
weight: string;
|
|
26
|
+
};
|
|
27
|
+
initialIcon?: {
|
|
28
|
+
icon: string;
|
|
29
|
+
weight: string;
|
|
30
|
+
};
|
|
31
|
+
initialIconClasses?: string;
|
|
32
|
+
searchIconClasses?: string;
|
|
33
|
+
additionalInputClasses?: string;
|
|
34
|
+
secondIconClasses?: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|