@truedat/core 6.12.0 → 6.12.2
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 +2 -2
- package/src/components/SelectedFilters.js +77 -67
- package/src/components/UserFilters.js +23 -3
- package/src/components/__tests__/SelectedFilters.spec.js +81 -0
- package/src/components/__tests__/UserFilters.spec.js +71 -0
- package/src/components/__tests__/__snapshots__/SelectedFilters.spec.js.snap +106 -0
- package/src/components/__tests__/__snapshots__/UserFilters.spec.js.snap +27 -0
- package/src/search/SearchContext.js +26 -9
- package/src/search/SearchSelectedFilters.js +7 -0
- package/src/search/SearchWidget.js +1 -1
- package/src/search/UserFilters.js +26 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "6.12.
|
|
3
|
+
"version": "6.12.2",
|
|
4
4
|
"description": "Truedat Web Core",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -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": "
|
|
121
|
+
"gitHead": "e0acd68539a1ed3786de65ab4fa4221455ea90a4"
|
|
122
122
|
}
|
|
@@ -2,6 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { useLocation } from "react-router-dom";
|
|
5
6
|
import FilterDropdown from "./FilterDropdown";
|
|
6
7
|
import FilterMultilevelDropdown from "./FilterMultilevelDropdown";
|
|
7
8
|
import HierarchyFilterDropdown from "./HierarchyFilterDropdown";
|
|
@@ -30,76 +31,85 @@ export const SelectedFilters = ({
|
|
|
30
31
|
userFilterScope,
|
|
31
32
|
searchFiltersPropsMapping,
|
|
32
33
|
searchFilterDispacher,
|
|
33
|
-
}) =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
deleteUserFilter={deleteUserFilter}
|
|
40
|
-
resetFilters={resetFilters}
|
|
41
|
-
selectedUserFilter={selectedUserFilter}
|
|
42
|
-
userFilters={userFilters}
|
|
43
|
-
disabled={loading}
|
|
44
|
-
/>
|
|
45
|
-
)}
|
|
46
|
-
<div className="selectedFilters">
|
|
47
|
-
{_.isEmpty(selectedFilters) ? null : (
|
|
48
|
-
<>
|
|
49
|
-
<div className="appliedFilters">
|
|
50
|
-
<FormattedMessage id="search.applied_filters" />
|
|
51
|
-
</div>
|
|
52
|
-
{selectedFilters.map((filter) => {
|
|
53
|
-
const isSelectedFilter = _.isEqual(filter, selectedFilter);
|
|
34
|
+
}) => {
|
|
35
|
+
const { pathname } = useLocation();
|
|
36
|
+
const taxonomyPathRegex = /^\/domains\/(\d+)\/\w+$/;
|
|
37
|
+
const taxonomyPath = pathname.match(taxonomyPathRegex);
|
|
38
|
+
const pathnameSplit = pathname.split("/");
|
|
39
|
+
const domainId = pathnameSplit[2];
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
return (
|
|
42
|
+
<>
|
|
43
|
+
{_.isEmpty(userFilters) ? null : (
|
|
44
|
+
<UserFilters
|
|
45
|
+
applyUserFilter={applyUserFilter}
|
|
46
|
+
userFilterScope={userFilterScope}
|
|
47
|
+
deleteUserFilter={deleteUserFilter}
|
|
48
|
+
domainId={taxonomyPath ? parseInt(domainId) : null}
|
|
49
|
+
resetFilters={resetFilters}
|
|
50
|
+
selectedUserFilter={selectedUserFilter}
|
|
51
|
+
userFilters={userFilters}
|
|
52
|
+
disabled={loading}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
<div className="selectedFilters">
|
|
56
|
+
{_.isEmpty(selectedFilters) ? null : (
|
|
57
|
+
<>
|
|
58
|
+
<div className="appliedFilters">
|
|
59
|
+
<FormattedMessage id="search.applied_filters" />
|
|
60
|
+
</div>
|
|
61
|
+
{selectedFilters.map((filter) => {
|
|
62
|
+
const isSelectedFilter = _.isEqual(filter, selectedFilter);
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
activeValues,
|
|
61
|
-
closeFilter,
|
|
62
|
-
filter,
|
|
63
|
-
loading,
|
|
64
|
-
openFilter,
|
|
65
|
-
options,
|
|
66
|
-
removeFilter,
|
|
67
|
-
toggleFilterValue,
|
|
68
|
-
};
|
|
64
|
+
const filterType = _.prop(filter)(filterTypes);
|
|
65
|
+
const options = isSelectedFilter ? selectedFilterValues : null;
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
67
|
+
const props = {
|
|
68
|
+
key: filter,
|
|
69
|
+
activeValues,
|
|
70
|
+
closeFilter,
|
|
71
|
+
filter,
|
|
72
|
+
loading,
|
|
73
|
+
openFilter,
|
|
74
|
+
options,
|
|
75
|
+
removeFilter,
|
|
76
|
+
toggleFilterValue,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
switch (filterType) {
|
|
80
|
+
case "domain":
|
|
81
|
+
return <FilterMultilevelDropdown {...props} />;
|
|
82
|
+
case "hierarchy":
|
|
83
|
+
return <HierarchyFilterDropdown {...props} />;
|
|
84
|
+
case "search":
|
|
85
|
+
return (
|
|
86
|
+
<SearchFilterDropdown
|
|
87
|
+
{...props}
|
|
88
|
+
{...searchFiltersPropsMapping[filter]}
|
|
89
|
+
open={isSelectedFilter}
|
|
90
|
+
searchFilterDispacher={searchFilterDispacher}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
default:
|
|
94
|
+
return <FilterDropdown {...props} />;
|
|
95
|
+
}
|
|
96
|
+
})}
|
|
97
|
+
<a className="resetFilters" onClick={() => resetFilters()}>
|
|
98
|
+
<FormattedMessage id="search.clear_filters" />
|
|
99
|
+
</a>
|
|
100
|
+
{saveFilters && (
|
|
101
|
+
<ModalSaveFilter
|
|
102
|
+
saveFilters={saveFilters}
|
|
103
|
+
activeFilters={activeFilters}
|
|
104
|
+
scope={userFilterScope}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
</>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
103
113
|
|
|
104
114
|
SelectedFilters.propTypes = {
|
|
105
115
|
activeFilters: PropTypes.object,
|
|
@@ -10,16 +10,35 @@ export const UserFilters = ({
|
|
|
10
10
|
applyUserFilter,
|
|
11
11
|
deleteUserFilter,
|
|
12
12
|
disabled,
|
|
13
|
+
domainId,
|
|
13
14
|
resetFilters,
|
|
14
15
|
selectedUserFilter,
|
|
15
16
|
userFilters,
|
|
16
17
|
userFilterScope,
|
|
17
18
|
}) => {
|
|
18
19
|
const authorized = useAuthorized();
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const showDomainFilter = (filters) => {
|
|
21
|
+
if (_.flow(_.keys, (k) => !_.includes("taxonomy")(k))(filters)) return true;
|
|
22
|
+
|
|
23
|
+
if (_.flow(_.keys, _.equals(["taxonomy"]))(filters)) return false;
|
|
24
|
+
|
|
25
|
+
if (_.flow(_.get("taxonomy"), _.size, (s) => s > 1)(filters)) return false;
|
|
26
|
+
|
|
27
|
+
if (
|
|
28
|
+
_.flow(_.get("taxonomy"), _.head, (t) => !_.equals(domainId)(t))(filters)
|
|
29
|
+
)
|
|
30
|
+
return false;
|
|
31
|
+
|
|
32
|
+
return true;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const sortedUserFilters = _.flow(
|
|
36
|
+
_.filter(({ filters }) =>
|
|
37
|
+
_.isNull(domainId) ? true : showDomainFilter(filters)
|
|
38
|
+
),
|
|
39
|
+
_.orderBy(["is_global", "id"], ["desc", "asc"])
|
|
22
40
|
)(userFilters);
|
|
41
|
+
|
|
23
42
|
return _.isEmpty(userFilters) ? null : (
|
|
24
43
|
<div className="selectedFilters">
|
|
25
44
|
{sortedUserFilters.map((userFilter, key) => {
|
|
@@ -89,6 +108,7 @@ export const UserFilters = ({
|
|
|
89
108
|
UserFilters.propTypes = {
|
|
90
109
|
applyUserFilter: PropTypes.func,
|
|
91
110
|
deleteUserFilter: PropTypes.func,
|
|
111
|
+
domainId: PropTypes.number,
|
|
92
112
|
resetFilters: PropTypes.func,
|
|
93
113
|
selectedUserFilter: PropTypes.string,
|
|
94
114
|
userFilters: PropTypes.array,
|
|
@@ -7,6 +7,13 @@ import { Icon, Dropdown, Segment } from "semantic-ui-react";
|
|
|
7
7
|
|
|
8
8
|
import { SelectedFilters } from "../SelectedFilters";
|
|
9
9
|
|
|
10
|
+
jest.mock("react-router-dom", () => ({
|
|
11
|
+
...jest.requireActual("react-router-dom"),
|
|
12
|
+
useLocation: () => ({
|
|
13
|
+
pathname: "/domains/123/structures",
|
|
14
|
+
}),
|
|
15
|
+
}));
|
|
16
|
+
|
|
10
17
|
const DummyLoader = () => <div></div>;
|
|
11
18
|
const DummyFilerItem = ({ active, toggleFilterValue, option }) => (
|
|
12
19
|
<Dropdown.Item onClick={() => toggleFilterValue(option)} active={active}>
|
|
@@ -144,3 +151,77 @@ describe("<SelectedFilters/>", () => {
|
|
|
144
151
|
).not.toBeNull();
|
|
145
152
|
});
|
|
146
153
|
});
|
|
154
|
+
|
|
155
|
+
describe("<SelectedFilters/> taxonomy screens", () => {
|
|
156
|
+
const props = {
|
|
157
|
+
resetFilters: jest.fn(),
|
|
158
|
+
filterTypes: {
|
|
159
|
+
foo: "fooType",
|
|
160
|
+
},
|
|
161
|
+
openFilter: jest.fn(),
|
|
162
|
+
closeFilter: jest.fn(),
|
|
163
|
+
selectedFilter: "foo",
|
|
164
|
+
selectedFilters: ["foo", "bar"],
|
|
165
|
+
selectedFilterActiveValues: ["value2"],
|
|
166
|
+
selectedFilterValues: ["value1", "value2"],
|
|
167
|
+
selectedUserFilter: null,
|
|
168
|
+
userFilters: [
|
|
169
|
+
{
|
|
170
|
+
id: 1,
|
|
171
|
+
name: "Hide Domain Filter",
|
|
172
|
+
scope: "data_structure",
|
|
173
|
+
filters: { taxonomy: [123] },
|
|
174
|
+
user_id: 1,
|
|
175
|
+
is_global: true,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 2,
|
|
179
|
+
name: "Show Status Filter",
|
|
180
|
+
scope: "data_structure",
|
|
181
|
+
filters: { status: ["pending"] },
|
|
182
|
+
user_id: 1,
|
|
183
|
+
is_global: true,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: 3,
|
|
187
|
+
name: "Hide Multiple Domain Filter",
|
|
188
|
+
scope: "data_structure",
|
|
189
|
+
filters: { status: ["pending"], taxonomy: [123, 321] },
|
|
190
|
+
user_id: 1,
|
|
191
|
+
is_global: true,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: 4,
|
|
195
|
+
name: "Hide Other Domain Filter",
|
|
196
|
+
scope: "data_structure",
|
|
197
|
+
filters: { status: ["pending"], taxonomy: [321] },
|
|
198
|
+
user_id: 1,
|
|
199
|
+
is_global: true,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: 5,
|
|
203
|
+
name: "Show Status and Domain Filter",
|
|
204
|
+
scope: "data_structure",
|
|
205
|
+
filters: { status: ["pending"], taxonomy: [123] },
|
|
206
|
+
user_id: 1,
|
|
207
|
+
is_global: true,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
searchFiltersPropsMapping: {},
|
|
211
|
+
searchFilterDispacher: jest.fn(),
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
it("matches the latest snapshot", () => {
|
|
215
|
+
const { container } = render(<SelectedFilters {...props} />);
|
|
216
|
+
expect(container).toMatchSnapshot();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("render only Show filters", () => {
|
|
220
|
+
const { queryByText } = render(<SelectedFilters {...props} />);
|
|
221
|
+
expect(queryByText("Hide Domain Filter")).toBeNull();
|
|
222
|
+
expect(queryByText("Show Status Filter")).toBeInTheDocument();
|
|
223
|
+
expect(queryByText("Hide Multiple Domain Filter")).toBeNull();
|
|
224
|
+
expect(queryByText("Hide Other Domain Filter")).toBeNull();
|
|
225
|
+
expect(queryByText("Show Status and Domain Filter")).toBeInTheDocument();
|
|
226
|
+
});
|
|
227
|
+
});
|
|
@@ -112,3 +112,74 @@ describe("<UserFilters /> not admin", () => {
|
|
|
112
112
|
expect(container).toMatchSnapshot();
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
|
+
|
|
116
|
+
describe("<UserFilters /> for taxonomy screens", () => {
|
|
117
|
+
jest.mock("../../hooks", () => ({
|
|
118
|
+
...jest.requireActual("../../hooks"),
|
|
119
|
+
useAuthorized: jest.fn(() => true),
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
const props = {
|
|
123
|
+
applyUserFilter,
|
|
124
|
+
deleteUserFilter,
|
|
125
|
+
resetFilters,
|
|
126
|
+
domainId: 123,
|
|
127
|
+
selectedUserFilter,
|
|
128
|
+
userFilters: [
|
|
129
|
+
{
|
|
130
|
+
id: 1,
|
|
131
|
+
name: "Hide Domain Filter",
|
|
132
|
+
scope: "data_structure",
|
|
133
|
+
filters: { taxonomy: [123] },
|
|
134
|
+
user_id: 1,
|
|
135
|
+
is_global: true,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 2,
|
|
139
|
+
name: "Show Status Filter",
|
|
140
|
+
scope: "data_structure",
|
|
141
|
+
filters: { status: ["pending"] },
|
|
142
|
+
user_id: 1,
|
|
143
|
+
is_global: true,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 3,
|
|
147
|
+
name: "Hide Multiple Domain Filter",
|
|
148
|
+
scope: "data_structure",
|
|
149
|
+
filters: { status: ["pending"], taxonomy: [123, 321] },
|
|
150
|
+
user_id: 1,
|
|
151
|
+
is_global: true,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: 4,
|
|
155
|
+
name: "Hide Other Domain Filter",
|
|
156
|
+
scope: "data_structure",
|
|
157
|
+
filters: { status: ["pending"], taxonomy: [321] },
|
|
158
|
+
user_id: 1,
|
|
159
|
+
is_global: true,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: 5,
|
|
163
|
+
name: "Show Status and Domain Filter",
|
|
164
|
+
scope: "data_structure",
|
|
165
|
+
filters: { status: ["pending"], taxonomy: [123] },
|
|
166
|
+
user_id: 1,
|
|
167
|
+
is_global: true,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
it("matches the latest snapshot", () => {
|
|
173
|
+
const { container } = render(<UserFilters {...props} />, renderOpts);
|
|
174
|
+
expect(container).toMatchSnapshot();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("render only Show filters", () => {
|
|
178
|
+
const { queryByText } = render(<UserFilters {...props} />, renderOpts);
|
|
179
|
+
expect(queryByText("Hide Domain Filter")).toBeNull();
|
|
180
|
+
expect(queryByText("Show Status Filter")).toBeInTheDocument();
|
|
181
|
+
expect(queryByText("Hide Multiple Domain Filter")).toBeNull();
|
|
182
|
+
expect(queryByText("Hide Other Domain Filter")).toBeNull();
|
|
183
|
+
expect(queryByText("Show Status and Domain Filter")).toBeInTheDocument();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -109,3 +109,109 @@ exports[`<SelectedFilters/> matches the latest snapshot 1`] = `
|
|
|
109
109
|
</div>
|
|
110
110
|
</div>
|
|
111
111
|
`;
|
|
112
|
+
|
|
113
|
+
exports[`<SelectedFilters/> taxonomy screens matches the latest snapshot 1`] = `
|
|
114
|
+
<div>
|
|
115
|
+
<div
|
|
116
|
+
class="selectedFilters"
|
|
117
|
+
>
|
|
118
|
+
<div
|
|
119
|
+
class="ui basic circular label global"
|
|
120
|
+
>
|
|
121
|
+
<span
|
|
122
|
+
class="userFilter"
|
|
123
|
+
>
|
|
124
|
+
Show Status Filter
|
|
125
|
+
</span>
|
|
126
|
+
</div>
|
|
127
|
+
<div
|
|
128
|
+
class="ui basic circular label global"
|
|
129
|
+
>
|
|
130
|
+
<span
|
|
131
|
+
class="userFilter"
|
|
132
|
+
>
|
|
133
|
+
Show Status and Domain Filter
|
|
134
|
+
</span>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
<div
|
|
138
|
+
class="selectedFilters"
|
|
139
|
+
>
|
|
140
|
+
<div
|
|
141
|
+
class="appliedFilters"
|
|
142
|
+
>
|
|
143
|
+
Filters:
|
|
144
|
+
</div>
|
|
145
|
+
<div
|
|
146
|
+
aria-expanded="true"
|
|
147
|
+
class="ui active visible floating item scrolling dropdown"
|
|
148
|
+
role="listbox"
|
|
149
|
+
tabindex="0"
|
|
150
|
+
>
|
|
151
|
+
<div
|
|
152
|
+
class="ui label"
|
|
153
|
+
>
|
|
154
|
+
foo
|
|
155
|
+
<i
|
|
156
|
+
aria-hidden="true"
|
|
157
|
+
class="delete icon"
|
|
158
|
+
/>
|
|
159
|
+
</div>
|
|
160
|
+
<div
|
|
161
|
+
class="menu transition dimmable visible"
|
|
162
|
+
>
|
|
163
|
+
<div
|
|
164
|
+
aria-checked="false"
|
|
165
|
+
class="item"
|
|
166
|
+
role="option"
|
|
167
|
+
>
|
|
168
|
+
<i
|
|
169
|
+
aria-hidden="true"
|
|
170
|
+
class="square outline icon"
|
|
171
|
+
/>
|
|
172
|
+
<i>
|
|
173
|
+
Empty
|
|
174
|
+
</i>
|
|
175
|
+
</div>
|
|
176
|
+
<div
|
|
177
|
+
aria-checked="false"
|
|
178
|
+
class="item"
|
|
179
|
+
role="option"
|
|
180
|
+
>
|
|
181
|
+
<i
|
|
182
|
+
aria-hidden="true"
|
|
183
|
+
class="square outline icon"
|
|
184
|
+
/>
|
|
185
|
+
<i>
|
|
186
|
+
Empty
|
|
187
|
+
</i>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
<div
|
|
192
|
+
aria-expanded="false"
|
|
193
|
+
class="ui floating item scrolling dropdown"
|
|
194
|
+
role="listbox"
|
|
195
|
+
tabindex="0"
|
|
196
|
+
>
|
|
197
|
+
<div
|
|
198
|
+
class="ui label"
|
|
199
|
+
>
|
|
200
|
+
bar
|
|
201
|
+
<i
|
|
202
|
+
aria-hidden="true"
|
|
203
|
+
class="delete icon"
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
<div
|
|
207
|
+
class="menu transition dimmable"
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
<a
|
|
211
|
+
class="resetFilters"
|
|
212
|
+
>
|
|
213
|
+
Clear filters
|
|
214
|
+
</a>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
`;
|
|
@@ -79,6 +79,33 @@ exports[`<UserFilters /> admin matches the latest snapshot with global filters 1
|
|
|
79
79
|
</div>
|
|
80
80
|
`;
|
|
81
81
|
|
|
82
|
+
exports[`<UserFilters /> for taxonomy screens matches the latest snapshot 1`] = `
|
|
83
|
+
<div>
|
|
84
|
+
<div
|
|
85
|
+
class="selectedFilters"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
class="ui basic circular label global"
|
|
89
|
+
>
|
|
90
|
+
<span
|
|
91
|
+
class="userFilter"
|
|
92
|
+
>
|
|
93
|
+
Show Status Filter
|
|
94
|
+
</span>
|
|
95
|
+
</div>
|
|
96
|
+
<div
|
|
97
|
+
class="ui basic circular label global"
|
|
98
|
+
>
|
|
99
|
+
<span
|
|
100
|
+
class="userFilter"
|
|
101
|
+
>
|
|
102
|
+
Show Status and Domain Filter
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
`;
|
|
108
|
+
|
|
82
109
|
exports[`<UserFilters /> not admin matches the latest snapshot 1`] = `
|
|
83
110
|
<div>
|
|
84
111
|
<div
|
|
@@ -2,6 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React, {
|
|
3
3
|
useState,
|
|
4
4
|
useEffect,
|
|
5
|
+
useCallback,
|
|
5
6
|
useContext,
|
|
6
7
|
createContext,
|
|
7
8
|
useMemo,
|
|
@@ -16,6 +17,8 @@ import { makeOption } from "@truedat/core/services/i18n";
|
|
|
16
17
|
|
|
17
18
|
const SearchContext = createContext();
|
|
18
19
|
|
|
20
|
+
const debounceQueryTime = 300;
|
|
21
|
+
|
|
19
22
|
export const SearchContextProvider = (props) => {
|
|
20
23
|
const initialDefaultFilters = _.prop("defaultFilters")(props);
|
|
21
24
|
const initialActiveFilters = _.propOr({}, "defaultSelectedFilters")(props);
|
|
@@ -56,6 +59,27 @@ export const SearchContextProvider = (props) => {
|
|
|
56
59
|
|
|
57
60
|
const [onSearchChange, setOnSearchChange] = useState();
|
|
58
61
|
|
|
62
|
+
const debouncedTriggerSearch = useCallback(
|
|
63
|
+
_.debounce(debounceQueryTime)((filterParam) => {
|
|
64
|
+
triggerSearch(filterParam).then(({ data, headers }) => {
|
|
65
|
+
setSearchData(data);
|
|
66
|
+
setCountData(headers);
|
|
67
|
+
setLoading(false);
|
|
68
|
+
});
|
|
69
|
+
}),
|
|
70
|
+
[]
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const debouncedTriggerSearchFilters = useCallback(
|
|
74
|
+
_.debounce(debounceQueryTime)((filterParam) => {
|
|
75
|
+
triggerFilters(filterParam).then(({ data }) => {
|
|
76
|
+
setFiltersPayload(data);
|
|
77
|
+
setLoadingFilters(false);
|
|
78
|
+
});
|
|
79
|
+
}),
|
|
80
|
+
[]
|
|
81
|
+
);
|
|
82
|
+
|
|
59
83
|
useEffect(() => {
|
|
60
84
|
if (initialDefaultFilters !== defaultFilters) {
|
|
61
85
|
setDefaultFilters(initialDefaultFilters);
|
|
@@ -188,10 +212,7 @@ export const SearchContextProvider = (props) => {
|
|
|
188
212
|
...(!_.isEmpty(query) && { query }),
|
|
189
213
|
must: filterMust,
|
|
190
214
|
};
|
|
191
|
-
|
|
192
|
-
setFiltersPayload(data);
|
|
193
|
-
setLoadingFilters(false);
|
|
194
|
-
});
|
|
215
|
+
debouncedTriggerSearchFilters(filterParam);
|
|
195
216
|
}, [query, filterMust]);
|
|
196
217
|
|
|
197
218
|
const { trigger: triggerSearch } = useSearch();
|
|
@@ -209,11 +230,7 @@ export const SearchContextProvider = (props) => {
|
|
|
209
230
|
};
|
|
210
231
|
setFilterParams(filterParam);
|
|
211
232
|
|
|
212
|
-
|
|
213
|
-
setSearchData(data);
|
|
214
|
-
setCountData(headers);
|
|
215
|
-
setLoading(false);
|
|
216
|
-
});
|
|
233
|
+
debouncedTriggerSearch(filterParam);
|
|
217
234
|
}, [
|
|
218
235
|
query,
|
|
219
236
|
searchMust,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
3
|
import { FormattedMessage } from "react-intl";
|
|
4
|
+
import { useLocation } from "react-router-dom";
|
|
4
5
|
import ModalSaveFilter from "./ModalSaveFilter";
|
|
5
6
|
import UserFilters from "./UserFilters";
|
|
6
7
|
import FilterDropdown from "./FilterDropdown";
|
|
@@ -22,11 +23,17 @@ export default function SearchSelectedFilters() {
|
|
|
22
23
|
userFiltersType,
|
|
23
24
|
} = context;
|
|
24
25
|
const [selectedUserFilter, setSelectedUserFilter] = useState();
|
|
26
|
+
const { pathname } = useLocation();
|
|
27
|
+
const taxonomyPathRegex = /^\/domains\/(\d+)\/\w+$/;
|
|
28
|
+
const taxonomyPath = pathname.match(taxonomyPathRegex);
|
|
29
|
+
const pathnameSplit = pathname.split("/");
|
|
30
|
+
const domainId = pathnameSplit[2];
|
|
25
31
|
|
|
26
32
|
return (
|
|
27
33
|
<>
|
|
28
34
|
{userFiltersType ? (
|
|
29
35
|
<UserFilters
|
|
36
|
+
domainId={taxonomyPath ? parseInt(domainId) : null}
|
|
30
37
|
setSelectedUserFilter={setSelectedUserFilter}
|
|
31
38
|
selectedUserFilter={selectedUserFilter}
|
|
32
39
|
/>
|
|
@@ -57,7 +57,11 @@ DeleteModal.propTypes = {
|
|
|
57
57
|
mutate: PropTypes.func,
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
export const UserFilters = ({
|
|
60
|
+
export const UserFilters = ({
|
|
61
|
+
domainId,
|
|
62
|
+
setSelectedUserFilter,
|
|
63
|
+
selectedUserFilter,
|
|
64
|
+
}) => {
|
|
61
65
|
const authorized = useAuthorized();
|
|
62
66
|
const {
|
|
63
67
|
userFiltersType,
|
|
@@ -72,9 +76,26 @@ export const UserFilters = ({ setSelectedUserFilter, selectedUserFilter }) => {
|
|
|
72
76
|
mutate,
|
|
73
77
|
} = useUserFilters(userFiltersType, userFilterScope);
|
|
74
78
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
const showDomainFilter = (filters) => {
|
|
80
|
+
if (_.flow(_.keys, (k) => !_.includes("taxonomy")(k))(filters)) return true;
|
|
81
|
+
|
|
82
|
+
if (_.flow(_.keys, _.equals(["taxonomy"]))(filters)) return false;
|
|
83
|
+
|
|
84
|
+
if (_.flow(_.get("taxonomy"), _.size, (s) => s > 1)(filters)) return false;
|
|
85
|
+
|
|
86
|
+
if (
|
|
87
|
+
_.flow(_.get("taxonomy"), _.head, (t) => !_.equals(domainId)(t))(filters)
|
|
88
|
+
)
|
|
89
|
+
return false;
|
|
90
|
+
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const sortedUserFilters = _.flow(
|
|
95
|
+
_.filter(({ filters }) =>
|
|
96
|
+
_.isNull(domainId) ? true : showDomainFilter(filters)
|
|
97
|
+
),
|
|
98
|
+
_.orderBy(["is_global", "id"], ["desc", "asc"])
|
|
78
99
|
)(userFilters);
|
|
79
100
|
|
|
80
101
|
return _.isEmpty(userFilters) ? null : (
|
|
@@ -127,6 +148,7 @@ export const UserFilters = ({ setSelectedUserFilter, selectedUserFilter }) => {
|
|
|
127
148
|
};
|
|
128
149
|
|
|
129
150
|
UserFilters.propTypes = {
|
|
151
|
+
domainId: PropTypes.number,
|
|
130
152
|
selectedUserFilter: PropTypes.string,
|
|
131
153
|
setSelectedUserFilter: PropTypes.func,
|
|
132
154
|
};
|