@truedat/core 6.5.3 → 6.5.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/core",
3
- "version": "6.5.3",
3
+ "version": "6.5.4",
4
4
  "description": "Truedat Web Core",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -36,7 +36,7 @@
36
36
  "@testing-library/react": "^12.0.0",
37
37
  "@testing-library/react-hooks": "^8.0.1",
38
38
  "@testing-library/user-event": "^13.2.1",
39
- "@truedat/test": "6.5.3",
39
+ "@truedat/test": "6.5.4",
40
40
  "babel-jest": "^28.1.0",
41
41
  "babel-plugin-dynamic-import-node": "^2.3.3",
42
42
  "babel-plugin-lodash": "^3.3.4",
@@ -118,5 +118,5 @@
118
118
  "react-dom": ">= 16.8.6 < 17",
119
119
  "semantic-ui-react": ">= 2.0.3 < 2.2"
120
120
  },
121
- "gitHead": "b462ae1bd669df63f6617f7d4bbbc12ca8c515e8"
121
+ "gitHead": "ca29de8f75c143bb950bb8c9fc8a4d96c97464fb"
122
122
  }
@@ -21,6 +21,7 @@ export default function FilterDropdown() {
21
21
  toggleFilterValue,
22
22
  } = useSearchContext();
23
23
 
