@truedat/core 5.18.1 → 5.18.3
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/ConfirmModal.js +1 -0
- package/src/components/FilterDropdown.js +132 -52
- package/src/components/FilterMultilevelDropdown.js +3 -0
- package/src/components/HierarchyFilterDropdown.js +2 -1
- package/src/components/SearchFilterDropdown.js +155 -0
- package/src/components/SelectedFilters.js +26 -10
- package/src/components/StructureFilterItem.js +33 -0
- package/src/components/__tests__/FilterDropdown.spec.js +172 -37
- package/src/components/__tests__/SearchFilterDropdown.spec.js +106 -0
- package/src/components/__tests__/SelectedFilters.spec.js +89 -32
- package/src/components/__tests__/StructureFilterItem.spec.js +26 -0
- package/src/components/__tests__/__snapshots__/FilterDropdown.spec.js.snap +43 -62
- package/src/components/__tests__/__snapshots__/FilterMultilevelDropdown.spec.js.snap +1 -0
- package/src/components/__tests__/__snapshots__/HierarchyFilterDropdown.spec.js.snap +2 -0
- package/src/components/__tests__/__snapshots__/SearchFilterDropdown.spec.js.snap +147 -0
- package/src/components/__tests__/__snapshots__/SelectedFilters.spec.js.snap +97 -49
- package/src/components/__tests__/__snapshots__/StructureFilterItem.spec.js.snap +28 -0
- package/src/components/index.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "5.18.
|
|
3
|
+
"version": "5.18.3",
|
|
4
4
|
"description": "Truedat Web Core",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"react-dom": ">= 16.8.6 < 17",
|
|
118
118
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "ba00f358149f00dcdabb3e3edd883c54c0bbd43a"
|
|
121
121
|
}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { FormattedMessage } from "react-intl";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
Label,
|
|
7
|
+
Icon,
|
|
8
|
+
Dropdown,
|
|
9
|
+
Dimmer,
|
|
10
|
+
Loader,
|
|
11
|
+
Input,
|
|
12
|
+
} from "semantic-ui-react";
|
|
13
|
+
import { accentInsensitivePathOrder, lowerDeburr } from "../services/sort";
|
|
7
14
|
import FilterItem from "./FilterItem";
|
|
8
15
|
|
|
9
16
|
const removePrefix = _.replace(/^.*\./, "");
|
|
@@ -17,55 +24,128 @@ export const FilterDropdown = ({
|
|
|
17
24
|
options,
|
|
18
25
|
removeFilter,
|
|
19
26
|
toggleFilterValue,
|
|
20
|
-
}) =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
27
|
+
}) => {
|
|
28
|
+
const [selected, setSelected] = useState();
|
|
29
|
+
const [query, setQuery] = useState();
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const activeOptions = _.filter((option) =>
|
|
33
|
+
_.includes(option.value)(activeValues)
|
|
34
|
+
)(options);
|
|
35
|
+
|
|
36
|
+
_.flow(
|
|
37
|
+
_.reduce((acc, option) => [...acc, option], []),
|
|
38
|
+
_.uniq,
|
|
39
|
+
setSelected
|
|
40
|
+
)(activeOptions);
|
|
41
|
+
}, [activeValues, options]);
|
|
42
|
+
|
|
43
|
+
const handleSearch = (e, { value }) => {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
setQuery(lowerDeburr(value));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const toogleSelectedOption = (selectedOption) => {
|
|
49
|
+
const newSelectedOptions = selected.find(
|
|
50
|
+
(s) => s.value === selectedOption.value
|
|
51
|
+
)
|
|
52
|
+
? selected.filter((s) => s.value !== selectedOption.value)
|
|
53
|
+
: [...selected, selectedOption];
|
|
54
|
+
setSelected(newSelectedOptions);
|
|
55
|
+
toggleFilterValue({ filter, value: selectedOption.value });
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const match = (name, query) => _.contains(query)(lowerDeburr(name));
|
|
59
|
+
const filterSearch = (all) =>
|
|
60
|
+
query ? _.filter((option) => match(option.text, query))(all) : all;
|
|
61
|
+
|
|
62
|
+
const filteredOptions = filterSearch(options);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Dropdown
|
|
66
|
+
item
|
|
67
|
+
floating
|
|
68
|
+
scrolling
|
|
69
|
+
icon={false}
|
|
70
|
+
upward={false}
|
|
71
|
+
trigger={
|
|
72
|
+
<Label key={filter}>
|
|
73
|
+
<FormattedMessage
|
|
74
|
+
id={`filters.${filter}`}
|
|
75
|
+
defaultMessage={removePrefix(filter)}
|
|
76
|
+
/>
|
|
77
|
+
<Icon
|
|
78
|
+
name="delete"
|
|
79
|
+
onClick={(e) => {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
e.stopPropagation();
|
|
82
|
+
removeFilter({ filter });
|
|
83
|
+
}}
|
|
84
|
+
/>
|
|
85
|
+
</Label>
|
|
86
|
+
}
|
|
87
|
+
onOpen={() => openFilter({ filter })}
|
|
88
|
+
onClose={() => closeFilter({ filter })}
|
|
89
|
+
open={!_.isEmpty(options)}
|
|
90
|
+
>
|
|
91
|
+
<Dimmer.Dimmable as={Dropdown.Menu} dimmed={loading}>
|
|
92
|
+
<>
|
|
93
|
+
{options && options.length >= 8 && (
|
|
94
|
+
<>
|
|
95
|
+
<Input
|
|
96
|
+
icon="search"
|
|
97
|
+
iconPosition="left"
|
|
98
|
+
className="search"
|
|
99
|
+
onKeyDown={(e) => {
|
|
100
|
+
if (e.key === " ") {
|
|
101
|
+
e.stopPropagation();
|
|
102
|
+
}
|
|
103
|
+
}}
|
|
104
|
+
onChange={handleSearch}
|
|
105
|
+
onClick={(e) => {
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
e.stopPropagation();
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
{selected &&
|
|
111
|
+
_.flow(
|
|
112
|
+
_.sortBy(accentInsensitivePathOrder("text")),
|
|
113
|
+
_.map.convert({ cap: false })((option, i) => (
|
|
114
|
+
<FilterItem
|
|
115
|
+
key={i}
|
|
116
|
+
filter={filter}
|
|
117
|
+
option={option}
|
|
118
|
+
toggleFilterValue={toogleSelectedOption}
|
|
119
|
+
active={_.includes(_.prop("value")(option))(activeValues)}
|
|
120
|
+
/>
|
|
121
|
+
))
|
|
122
|
+
)(selected)}
|
|
123
|
+
<Dropdown.Divider />
|
|
124
|
+
</>
|
|
125
|
+
)}
|
|
126
|
+
{filteredOptions &&
|
|
127
|
+
_.flow(
|
|
128
|
+
_.sortBy(accentInsensitivePathOrder("text")),
|
|
129
|
+
_.map.convert({ cap: false })((option, i) => (
|
|
130
|
+
<FilterItem
|
|
131
|
+
key={i}
|
|
132
|
+
filter={filter}
|
|
133
|
+
option={option}
|
|
134
|
+
toggleFilterValue={toggleFilterValue}
|
|
135
|
+
active={_.includes(_.prop("value")(option))(activeValues)}
|
|
136
|
+
/>
|
|
137
|
+
))
|
|
138
|
+
)(filteredOptions)}
|
|
139
|
+
</>
|
|
140
|
+
{loading && (
|
|
141
|
+
<Dimmer active inverted>
|
|
142
|
+
<Loader size="tiny" />
|
|
143
|
+
</Dimmer>
|
|
144
|
+
)}
|
|
145
|
+
</Dimmer.Dimmable>
|
|
146
|
+
</Dropdown>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
69
149
|
|
|
70
150
|
FilterDropdown.propTypes = {
|
|
71
151
|
activeValues: PropTypes.array,
|
|
@@ -14,6 +14,7 @@ import { lowerDeburr } from "../services/sort";
|
|
|
14
14
|
import DropdownMenuItem from "./DropdownMenuItem";
|
|
15
15
|
|
|
16
16
|
export const FilterMultilevelDropdown = ({
|
|
17
|
+
name,
|
|
17
18
|
activeValues,
|
|
18
19
|
closeFilter,
|
|
19
20
|
filter,
|
|
@@ -130,6 +131,7 @@ export const FilterMultilevelDropdown = ({
|
|
|
130
131
|
|
|
131
132
|
return (
|
|
132
133
|
<Dropdown
|
|
134
|
+
name={name || "filterMultilevelDropdown"}
|
|
133
135
|
item
|
|
134
136
|
floating
|
|
135
137
|
icon={false}
|
|
@@ -193,6 +195,7 @@ export const FilterMultilevelDropdown = ({
|
|
|
193
195
|
};
|
|
194
196
|
|
|
195
197
|
FilterMultilevelDropdown.propTypes = {
|
|
198
|
+
name: PropTypes.string,
|
|
196
199
|
activeValues: PropTypes.array,
|
|
197
200
|
closeFilter: PropTypes.func,
|
|
198
201
|
filter: PropTypes.string,
|
|
@@ -72,6 +72,7 @@ const PopulatedHierarchyFilterDropdown = (props) => {
|
|
|
72
72
|
|
|
73
73
|
return (
|
|
74
74
|
<FilterMultilevelDropdown
|
|
75
|
+
name="hierarchyFilterDropdown"
|
|
75
76
|
activeValues={idActiveValues}
|
|
76
77
|
closeFilter={closeFilter}
|
|
77
78
|
filter={filter}
|
|
@@ -97,7 +98,7 @@ PopulatedHierarchyFilterDropdown.propTypes = {
|
|
|
97
98
|
|
|
98
99
|
const HierarchyFilterDropdown = (props) =>
|
|
99
100
|
_.isEmpty(props.options) ? (
|
|
100
|
-
<FilterMultilevelDropdown {...props} />
|
|
101
|
+
<FilterMultilevelDropdown {...props} name="hierarchyFilterDropdown" />
|
|
101
102
|
) : (
|
|
102
103
|
<PopulatedHierarchyFilterDropdown {...props} />
|
|
103
104
|
);
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import _ from "lodash/fp";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Label,
|
|
9
|
+
Icon,
|
|
10
|
+
Dropdown,
|
|
11
|
+
Dimmer,
|
|
12
|
+
Loader,
|
|
13
|
+
Input,
|
|
14
|
+
} from "semantic-ui-react";
|
|
15
|
+
import { accentInsensitivePathOrder } from "../services/sort";
|
|
16
|
+
|
|
17
|
+
const removePrefix = _.replace(/^.*\./, "");
|
|
18
|
+
const SPACE_CODE = 32;
|
|
19
|
+
|
|
20
|
+
export const SearchFilterDropdown = ({
|
|
21
|
+
query,
|
|
22
|
+
searchCallback,
|
|
23
|
+
placeholder,
|
|
24
|
+
options,
|
|
25
|
+
open,
|
|
26
|
+
loading,
|
|
27
|
+
activeValues,
|
|
28
|
+
closeFilter,
|
|
29
|
+
filter,
|
|
30
|
+
FilterDataLoader,
|
|
31
|
+
loaderProps,
|
|
32
|
+
FilterItem,
|
|
33
|
+
openFilter,
|
|
34
|
+
removeFilter,
|
|
35
|
+
toggleFilterValue,
|
|
36
|
+
searchFilterDispacher,
|
|
37
|
+
}) => {
|
|
38
|
+
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
39
|
+
const { formatMessage } = useIntl();
|
|
40
|
+
|
|
41
|
+
const toogleSelectedOption = (selectedOption) => {
|
|
42
|
+
const newSelectedOptions = selectedOptions.find(
|
|
43
|
+
(s) => s.id === selectedOption.id
|
|
44
|
+
)
|
|
45
|
+
? selectedOptions.filter((s) => s.id !== selectedOption.id)
|
|
46
|
+
: [...selectedOptions, selectedOption];
|
|
47
|
+
setSelectedOptions(newSelectedOptions);
|
|
48
|
+
toggleFilterValue({ filter, value: selectedOption.id });
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Dropdown
|
|
53
|
+
name="searchFilterDropdown"
|
|
54
|
+
item
|
|
55
|
+
floating
|
|
56
|
+
scrolling
|
|
57
|
+
icon={false}
|
|
58
|
+
upward={false}
|
|
59
|
+
trigger={
|
|
60
|
+
<Label key={filter}>
|
|
61
|
+
{formatMessage({
|
|
62
|
+
id: `filters.${filter}`,
|
|
63
|
+
defaultMessage: removePrefix(filter),
|
|
64
|
+
})}
|
|
65
|
+
<Icon
|
|
66
|
+
name="delete"
|
|
67
|
+
onClick={(e) => {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
removeFilter({ filter });
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
</Label>
|
|
74
|
+
}
|
|
75
|
+
onOpen={() => openFilter({ filter })}
|
|
76
|
+
onClose={(e) => {
|
|
77
|
+
// Next line Fix bug: https://github.com/Semantic-Org/Semantic-UI-React/pull/3766
|
|
78
|
+
if (e?.type === "keydown" && e?.keyCode === SPACE_CODE) return;
|
|
79
|
+
closeFilter({ filter });
|
|
80
|
+
}}
|
|
81
|
+
open={open}
|
|
82
|
+
>
|
|
83
|
+
<Dimmer.Dimmable as={Dropdown.Menu} dimmed={loading}>
|
|
84
|
+
<FilterDataLoader {...loaderProps} />
|
|
85
|
+
<Input
|
|
86
|
+
icon="search"
|
|
87
|
+
iconPosition="left"
|
|
88
|
+
placeholder={placeholder}
|
|
89
|
+
// Next line Fix bug: https://github.com/Semantic-Org/Semantic-UI-React/issues/1593
|
|
90
|
+
onClick={(e) => e.stopPropagation()}
|
|
91
|
+
value={query}
|
|
92
|
+
onChange={(_e, data) =>
|
|
93
|
+
searchFilterDispacher(searchCallback({ query: data.value }))
|
|
94
|
+
}
|
|
95
|
+
// Next line Fix bug: https://github.com/Semantic-Org/Semantic-UI-React/issues/4374
|
|
96
|
+
onKeyDown={(e) => e.keyCode === SPACE_CODE && e.stopPropagation()}
|
|
97
|
+
/>
|
|
98
|
+
{selectedOptions &&
|
|
99
|
+
_.flow(
|
|
100
|
+
_.sortBy(accentInsensitivePathOrder("text")),
|
|
101
|
+
_.map.convert({ cap: false })((option, i) => (
|
|
102
|
+
<FilterItem
|
|
103
|
+
key={i}
|
|
104
|
+
filter={filter}
|
|
105
|
+
option={option}
|
|
106
|
+
toggleFilterValue={toogleSelectedOption}
|
|
107
|
+
active={_.includes(_.prop("id")(option))(activeValues)}
|
|
108
|
+
/>
|
|
109
|
+
))
|
|
110
|
+
)(selectedOptions)}
|
|
111
|
+
<Dropdown.Divider />
|
|
112
|
+
{options &&
|
|
113
|
+
_.flow(
|
|
114
|
+
_.sortBy(accentInsensitivePathOrder("text")),
|
|
115
|
+
_.filter((o) => !_.includes(_.prop("id")(o))(activeValues)),
|
|
116
|
+
_.map.convert({ cap: false })((option, i) => (
|
|
117
|
+
<FilterItem
|
|
118
|
+
key={i}
|
|
119
|
+
filter={filter}
|
|
120
|
+
option={option}
|
|
121
|
+
toggleFilterValue={toogleSelectedOption}
|
|
122
|
+
active={_.includes(_.prop("id")(option))(activeValues)}
|
|
123
|
+
/>
|
|
124
|
+
))
|
|
125
|
+
)(options)}
|
|
126
|
+
{loading && (
|
|
127
|
+
<Dimmer active inverted>
|
|
128
|
+
<Loader size="tiny" />
|
|
129
|
+
</Dimmer>
|
|
130
|
+
)}
|
|
131
|
+
</Dimmer.Dimmable>
|
|
132
|
+
</Dropdown>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
SearchFilterDropdown.propTypes = {
|
|
137
|
+
query: PropTypes.string,
|
|
138
|
+
searchCallback: PropTypes.func,
|
|
139
|
+
placeholder: PropTypes.string,
|
|
140
|
+
options: PropTypes.object,
|
|
141
|
+
open: PropTypes.bool,
|
|
142
|
+
loading: PropTypes.bool,
|
|
143
|
+
activeValues: PropTypes.array,
|
|
144
|
+
closeFilter: PropTypes.func,
|
|
145
|
+
filter: PropTypes.string,
|
|
146
|
+
FilterDataLoader: PropTypes.node,
|
|
147
|
+
loaderProps: PropTypes.object,
|
|
148
|
+
FilterItem: PropTypes.object,
|
|
149
|
+
openFilter: PropTypes.func,
|
|
150
|
+
removeFilter: PropTypes.func,
|
|
151
|
+
toggleFilterValue: PropTypes.func,
|
|
152
|
+
searchFilterDispacher: PropTypes.func,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export default SearchFilterDropdown;
|
|
@@ -5,6 +5,7 @@ import { FormattedMessage } from "react-intl";
|
|
|
5
5
|
import FilterDropdown from "./FilterDropdown";
|
|
6
6
|
import FilterMultilevelDropdown from "./FilterMultilevelDropdown";
|
|
7
7
|
import HierarchyFilterDropdown from "./HierarchyFilterDropdown";
|
|
8
|
+
import SearchFilterDropdown from "./SearchFilterDropdown";
|
|
8
9
|
import ModalSaveFilter from "./ModalSaveFilter";
|
|
9
10
|
import UserFilters from "./UserFilters";
|
|
10
11
|
|
|
@@ -27,6 +28,8 @@ export const SelectedFilters = ({
|
|
|
27
28
|
toggleFilterValue,
|
|
28
29
|
userFilters,
|
|
29
30
|
userFilterScope,
|
|
31
|
+
searchFiltersPropsMapping,
|
|
32
|
+
searchFilterDispacher,
|
|
30
33
|
}) => (
|
|
31
34
|
<>
|
|
32
35
|
{_.isEmpty(userFilters) ? null : (
|
|
@@ -47,10 +50,10 @@ export const SelectedFilters = ({
|
|
|
47
50
|
<FormattedMessage id="search.applied_filters" />
|
|
48
51
|
</div>
|
|
49
52
|
{selectedFilters.map((filter) => {
|
|
53
|
+
const isSelectedFilter = _.isEqual(filter, selectedFilter);
|
|
54
|
+
|
|
50
55
|
const filterType = _.prop(filter)(filterTypes);
|
|
51
|
-
const options =
|
|
52
|
-
? selectedFilterValues
|
|
53
|
-
: null;
|
|
56
|
+
const options = isSelectedFilter ? selectedFilterValues : null;
|
|
54
57
|
|
|
55
58
|
const props = {
|
|
56
59
|
key: filter,
|
|
@@ -63,13 +66,24 @@ export const SelectedFilters = ({
|
|
|
63
66
|
removeFilter,
|
|
64
67
|
toggleFilterValue,
|
|
65
68
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
|
|
70
|
+
switch (filterType) {
|
|
71
|
+
case "domain":
|
|
72
|
+
return <FilterMultilevelDropdown {...props} />;
|
|
73
|
+
case "hierarchy":
|
|
74
|
+
return <HierarchyFilterDropdown {...props} />;
|
|
75
|
+
case "search":
|
|
76
|
+
return (
|
|
77
|
+
<SearchFilterDropdown
|
|
78
|
+
{...props}
|
|
79
|
+
{...searchFiltersPropsMapping[filter]}
|
|
80
|
+
open={isSelectedFilter}
|
|
81
|
+
searchFilterDispacher={searchFilterDispacher}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
default:
|
|
85
|
+
return <FilterDropdown {...props} />;
|
|
86
|
+
}
|
|
73
87
|
})}
|
|
74
88
|
<a className="resetFilters" onClick={() => resetFilters()}>
|
|
75
89
|
<FormattedMessage id="search.clear_filters" />
|
|
@@ -106,6 +120,8 @@ SelectedFilters.propTypes = {
|
|
|
106
120
|
toggleFilterValue: PropTypes.func,
|
|
107
121
|
userFilters: PropTypes.array,
|
|
108
122
|
userFilterScope: PropTypes.string,
|
|
123
|
+
searchFiltersPropsMapping: PropTypes.object,
|
|
124
|
+
searchFilterDispacher: PropTypes.func,
|
|
109
125
|
};
|
|
110
126
|
|
|
111
127
|
export default SelectedFilters;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Icon, Dropdown, Segment } from "semantic-ui-react";
|
|
5
|
+
|
|
6
|
+
const preventDefault = (e, callback) => {
|
|
7
|
+
e && e.preventDefault();
|
|
8
|
+
e && e.stopPropagation();
|
|
9
|
+
callback();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const StructureFilterItem = ({ active, toggleFilterValue, option }) => (
|
|
13
|
+
<Dropdown.Item
|
|
14
|
+
onClick={(e) => preventDefault(e, () => toggleFilterValue(option))}
|
|
15
|
+
active={active}
|
|
16
|
+
>
|
|
17
|
+
<Segment vertical>
|
|
18
|
+
<Icon name={active ? "check square outline" : "square outline"} />
|
|
19
|
+
{_.trim(option.name)}
|
|
20
|
+
<small>{` - (${option.type})`}</small>
|
|
21
|
+
<br />
|
|
22
|
+
<small>{option.path.join(" > ")}</small>
|
|
23
|
+
</Segment>
|
|
24
|
+
</Dropdown.Item>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
StructureFilterItem.propTypes = {
|
|
28
|
+
active: PropTypes.bool,
|
|
29
|
+
toggleFilterValue: PropTypes.func,
|
|
30
|
+
option: PropTypes.object,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default StructureFilterItem;
|