24
+ const sortedOptions = _.sortBy(accentInsensitivePathOrder("text"))(options);
24
25
  return (
25
26
  <Dropdown
26
27
  item
@@ -49,21 +50,19 @@ export default function FilterDropdown() {
49
50
  open={!_.isEmpty(options)}
50
51
  >
51
52
  <Dimmer.Dimmable as={Dropdown.Menu} dimmed={loading}>
52
- {options &&
53
- _.flow(
54
- _.sortBy(accentInsensitivePathOrder("text")),
55
- _.map.convert({ cap: false })((option, i) => (
56
- <FilterItem
57
- key={i}
58
- filter={filter}
59
- option={option}
60
- toggleFilterValue={toggleFilterValue}
61
- active={_.includes(_.prop("value")(option))(
62
- activeFilterSelectedValues
63
- )}
64
- />
65
- ))
66
- )(options)}
53
+ <>
54
+ {sortedOptions.map((option, i) => (
55
+ <FilterItem
56
+ key={i}
57
+ filter={filter}
58
+ toggleFilterValue={toggleFilterValue}
59
+ option={option}
60
+ active={_.includes(_.prop("value")(option))(
61
+ activeFilterSelectedValues
62
+ )}
63
+ />
64
+ ))}
65
+ </>
67
66
  {loading && (
68
67
  <Dimmer active inverted>
69
68
  <Loader size="tiny" />
@@ -0,0 +1,140 @@
1
+ import _ from "lodash/fp";
2
+ import React, { useState, useEffect } from "react";
3
+ import { FormattedMessage } from "react-intl";
4
+ import {
5
+ Label,
6
+ Icon,
7
+ Dropdown,
8
+ Dimmer,
9
+ Loader,
10
+ Input,
11
+ } from "semantic-ui-react";
12
+ import {
13
+ accentInsensitivePathOrder,
14
+ lowerDeburr,
15
+ } from "@truedat/core/services/sort";
16
+ import FilterItem from "./FilterItem";
17
+
18
+ import { useSearchContext } from "./SearchContext";
19
+
20
+ const removePrefix = _.replace(/^.*\./, "");
21
+
22
+ export default function FilterQueryDropdown() {
23
+ const {
24
+ loadingFilters: loading,
25
+ filter,
26
+ options,
27
+ activeFilterSelectedValues,
28
+ openFilter,
29
+ closeFilter,
30
+ removeFilter,
31
+ toggleFilterValue,
32
+ } = useSearchContext();
33
+
34
+ const [selected, setSelected] = useState([]);
35
+ const [localQuery, setLocalQuery] = useState("");
36
+
37
+ const sortedOptions = _.sortBy(accentInsensitivePathOrder("text"))(options);
38
+
39
+ useEffect(() => {
40
+ const activeOptions = _.filter((option) =>
41
+ _.includes(option.value)(activeFilterSelectedValues)
42
+ )(options);
43
+
44
+ _.flow(
45
+ _.reduce((acc, option) => [...acc, option], []),
46
+ _.uniq,
47
+ setSelected
48
+ )(activeOptions);
49
+ }, [activeFilterSelectedValues, options]);
50
+
51
+ const handleSearch = (e, { value }) => {
52
+ e.preventDefault();
53
+ setLocalQuery(lowerDeburr(value));
54
+ };
55
+
56
+ const match = (name, localQuery) => _.contains(localQuery)(lowerDeburr(name));
57
+ const filteredOptions = _.filter(
58
+ (option) =>
59
+ match(option.text, localQuery) &&
60
+ !_.includes(option.value)(activeFilterSelectedValues)
61
+ )(sortedOptions);
62
+
63
+ return (
64
+ <Dropdown
65
+ item
66
+ floating
67
+ scrolling
68
+ icon={false}
69
+ upward={false}
70
+ trigger={
71
+ <Label key={filter}>
72
+ <FormattedMessage
73
+ id={`filters.${filter}`}
74
+ defaultMessage={removePrefix(filter)}
75
+ />
76
+ <Icon
77
+ name="delete"
78
+ onClick={(e) => {
79
+ e.preventDefault();
80
+ e.stopPropagation();
81
+ removeFilter({ filter });
82
+ }}
83
+ />
84
+ </Label>
85
+ }
86
+ onOpen={() => openFilter({ filter })}
87
+ onClose={() => closeFilter({ filter })}
88
+ open={!_.isEmpty(options)}
89
+ >
90
+ <Dimmer.Dimmable as={Dropdown.Menu} dimmed={loading}>
91
+ <>
92
+ <>
93
+ <Input
94
+ icon="search"
95
+ iconPosition="left"
96
+ className="search"
97
+ onKeyDown={(e) => {
98
+ if (e.key === " ") {
99
+ e.stopPropagation();
100
+ }
101
+ }}
102
+ onChange={handleSearch}
103
+ value={localQuery}
104
+ onClick={(e) => {
105
+ e.preventDefault();
106
+ e.stopPropagation();
107
+ }}
108
+ />
109
+ {selected.map((option, i) => (
110
+ <FilterItem
111
+ key={i}
112
+ filter={filter}
113
+ toggleFilterValue={toggleFilterValue}
114
+ option={option}
115
+ active={true}
116
+ />
117
+ ))}
118
+ <Dropdown.Divider />
119
+ {filteredOptions.map((option, i) => (
120
+ <FilterItem
121
+ key={i}
122
+ filter={filter}
123
+ toggleFilterValue={toggleFilterValue}
124
+ option={option}
125
+ active={_.includes(_.prop("value")(option))(
126
+ activeFilterSelectedValues
127
+ )}
128
+ />
129
+ ))}
130
+ </>
131
+ </>
132
+ {loading && (
133
+ <Dimmer active inverted>
134
+ <Loader size="tiny" />
135
+ </Dimmer>
136
+ )}
137
+ </Dimmer.Dimmable>
138
+ </Dropdown>
139
+ );
140
+ }
@@ -41,7 +41,6 @@ export const SearchContextProvider = (props) => {
41
41
  const [activeFilterName, setActiveFilterName] = useState([]);
42
42
  const [allActiveFilters, setAllActiveFilters] = useState({});
43
43
  const [hiddenFilters, setHiddenFilters] = useState({});
44
-
45
44
  const [filterParams, setFilterParams] = useState({});
46
45
  const [sortColumn, setSortColumn] = useState(initialSortColumn);
47
46
  const [sortDirection, setSortDirection] = useState(initialSortDirection);
@@ -118,7 +117,8 @@ export const SearchContextProvider = (props) => {
118
117
  type,
119
118
  }),
120
119
  formatFilterValues,
121
- _.map(makeOption(translations(formatMessage), activeFilterName))
120
+ _.map(makeOption(translations(formatMessage), activeFilterName)),
121
+ _.reject((item) => _.values(item).includes(undefined))
122
122
  )(filters);
123
123
 
124
124
  const activeFilterSelectedValues = _.flow(
@@ -149,9 +149,7 @@ export const SearchContextProvider = (props) => {
149
149
  const sort = useMemo(
150
150
  () =>
151
151
  sortColumn
152
- ? {
153
- [sortColumn]: sortDirection === "ascending" ? "asc" : "desc",
154
- }
152
+ ? { [sortColumn]: sortDirection === "ascending" ? "asc" : "desc" }
155
153
  : null,
156
154
  [sortColumn, sortDirection]
157
155
  );
@@ -193,18 +191,11 @@ export const SearchContextProvider = (props) => {
193
191
  }, [query, searchMust, sort, defaultFilters, page, size]);
194
192
 
195
193
  const makeFiltersGroup = (filters, groups) =>
196
- _.flow(
197
- _.groupBy((filter) =>
198
- _.flow(
199
- _.find(([_group, fields]) => _.contains(filter)(fields)),
200
- _.prop("[0]")
201
- )(groups)
202
- ),
203
- _.toPairs,
204
- _.remove(([key, _value]) => {
205
- return _.startsWith("_")(key);
206
- }),
207
- _.fromPairs
194
+ _.groupBy((filter) =>
195
+ _.flow(
196
+ _.find(([_group, fields]) => _.contains(filter)(fields)),
197
+ _.prop("[0]")
198
+ )(groups)
208
199
  )(filters);
209
200
 
210
201
  const filtersByGroup = makeFiltersGroup(availableFilters, filtersGroup);
@@ -225,6 +216,25 @@ export const SearchContextProvider = (props) => {
225
216
  ])
226
217
  )(filtersGroup);
227
218
 
219
+ const handleSortSelection = (columnName) => {
220
+ if (!columnName) return;
221
+
222
+ if (sortColumn !== columnName) {
223
+ setSortColumn(columnName);
224
+ setSortDirection("ascending");
225
+ } else {
226
+ setSortDirection(
227
+ sortDirection === "ascending" ? "descending" : "ascending"
228
+ );
229
+ }
230
+ };
231
+
232
+ const setQueryAndScoreSort = (query) => {
233
+ setSortColumn(query == "" ? initialSortColumn : "_score");
234
+ setSortDirection(query == "" ? initialSortDirection : "descending");
235
+ setQuery(query);
236
+ };
237
+
228
238
  const context = {
229
239
  disabled: false,
230
240
  loadingFilters,
@@ -250,7 +260,7 @@ export const SearchContextProvider = (props) => {
250
260
  toggleFilterValue,
251
261
  toggleHiddenFilterValue,
252
262
  searchMust,
253
- setQuery,
263
+ setQuery: setQueryAndScoreSort,
254
264
  setAllActiveFilters,
255
265
  allActiveFilters,
256
266
  filters,
@@ -262,6 +272,8 @@ export const SearchContextProvider = (props) => {
262
272
  sortDirection,
263
273
  setSortColumn,
264
274
  setSortDirection,
275
+ handleSortSelection,
276
+ initialSortColumn,
265
277
  selectPage,
266
278
  setSize,
267
279
  count,
@@ -5,10 +5,13 @@ import { useUserFilters, useUserFiltersCreate } from "../hooks/useUserFilters";
5
5
  import ModalSaveFilter from "../components/ModalSaveFilter";
6
6
  import UserFilters from "./UserFilters";
7
7
  import FilterDropdown from "./FilterDropdown";
8
+ import FilterQueryDropdown from "./FilterQueryDropdown";
8
9
  import FilterMultilevelDropdown from "./FilterMultilevelDropdown";
9
10
  import HierarchyFilterDropdown from "./HierarchyFilterDropdown";
10
11
  import SearchContext, { useSearchContext } from "./SearchContext";
11
12
 
13
+ const MIN_LENGTH_FOR_QUERY_DROPDOWN = 8;
14
+
12
15
  export default function SearchSelectedFilters() {
13
16
  const context = useSearchContext();
14
17
  const {
@@ -69,6 +72,8 @@ export default function SearchSelectedFilters() {
69
72
  <FilterMultilevelDropdown />
70
73
  ) : filterType === "hierarchy" ? (
71
74
  <HierarchyFilterDropdown />
75
+ ) : _.size(options) >= MIN_LENGTH_FOR_QUERY_DROPDOWN ? (
76
+ <FilterQueryDropdown />
72
77
  ) : (
73
78
  <FilterDropdown />
74
79
  )}
@@ -0,0 +1,99 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { waitFor } from "@testing-library/react";
5
+ import userEvent from "@testing-library/user-event";
6
+ import SearchContext from "@truedat/core/search/SearchContext";
7
+
8
+ import FilterDropdown from "../FilterDropdown";
9
+
10
+ const options = _.map((value) => ({ value, text: value }))([
11
+ "value1",
12
+ "value2",
13
+ ]);
14
+
15
+ const searchProps = {
16
+ loadingFilters: false,
17
+ openFilter: jest.fn(),
18
+ closeFilter: jest.fn(),
19
+ removeFilter: jest.fn(),
20
+ toggleFilterValue: jest.fn(),
21
+ useFilters: jest.fn(),
22
+ useSearch: jest.fn(),
23
+ filter: "foo",
24
+ options,
25
+ };
26
+
27
+ describe("<FilterDropdown/>", () => {
28
+ it("matches the latest snapshot", () => {
29
+ const { container } = render(
30
+ <SearchContext.Provider value={searchProps}>
31
+ <FilterDropdown />
32
+ </SearchContext.Provider>
33
+ );
34
+ expect(container).toMatchSnapshot();
35
+ });
36
+
37
+ it("no render search input if has more than eight options", () => {
38
+ const { container } = render(
39
+ <SearchContext.Provider value={searchProps}>
40
+ <FilterDropdown />
41
+ </SearchContext.Provider>
42
+ );
43
+ const searchInput = container.querySelector(".search input[type='text']");
44
+ expect(searchInput).not.toBeInTheDocument();
45
+ });
46
+
47
+ it("dispatches openFilter", () => {
48
+ const customProps = {
49
+ ...searchProps,
50
+ options: [],
51
+ };
52
+
53
+ const { rerender } = render(
54
+ <SearchContext.Provider value={customProps}>
55
+ <FilterDropdown />
56
+ </SearchContext.Provider>
57
+ );
58
+
59
+ rerender(
60
+ <SearchContext.Provider value={searchProps}>
61
+ <FilterDropdown />
62
+ </SearchContext.Provider>
63
+ );
64
+
65
+ waitFor(() => expect(searchProps.openFilter).toBeCalledTimes(1));
66
+ });
67
+
68
+ it("dispatches closeFilter", () => {
69
+ const customProps = {
70
+ ...searchProps,
71
+ options: [],
72
+ };
73
+
74
+ const { rerender } = render(
75
+ <SearchContext.Provider value={searchProps}>
76
+ <FilterDropdown />
77
+ </SearchContext.Provider>
78
+ );
79
+ rerender(
80
+ <SearchContext.Provider value={customProps}>
81
+ <FilterDropdown />
82
+ </SearchContext.Provider>
83
+ );
84
+
85
+ waitFor(() => expect(searchProps.closeFilter).toBeCalledTimes(1));
86
+ });
87
+
88
+ it("remove filter dispatches removeFilter", async () => {
89
+ const { container } = render(
90
+ <SearchContext.Provider value={searchProps}>
91
+ <FilterDropdown />
92
+ </SearchContext.Provider>
93
+ );
94
+ userEvent.click(container.querySelector('[class="delete icon"]'));
95
+ await waitFor(() => {
96
+ expect(searchProps.removeFilter).toBeCalledTimes(1);
97
+ });
98
+ });
99
+ });
@@ -0,0 +1,46 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { FilterItem } from "../FilterItem";
5
+
6
+ const props = {
7
+ active: true,
8
+ filter: "foo",
9
+ toggleFilterValue: jest.fn(),
10
+ option: { value: "foo", text: "bar" },
11
+ };
12
+
13
+ describe("<FilterItem/>", () => {
14
+ it("matches the latest snapshot", () => {
15
+ const { container } = render(<FilterItem {...props} />);
16
+ expect(container).toMatchSnapshot();
17
+ });
18
+
19
+ it("show active with false", () => {
20
+ const newProps = {
21
+ ...props,
22
+ active: false,
23
+ };
24
+ const { getByRole } = render(<FilterItem {...newProps} />);
25
+ const divElement = getByRole("option");
26
+ expect(divElement).toHaveAttribute("aria-checked", "false");
27
+ });
28
+
29
+ it("show empty filter", () => {
30
+ const newProps = {
31
+ ...props,
32
+ option: { value: "foo", text: "" },
33
+ };
34
+ const { getByText } = render(<FilterItem {...newProps} />);
35
+ const emptyElement = getByText("Empty");
36
+ expect(emptyElement).toBeInTheDocument();
37
+ });
38
+
39
+ it("dispatches toggleFilterValue on click", () => {
40
+ const { getByRole } = render(<FilterItem {...props} />);
41
+ expect(props.toggleFilterValue.mock.calls.length).toBe(0);
42
+ const dropdownItem = getByRole("option", { name: "bar" });
43
+ userEvent.click(dropdownItem);
44
+ expect(props.toggleFilterValue.mock.calls.length).toBe(1);
45
+ });
46
+ });
@@ -0,0 +1,200 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { waitFor, within } from "@testing-library/react";
5
+ import userEvent from "@testing-library/user-event";
6
+ import SearchContext from "@truedat/core/search/SearchContext";
7
+ import FilterQueryDropdown from "../FilterQueryDropdown";
8
+
9
+ const options = _.range(0, 10).map((n) => ({
10
+ value: `value${n}`,
11
+ text: `value${n}`,
12
+ }));
13
+
14
+ const searchProps = {
15
+ loadingFilters: false,
16
+ openFilter: jest.fn(),
17
+ closeFilter: jest.fn(),
18
+ removeFilter: jest.fn(),
19
+ toggleFilterValue: jest.fn(),
20
+ useFilters: jest.fn(),
21
+ useSearch: jest.fn(),
22
+ filter: "foo",
23
+ options,
24
+ };
25
+
26
+ describe("<FilterQueryDropdown/>", () => {
27
+ it("matches the latest snapshot", () => {
28
+ const { container } = render(
29
+ <SearchContext.Provider value={searchProps}>
30
+ <FilterQueryDropdown />
31
+ </SearchContext.Provider>
32
+ );
33
+ expect(container).toMatchSnapshot();
34
+ });
35
+
36
+ it("render search input if has more than eight options", () => {
37
+ const { container } = render(
38
+ <SearchContext.Provider value={searchProps}>
39
+ <FilterQueryDropdown />
40
+ </SearchContext.Provider>
41
+ );
42
+ const searchInput = container.querySelector(".search input[type='text']");
43
+ expect(searchInput).toBeInTheDocument();
44
+ });
45
+
46
+ it("check option check it correctly", () => {
47
+ const selectedOption = searchProps.options[6].text;
48
+
49
+ const { getByRole, getAllByRole, rerender } = render(
50
+ <SearchContext.Provider value={searchProps}>
51
+ <FilterQueryDropdown />
52
+ </SearchContext.Provider>
53
+ );
54
+
55
+ expect(searchProps.toggleFilterValue).toBeCalledTimes(0);
56
+ userEvent.click(
57
+ getByRole("option", { name: new RegExp(selectedOption, "i") })
58
+ );
59
+ expect(searchProps.toggleFilterValue).toBeCalledWith({
60
+ filter: searchProps.filter,
61
+ value: selectedOption,
62
+ });
63
+
64
+ const rerenderProps = {
65
+ ...searchProps,
66
+ activeFilterSelectedValues: [selectedOption],
67
+ };
68
+ rerender(
69
+ <SearchContext.Provider value={rerenderProps}>
70
+ <FilterQueryDropdown />
71
+ </SearchContext.Provider>
72
+ );
73
+
74
+ expect(
75
+ within(getAllByRole("option")[0]).queryByText(selectedOption)
76
+ ).not.toBeNull();
77
+ });
78
+
79
+ it("type in filter input filter options", () => {
80
+ const searchText = "3";
81
+
82
+ const { getByRole, queryByRole, getAllByRole, container } = render(
83
+ <SearchContext.Provider value={searchProps}>
84
+ <FilterQueryDropdown />
85
+ </SearchContext.Provider>
86
+ );
87
+
88
+ const input = container.querySelector(".search input[type='text']");
89
+
90
+ expect(
91
+ getByRole("option", {
92
+ name: new RegExp(searchProps.options[1].text, "i"),
93
+ })
94
+ ).toBeInTheDocument();
95
+
96
+ userEvent.type(input, searchText);
97
+
98
+ expect(
99
+ queryByRole("option", {
100
+ name: new RegExp(searchProps.options[1].text, "i"),
101
+ })
102
+ ).toBeNull();
103
+
104
+ expect(
105
+ within(getByRole("option")).getByText(`value${searchText}`)
106
+ ).toBeInTheDocument();
107
+
108
+ expect(getAllByRole("option").length).toBe(1);
109
+ });
110
+
111
+ it("type in filter not hidde selected values", async () => {
112
+ const selectedOption = options[6].text;
113
+
114
+ const customProps = {
115
+ ...searchProps,
116
+ activeFilterSelectedValues: [selectedOption],
117
+ };
118
+
119
+ const searchText = "3";
120
+
121
+ const { getAllByRole, container, queryByRole } = render(
122
+ <SearchContext.Provider value={customProps}>
123
+ <FilterQueryDropdown />
124
+ </SearchContext.Provider>
125
+ );
126
+
127
+ const input = container.querySelector(".search input[type='text']");
128
+
129
+ userEvent.type(input, searchText);
130
+
131
+ expect(
132
+ within(getAllByRole("option")[0]).getByText(selectedOption)
133
+ ).toBeInTheDocument();
134
+
135
+ expect(
136
+ within(getAllByRole("option")[1]).getByText(`value${searchText}`)
137
+ ).toBeInTheDocument();
138
+
139
+ expect(
140
+ queryByRole("option", {
141
+ name: new RegExp(customProps.options[1].text, "i"),
142
+ })
143
+ ).toBeNull();
144
+
145
+ expect(getAllByRole("option").length).toBe(2);
146
+ });
147
+
148
+ it("dispatches openFilter", () => {
149
+ const customProps = {
150
+ ...searchProps,
151
+ options: [],
152
+ };
153
+
154
+ const { rerender } = render(
155
+ <SearchContext.Provider value={customProps}>
156
+ <FilterQueryDropdown />
157
+ </SearchContext.Provider>
158
+ );
159
+
160
+ rerender(
161
+ <SearchContext.Provider value={searchProps}>
162
+ <FilterQueryDropdown />
163
+ </SearchContext.Provider>
164
+ );
165
+
166
+ waitFor(() => expect(searchProps.openFilter).toBeCalledTimes(1));
167
+ });
168
+
169
+ it("dispatches closeFilter", () => {
170
+ const customProps = {
171
+ ...searchProps,
172
+ options: [],
173
+ };
174
+
175
+ const { rerender } = render(
176
+ <SearchContext.Provider value={searchProps}>
177
+ <FilterQueryDropdown />
178
+ </SearchContext.Provider>
179
+ );
180
+ rerender(
181
+ <SearchContext.Provider value={customProps}>
182
+ <FilterQueryDropdown />
183
+ </SearchContext.Provider>
184
+ );
185
+
186
+ waitFor(() => expect(searchProps.closeFilter).toBeCalledTimes(1));
187
+ });
188
+
189
+ it("remove filter dispatches removeFilter", async () => {
190
+ const { container } = render(
191
+ <SearchContext.Provider value={searchProps}>
192
+ <FilterQueryDropdown />
193
+ </SearchContext.Provider>
194
+ );
195
+ userEvent.click(container.querySelector('[class="delete icon"]'));
196
+ await waitFor(() => {
197
+ expect(searchProps.removeFilter).toBeCalledTimes(1);
198
+ });
199
+ });
200
+ });
@@ -0,0 +1,52 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { waitFor } from "@testing-library/react";
5
+ import userEvent from "@testing-library/user-event";
6
+ import SearchContext from "@truedat/core/search/SearchContext";
7
+ import SearchWidget from "../SearchWidget";
8
+
9
+ const messages = {
10
+ en: {
11
+ "search.placeholder": "Search...",
12
+ },
13
+ };
14
+
15
+ const renderOpts = { messages };
16
+
17
+ const setQuery = jest.fn();
18
+ const searchProps = {
19
+ userFiltersType: "foo",
20
+ useFilters: jest.fn(),
21
+ useSearch: jest.fn(),
22
+ loadingFilters: false,
23
+ query: "",
24
+ setQuery,
25
+ };
26
+
27
+ describe("<SearchWidget/>", () => {
28
+ it("matches the latest snapshot", () => {
29
+ const { container } = render(
30
+ <SearchContext.Provider value={searchProps}>
31
+ <SearchWidget />
32
+ </SearchContext.Provider>,
33
+ renderOpts
34
+ );
35
+ expect(container).toMatchSnapshot();
36
+ });
37
+
38
+ it("type in filter input filter options", async () => {
39
+ const { getByRole } = render(
40
+ <SearchContext.Provider value={searchProps}>
41
+ <SearchWidget />
42
+ </SearchContext.Provider>,
43
+ renderOpts
44
+ );
45
+
46
+ userEvent.type(await getByRole("textbox"), "3");
47
+
48
+ await waitFor(() => {
49
+ expect(setQuery).toBeCalledTimes(1);
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,48 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<FilterDropdown/> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ aria-expanded="true"
7
+ class="ui active visible floating item scrolling dropdown"
8
+ role="listbox"
9
+ tabindex="0"
10
+ >
11
+ <div
12
+ class="ui label"
13
+ >
14
+ foo
15
+ <i
16
+ aria-hidden="true"
17
+ class="delete icon"
18
+ />
19
+ </div>
20
+ <div
21
+ class="menu transition dimmable visible"
22
+ >
23
+ <div
24
+ aria-checked="false"
25
+ class="item"
26
+ role="option"
27
+ >
28
+ <i
29
+ aria-hidden="true"
30
+ class="square outline icon"
31
+ />
32
+ value1
33
+ </div>
34
+ <div
35
+ aria-checked="false"
36
+ class="item"
37
+ role="option"
38
+ >
39
+ <i
40
+ aria-hidden="true"
41
+ class="square outline icon"
42
+ />
43
+ value2
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ `;
@@ -0,0 +1,17 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<FilterItem/> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ aria-checked="true"
7
+ class="active item"
8
+ role="option"
9
+ >
10
+ <i
11
+ aria-hidden="true"
12
+ class="check square outline icon"
13
+ />
14
+ bar
15
+ </div>
16
+ </div>
17
+ `;
@@ -0,0 +1,151 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<FilterQueryDropdown/> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ aria-expanded="true"
7
+ class="ui active visible floating item scrolling dropdown"
8
+ role="listbox"
9
+ tabindex="0"
10
+ >
11
+ <div
12
+ class="ui label"
13
+ >
14
+ foo
15
+ <i
16
+ aria-hidden="true"
17
+ class="delete icon"
18
+ />
19
+ </div>
20
+ <div
21
+ class="menu transition dimmable visible"
22
+ >
23
+ <div
24
+ class="ui left icon input search"
25
+ >
26
+ <input
27
+ type="text"
28
+ value=""
29
+ />
30
+ <i
31
+ aria-hidden="true"
32
+ class="search icon"
33
+ />
34
+ </div>
35
+ <div
36
+ class="divider"
37
+ />
38
+ <div
39
+ aria-checked="false"
40
+ class="item"
41
+ role="option"
42
+ >
43
+ <i
44
+ aria-hidden="true"
45
+ class="square outline icon"
46
+ />
47
+ value0
48
+ </div>
49
+ <div
50
+ aria-checked="false"
51
+ class="item"
52
+ role="option"
53
+ >
54
+ <i
55
+ aria-hidden="true"
56
+ class="square outline icon"
57
+ />
58
+ value1
59
+ </div>
60
+ <div
61
+ aria-checked="false"
62
+ class="item"
63
+ role="option"
64
+ >
65
+ <i
66
+ aria-hidden="true"
67
+ class="square outline icon"
68
+ />
69
+ value2
70
+ </div>
71
+ <div
72
+ aria-checked="false"
73
+ class="item"
74
+ role="option"
75
+ >
76
+ <i
77
+ aria-hidden="true"
78
+ class="square outline icon"
79
+ />
80
+ value3
81
+ </div>
82
+ <div
83
+ aria-checked="false"
84
+ class="item"
85
+ role="option"
86
+ >
87
+ <i
88
+ aria-hidden="true"
89
+ class="square outline icon"
90
+ />
91
+ value4
92
+ </div>
93
+ <div
94
+ aria-checked="false"
95
+ class="item"
96
+ role="option"
97
+ >
98
+ <i
99
+ aria-hidden="true"
100
+ class="square outline icon"
101
+ />
102
+ value5
103
+ </div>
104
+ <div
105
+ aria-checked="false"
106
+ class="item"
107
+ role="option"
108
+ >
109
+ <i
110
+ aria-hidden="true"
111
+ class="square outline icon"
112
+ />
113
+ value6
114
+ </div>
115
+ <div
116
+ aria-checked="false"
117
+ class="item"
118
+ role="option"
119
+ >
120
+ <i
121
+ aria-hidden="true"
122
+ class="square outline icon"
123
+ />
124
+ value7
125
+ </div>
126
+ <div
127
+ aria-checked="false"
128
+ class="item"
129
+ role="option"
130
+ >
131
+ <i
132
+ aria-hidden="true"
133
+ class="square outline icon"
134
+ />
135
+ value8
136
+ </div>
137
+ <div
138
+ aria-checked="false"
139
+ class="item"
140
+ role="option"
141
+ >
142
+ <i
143
+ aria-hidden="true"
144
+ class="square outline icon"
145
+ />
146
+ value9
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ `;
@@ -0,0 +1,54 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<SearchWidget/> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ class="ui action left icon input"
7
+ >
8
+ <input
9
+ placeholder="Search..."
10
+ type="text"
11
+ value=""
12
+ />
13
+ <i
14
+ aria-hidden="true"
15
+ class="search link icon"
16
+ />
17
+ <div
18
+ aria-busy="false"
19
+ aria-expanded="false"
20
+ class="ui button floating labeled scrolling dropdown icon"
21
+ role="listbox"
22
+ tabindex="0"
23
+ >
24
+ <div
25
+ aria-atomic="true"
26
+ aria-live="polite"
27
+ class="divider text"
28
+ role="alert"
29
+ >
30
+ Filters
31
+ </div>
32
+ <i
33
+ aria-hidden="true"
34
+ class="filter icon"
35
+ />
36
+ <div
37
+ class="menu transition"
38
+ >
39
+ <div
40
+ class="item"
41
+ role="option"
42
+ >
43
+ <em>
44
+ (reset filters)
45
+ </em>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ <div
51
+ class="selectedFilters"
52
+ />
53
+ </div>
54
+ `;