@truedat/dd 6.6.0 → 6.6.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.
Files changed (102) hide show
  1. package/package.json +6 -6
  2. package/src/components/CatalogCustomViewCards.js +9 -32
  3. package/src/components/DictionaryRoutes.js +1 -9
  4. package/src/components/GrantRemovalDirectButton.js +1 -3
  5. package/src/components/GrantRequestBulkRoleSelector.js +1 -0
  6. package/src/components/GrantRequestCancel.js +1 -1
  7. package/src/components/GrantRoutes.js +22 -15
  8. package/src/components/StructureGrantListButton.js +4 -4
  9. package/src/components/StructureSelector.js +70 -44
  10. package/src/components/StructureStructureForm.js +1 -1
  11. package/src/components/StructuresBulkUpdate.js +10 -14
  12. package/src/components/StructuresDownloadOption.js +31 -27
  13. package/src/components/StructuresEditableDownloadOption.js +12 -7
  14. package/src/components/StructuresGrantRequestView.js +55 -24
  15. package/src/components/StructuresLabelResults.js +5 -11
  16. package/src/components/StructuresPagination.js +13 -15
  17. package/src/components/StructuresRoutes.js +2 -18
  18. package/src/components/StructuresTable.js +79 -115
  19. package/src/components/StructuresUpdateOption.js +77 -9
  20. package/src/components/StructuresView.js +67 -52
  21. package/src/components/__tests__/CatalogCustomViewCards.spec.js +44 -7
  22. package/src/components/__tests__/StructureGrantListButton.spec.js +27 -17
  23. package/src/components/__tests__/StructureSelector.spec.js +70 -25
  24. package/src/components/__tests__/StructureStructureForm.spec.js +92 -60
  25. package/src/components/__tests__/StructureStructureLinks.spec.js +1 -1
  26. package/src/components/__tests__/StructuresBulkUpdate.spec.js +26 -14
  27. package/src/components/__tests__/StructuresDownloadOption.spec.js +38 -5
  28. package/src/components/__tests__/StructuresEditableDownloadOption.spec.js +20 -8
  29. package/src/components/__tests__/StructuresGrantRequestView.spec.js +43 -15
  30. package/src/components/__tests__/StructuresLabelResults.spec.js +37 -10
  31. package/src/components/__tests__/StructuresOptions.spec.js +62 -1
  32. package/src/components/__tests__/StructuresSearchResults.spec.js +67 -12
  33. package/src/components/__tests__/StructuresTable.spec.js +77 -88
  34. package/src/components/__tests__/StructuresUpdateOption.spec.js +53 -6
  35. package/src/components/__tests__/StructuresView.spec.js +126 -31
  36. package/src/components/__tests__/__snapshots__/GrantRoutes.spec.js.snap +5 -0
  37. package/src/components/__tests__/__snapshots__/StructureSelector.spec.js.snap +206 -42
  38. package/src/components/__tests__/__snapshots__/StructuresDownloadOption.spec.js.snap +17 -0
  39. package/src/components/__tests__/__snapshots__/StructuresGrantRequestView.spec.js.snap +68 -5
  40. package/src/components/__tests__/__snapshots__/StructuresLabelResults.spec.js.snap +7 -12
  41. package/src/components/__tests__/__snapshots__/StructuresSearchResults.spec.js.snap +72 -27
  42. package/src/components/__tests__/__snapshots__/StructuresTable.spec.js.snap +226 -153
  43. package/src/components/__tests__/__snapshots__/StructuresUpdateOption.spec.js.snap +3 -3
  44. package/src/components/index.js +0 -8
  45. package/src/hooks/useStructures.js +6 -6
  46. package/src/reducers/__tests__/selectedUserSearchFilter.spec.js +2 -23
  47. package/src/reducers/__tests__/structureQuery.spec.js +1 -63
  48. package/src/reducers/index.js +0 -18
  49. package/src/reducers/previousStructureQuery.js +3 -6
  50. package/src/reducers/selectedUserSearchFilter.js +1 -10
  51. package/src/reducers/structureQuery.js +1 -33
  52. package/src/routines.js +1 -15
  53. package/src/sagas/__tests__/bulkUpdateStructures.spec.js +7 -7
  54. package/src/sagas/__tests__/downloadEditableStructures.spec.js +1 -6
  55. package/src/sagas/__tests__/downloadStructures.spec.js +2 -7
  56. package/src/sagas/__tests__/fetchStructures.spec.js +4 -4
  57. package/src/sagas/bulkUpdateStructures.js +6 -4
  58. package/src/sagas/downloadEditableStructures.js +2 -3
  59. package/src/sagas/downloadStructures.js +2 -3
  60. package/src/sagas/index.js +0 -3
  61. package/src/selectors/__tests__/getGrantSelectedFilters.spec.js +1 -1
  62. package/src/selectors/__tests__/structureColumnsSelector.spec.js +5 -19
  63. package/src/selectors/__tests__/templateNamesSelector.spec.js +19 -0
  64. package/src/selectors/getGrantRequestsSelectedFilters.js +3 -1
  65. package/src/selectors/index.js +1 -8
  66. package/src/selectors/structureColumnsSelector.js +6 -46
  67. package/src/selectors/templateNamesSelector.js +7 -0
  68. package/src/utils/structureCustomTranslations.js +19 -0
  69. package/src/components/StructureDateFilter.js +0 -32
  70. package/src/components/StructureFilters.js +0 -19
  71. package/src/components/StructureFiltersLoader.js +0 -32
  72. package/src/components/StructureSelectedFilters.js +0 -94
  73. package/src/components/__tests__/StructureDateFilter.spec.js +0 -11
  74. package/src/components/__tests__/__snapshots__/StructureDateFilter.spec.js.snap +0 -13
  75. package/src/reducers/__tests__/structureActiveFilters.spec.js +0 -100
  76. package/src/reducers/__tests__/structureDateFilter.spec.js +0 -57
  77. package/src/reducers/__tests__/structureFilters.spec.js +0 -37
  78. package/src/reducers/__tests__/structureUserFilters.spec.js +0 -76
  79. package/src/reducers/__tests__/structuresActions.spec.js +0 -38
  80. package/src/reducers/__tests__/structuresLoading.spec.js +0 -26
  81. package/src/reducers/structureActiveFilters.js +0 -58
  82. package/src/reducers/structureCount.js +0 -20
  83. package/src/reducers/structureDateFilter.js +0 -33
  84. package/src/reducers/structureFilters.js +0 -21
  85. package/src/reducers/structureFiltersLoading.js +0 -14
  86. package/src/reducers/structureSelectedFilter.js +0 -34
  87. package/src/reducers/structuresActions.js +0 -18
  88. package/src/reducers/structuresLoading.js +0 -14
  89. package/src/reducers/structuresPageSize.js +0 -15
  90. package/src/sagas/fetchStructureFilters.js +0 -29
  91. package/src/selectors/__tests__/bulkUpdateDisabledSelector.spec.js +0 -72
  92. package/src/selectors/__tests__/getStructureAvailableFilters.spec.js +0 -15
  93. package/src/selectors/__tests__/getStructureSelectedFilterActiveValues.spec.js +0 -20
  94. package/src/selectors/__tests__/getStructureSelectedFilterValues.spec.js +0 -15
  95. package/src/selectors/__tests__/getStructureSelectedFilters.spec.js +0 -15
  96. package/src/selectors/bulkUpdateDisabledSelector.js +0 -46
  97. package/src/selectors/getPreviousStructureQuery.js +0 -2
  98. package/src/selectors/getStructureAvailableFilters.js +0 -15
  99. package/src/selectors/getStructureFilterTypes.js +0 -7
  100. package/src/selectors/getStructureSelectedFilterActiveValues.js +0 -9
  101. package/src/selectors/getStructureSelectedFilterValues.js +0 -12
  102. package/src/selectors/getStructureSelectedFilters.js +0 -7
@@ -6,18 +6,35 @@ import { useHistory } from "react-router-dom";
6
6
  import { Header, Icon, Divider } from "semantic-ui-react";
7
7
  import { FormattedMessage } from "react-intl";
8
8
  import { linkTo } from "@truedat/core/routes";
9
- import { structureRowsSelector } from "../selectors";
10
- import StructureSelectedFilters from "./StructureSelectedFilters";
11
- import StructureDateFilter from "./StructureDateFilter";
12
- import StructuresSearch from "./StructuresSearch";
9
+ import {
10
+ SearchContextProvider,
11
+ useSearchContext,
12
+ } from "@truedat/core/search/SearchContext";
13
+
14
+ import SearchWidget from "@truedat/core/search/SearchWidget";
15
+ import translations from "../utils/structureCustomTranslations";
16
+ import {
17
+ useDataStructureFilters,
18
+ useDataStructureSearch,
19
+ } from "../hooks/useStructures";
20
+
13
21
  import StructuresSearchResults from "./StructuresSearchResults";
14
22
  import StructureGrantCart from "./StructureGrantCart";
15
23
 
16
- export const StructuresGrantRequestView = ({ loading, structures }) => {
24
+ export function StructuresGrantRequestViewContent() {
17
25
  const history = useHistory();
18
26
  const segment = useRef(null);
19
27
  const [isOverflown, setIsOverflown] = useState(null);
20
28
 
29
+ const { searchData, loading } = useSearchContext();
30
+ const structures = searchData?.data;
31
+
32
+ const isOverflownFn = (element) =>
33
+ !element
34
+ ? false
35
+ : element.scrollHeight > element.clientHeight ||
36
+ element.scrollWidth > element.clientWidth;
37
+
21
38
  useEffect(() => {
22
39
  setIsOverflown(isOverflownFn(segment.current));
23
40
  }, [loading]);
@@ -67,9 +84,7 @@ export const StructuresGrantRequestView = ({ loading, structures }) => {
67
84
  </Header.Content>
68
85
  </Header>
69
86
  <Divider hidden />
70
- <StructuresSearch />
71
- <StructureSelectedFilters />
72
- <StructureDateFilter />
87
+ <SearchWidget dateFilter />
73
88
  <StructuresSearchResults
74
89
  structures={structures}
75
90
  loading={loading}
@@ -79,28 +94,44 @@ export const StructuresGrantRequestView = ({ loading, structures }) => {
79
94
  </div>
80
95
  </div>
81
96
  );
82
- };
97
+ }
83
98
 
84
- const isOverflownFn = (element) =>
85
- !element
86
- ? false
87
- : element.scrollHeight > element.clientHeight ||
88
- element.scrollWidth > element.clientWidth;
99
+ export const StructuresGrantRequestView = (props) => {
100
+ const defaultFilters = _.propOr({}, "defaultFilters")(props);
101
+ const filtersGroup = _.propOr([], "filtersGroup")(props);
102
+ const enrichSearchPayload = {
103
+ my_grant_requests: true,
104
+ with_data_fields: false,
105
+ };
106
+
107
+ const searchProps = {
108
+ initialSortColumn: "name.raw",
109
+ initialSortDirection: "ascending",
110
+ useSearch: useDataStructureSearch,
111
+ useFilters: useDataStructureFilters,
112
+ pageSize: 20,
113
+ userFiltersType: "user_search_filters",
114
+ userFilterScope: "data_structure",
115
+ translations,
116
+ filtersGroup,
117
+ defaultFilters,
118
+ enrichSearchPayload,
119
+ };
120
+
121
+ return (
122
+ <SearchContextProvider {...searchProps}>
123
+ <StructuresGrantRequestViewContent />
124
+ </SearchContextProvider>
125
+ );
126
+ };
89
127
 
90
128
  StructuresGrantRequestView.propTypes = {
91
- structures: PropTypes.array,
92
- loading: PropTypes.bool,
129
+ filtersGroup: PropTypes.array,
130
+ defaultFilters: PropTypes.object,
93
131
  };
94
132
 
95
133
  const mapStateToProps = (state) => ({
96
- structures: structureRowsSelector(state, null, [
97
- "my_grants",
98
- "my_grant_request",
99
- "external_id",
100
- "data_fields",
101
- "user_permissions",
102
- ]),
103
- loading: state.structuresLoading,
134
+ filtersGroup: state?.structureFiltersGroup,
104
135
  });
105
136
 
106
137
  export default connect(mapStateToProps)(StructuresGrantRequestView);
@@ -1,12 +1,12 @@
1
1
  import React from "react";
2
- import PropTypes from "prop-types";
3
- import { connect } from "react-redux";
4
2
  import { FormattedMessage, useIntl } from "react-intl";
5
3
  import { Label } from "semantic-ui-react";
4
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
6
5
 
7
- export const StructuresLabelResults = ({ structureCount }) => {
6
+ export const StructuresLabelResults = () => {
8
7
  const { formatNumber } = useIntl();
9
- const count = formatNumber(structureCount);
8
+ const { count: originalCount } = useSearchContext();
9
+ const count = formatNumber(originalCount);
10
10
  return (
11
11
  <Label className="structures-label-results">
12
12
  <FormattedMessage id="structures.retrieved.results" values={{ count }} />
@@ -14,10 +14,4 @@ export const StructuresLabelResults = ({ structureCount }) => {
14
14
  );
15
15
  };
16
16
 
17
- StructuresLabelResults.propTypes = {
18
- structureCount: PropTypes.number
19
- };
20
-
21
- const mapStateToProps = ({ structureCount }) => ({ structureCount });
22
-
23
- export default connect(mapStateToProps)(StructuresLabelResults);
17
+ export default StructuresLabelResults;
@@ -1,18 +1,16 @@
1
- import { connect } from "react-redux";
2
- import { bindActionCreators } from "redux";
1
+ import React from "react";
3
2
  import { Pagination } from "@truedat/core/components";
4
- import { selectStructurePage } from "../routines";
3
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
5
4
 
6
- const mapDispatchToProps = (dispatch) =>
7
- bindActionCreators({ selectPage: selectStructurePage }, dispatch);
5
+ export default function StructuresPagination() {
6
+ const { count, size, page, selectPage } = useSearchContext();
7
+ const totalPages = Math.ceil(count / size);
8
8
 
9
- const mapStateToProps = ({
10
- structureQuery,
11
- structureCount,
12
- structuresPageSize,
13
- }) => ({
14
- activePage: structureQuery?.page,
15
- totalPages: Math.ceil(structureCount / structuresPageSize),
16
- });
17
-
18
- export default connect(mapStateToProps, mapDispatchToProps)(Pagination);
9
+ return (
10
+ <Pagination
11
+ totalPages={totalPages}
12
+ activePage={page}
13
+ selectPage={selectPage}
14
+ />
15
+ );
16
+ }
@@ -1,6 +1,5 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
-
4
3
  import { useIntl } from "react-intl";
5
4
  import { Route, Switch, useRouteMatch } from "react-router-dom";
6
5
  import { Unauthorized } from "@truedat/core/components";
@@ -18,7 +17,6 @@ import {
18
17
  import AddStructureMember from "./AddStructureMember";
19
18
  import StructureCrumbs from "./StructureCrumbs";
20
19
  import StructureLoader from "./StructureLoader";
21
- import UserSearchFiltersLoader from "./UserSearchFiltersLoader";
22
20
  import StructureView from "./StructureView";
23
21
  import BucketView from "./BucketView";
24
22
  import StructuresBulkUpdate from "./StructuresBulkUpdate";
@@ -61,25 +59,11 @@ const AuthorizedRoutes = () => {
61
59
  <Route
62
60
  exact
63
61
  path={BUCKETS_VIEW}
64
- render={() => (
65
- <>
66
- <UserSearchFiltersLoader scope="data_structure" />
67
- <StructuresView customView />
68
- </>
69
- )}
62
+ render={() => <StructuresView customView />}
70
63
  />
71
64
  <Route exact path={[BUCKET_VIEW]} render={() => <BucketView />} />
72
65
 
73
- <Route
74
- exact
75
- path={STRUCTURES}
76
- render={() => (
77
- <>
78
- <UserSearchFiltersLoader scope="data_structure" />
79
- <StructuresView />
80
- </>
81
- )}
82
- />
66
+ <Route exact path={STRUCTURES} render={() => <StructuresView />} />
83
67
  </Switch>
84
68
  <Route path={STRUCTURE_EVENTS} component={StructureEventsLoader} />
85
69
  <Switch>
@@ -1,11 +1,10 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
3
  import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { getSortInfo, sortColumn } from "@truedat/core/services/sort";
4
+ import { useSelector } from "react-redux";
6
5
  import { Table } from "semantic-ui-react";
7
6
  import { FormattedMessage } from "react-intl";
8
- import { sortStructures } from "../routines";
7
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
9
8
  import { structureColumnsSelector } from "../selectors";
10
9
  import StructureRow from "./StructureRow";
11
10
 
@@ -18,130 +17,95 @@ const isPositive = (links, id) => {
18
17
  return link ? true : false;
19
18
  };
20
19
 
21
- export class StructuresTable extends React.Component {
22
- state = {
23
- sortedColumn: _.prop("column")(getSortInfo(this.props.structuresSort)),
24
- direction: _.prop("direction")(getSortInfo(this.props.structuresSort)),
25
- };
20
+ export const StructuresTable = ({
21
+ columns: overwriteColumns,
22
+ grantable,
23
+ onStructureSelected,
24
+ selectedStructure,
25
+ size,
26
+ links = [],
27
+ placeToTop = true,
28
+ }) => {
29
+ const {
30
+ searchData,
31
+ sortColumn,
32
+ sortDirection,
33
+ defaultFilters,
34
+ handleSortSelection,
35
+ } = useSearchContext();
26
36
 
27
- setDirection = (direction) => {
28
- this.setState({ direction: direction });
29
- };
37
+ const columns = useSelector((state) =>
38
+ structureColumnsSelector(state, defaultFilters, overwriteColumns)
39
+ );
30
40
 
31
- setColumn = (column) => {
32
- this.setState({ sortedColumn: column });
33
- };
41
+ const structures = searchData?.data;
34
42
 
35
- componentDidUpdate(prevProps) {
36
- if (prevProps.structuresSort != this.props.structuresSort) {
37
- const { column: sortedColumn, direction: direction } = getSortInfo(
38
- this.props.structuresSort
39
- );
40
- this.setState({ sortedColumn, direction });
41
- }
42
- }
43
-
44
- render() {
45
- const {
46
- columns,
47
- grantable,
48
- onStructureSelected,
49
- selectedStructure,
50
- size,
51
- sortStructures,
52
- structures,
53
- links = [],
54
- placeToTop = true,
55
- } = this.props;
56
- const { sortedColumn, direction } = this.state;
57
-
58
- if (_.isEmpty(columns)) {
59
- return null;
60
- } else {
61
- // selectedStructure will be placed at top unless it is present in structures
62
- const tableData =
63
- _.has("id")(selectedStructure) && placeToTop
64
- ? _.any(_.propEq("id", selectedStructure.id))(structures) &&
65
- placeToTop
66
- ? structures
67
- : [selectedStructure, ...structures]
68
- : structures;
69
- const headerRow = (
70
- <Table.Row>
71
- {columns.map((column, key) => (
72
- <Table.HeaderCell
73
- key={key}
74
- content={
75
- <FormattedMessage
76
- id={`structure.${column.header || column.name}`}
77
- />
78
- }
79
- sorted={
80
- _.path("sort.name")(column) === sortedColumn ? direction : null
81
- }
82
- className={_.path("sort.name")(column) ? "" : "disabled"}
83
- onClick={() =>
84
- sortColumn(
85
- column,
86
- sortStructures,
87
- this.setDirection,
88
- this.setColumn,
89
- direction,
90
- sortedColumn
91
- )
92
- }
93
- width={_.propOr(1, "width")(column)}
94
- />
95
- ))}
96
- {grantable && (
97
- <Table.HeaderCell textAlign="center">
98
- Request grant
99
- </Table.HeaderCell>
100
- )}
101
- </Table.Row>
102
- );
43
+ if (_.isEmpty(columns)) {
44
+ return null;
45
+ } else {
46
+ // selectedStructure will be placed at top unless it is present in structures
47
+ const tableData =
48
+ _.has("id")(selectedStructure) && placeToTop
49
+ ? _.any(_.propEq("id", selectedStructure.id))(structures) && placeToTop
50
+ ? structures
51
+ : [selectedStructure, ...structures]
52
+ : structures;
53
+ const headerRow = (
54
+ <Table.Row>
55
+ {columns.map((column, key) => (
56
+ <Table.HeaderCell
57
+ key={key}
58
+ content={
59
+ <FormattedMessage
60
+ id={`structure.${column.header || column.name}`}
61
+ />
62
+ }
63
+ sorted={
64
+ _.path("sort.name")(column) === sortColumn ? sortDirection : null
65
+ }
66
+ className={_.path("sort.name")(column) ? "" : "disabled"}
67
+ onClick={() => handleSortSelection(_.path("sort.name")(column))}
68
+ width={_.propOr(1, "width")(column)}
69
+ />
70
+ ))}
71
+ {grantable && (
72
+ <Table.HeaderCell textAlign="center">Request grant</Table.HeaderCell>
73
+ )}
74
+ </Table.Row>
75
+ );
103
76
 
104
- const renderBodyRow = (s, i) => (
105
- <StructureRow
106
- key={i}
107
- columns={columns}
108
- structure={s}
109
- active={selectedStructure && _.propEq("id", s.id)(selectedStructure)}
110
- positive={isPositive(links, s.id)}
111
- onClick={onStructureSelected}
112
- grantable={grantable}
113
- />
114
- );
115
- return (
116
- <Table
117
- selectable
118
- sortable
119
- size={size}
120
- headerRow={headerRow}
121
- renderBodyRow={renderBodyRow}
122
- tableData={tableData}
123
- />
124
- );
125
- }
77
+ const renderBodyRow = (s, i) => (
78
+ <StructureRow
79
+ key={i}
80
+ columns={columns}
81
+ structure={s}
82
+ active={selectedStructure && _.propEq("id", s.id)(selectedStructure)}
83
+ positive={isPositive(links, s.id)}
84
+ onClick={onStructureSelected}
85
+ grantable={grantable}
86
+ />
87
+ );
88
+ return (
89
+ <Table
90
+ selectable
91
+ sortable
92
+ size={size}
93
+ headerRow={headerRow}
94
+ renderBodyRow={renderBodyRow}
95
+ tableData={tableData}
96
+ />
97
+ );
126
98
  }
127
- }
99
+ };
128
100
 
129
101
  StructuresTable.propTypes = {
130
102
  grantable: PropTypes.bool,
131
- columns: PropTypes.array.isRequired,
103
+ columns: PropTypes.array,
132
104
  onStructureSelected: PropTypes.func,
133
105
  selectedStructure: PropTypes.object,
134
106
  size: PropTypes.string,
135
- sortStructures: PropTypes.func,
136
- structures: PropTypes.array,
137
- structuresSort: PropTypes.array,
138
107
  links: PropTypes.array,
139
108
  placeToTop: PropTypes.bool,
140
109
  };
141
110
 
142
- const mapStateToProps = (state, props) => ({
143
- columns: structureColumnsSelector(state, props),
144
- structuresSort: _.path("structureQuery.sort")(state),
145
- });
146
-
147
- export default connect(mapStateToProps, { sortStructures })(StructuresTable);
111
+ export default StructuresTable;
@@ -1,22 +1,86 @@
1
- import React from "react";
1
+ import _ from "lodash/fp";
2
+ import React, { useState, useEffect } from "react";
2
3
  import PropTypes from "prop-types";
3
- import { connect } from "react-redux";
4
+ import { connect, useDispatch } from "react-redux";
4
5
  import { Dropdown } from "semantic-ui-react";
5
- import { Link } from "react-router-dom";
6
+ import { useHistory } from "react-router-dom";
6
7
  import { useIntl } from "react-intl";
7
8
  import { useAuthorized } from "@truedat/core/hooks";
8
9
  import { STRUCTURES_BULK_UPDATE } from "@truedat/core/routes";
9
- import { bulkUpdateDisabledSelector } from "../selectors";
10
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
11
+ import { templateNamesSelector } from "../selectors";
12
+ import { structureSearchQuery } from "../routines";
10
13
 
11
- export const StructuresUpdateOption = ({ disabled }) => {
14
+ export const StructuresUpdateOption = ({
15
+ structureTypes,
16
+ structureTypesLoading,
17
+ templates,
18
+ }) => {
12
19
  const { formatMessage } = useIntl();
13
20
  const authorized = useAuthorized();
21
+ const history = useHistory();
22
+ const [disabled, setDisabled] = useState(true);
23
+ const setStructureQuery = useDispatch();
24
+ const {
25
+ searchData,
26
+ loading: structuresLoading,
27
+ allActiveFilters,
28
+ allFilters,
29
+ count: structureCount,
30
+ filterParams: searchParams,
31
+ } = useSearchContext();
32
+
33
+ const structures = _.propOr([], "data")(searchData);
34
+ const actions = _.propOr({}, "_actions")(searchData);
35
+
36
+ const types = _.prop("type.raw")(allActiveFilters);
37
+
38
+ useEffect(() => {
39
+ if (
40
+ structuresLoading ||
41
+ structureTypesLoading ||
42
+ _.isEmpty(structures) ||
43
+ _.isEmpty(templates) ||
44
+ _.size(types) != 1 ||
45
+ structureCount <= 0
46
+ ) {
47
+ setDisabled(true);
48
+ } else {
49
+ const structure = _.head(structures);
50
+ setDisabled(
51
+ _.flow(
52
+ _.map("name"),
53
+ _.negate(_.includes(_.prop("type")(structure)))
54
+ )(structureTypes)
55
+ );
56
+ }
57
+ }, [
58
+ structures,
59
+ templates,
60
+ types,
61
+ structuresLoading,
62
+ structureTypes,
63
+ structureTypesLoading,
64
+ structureCount,
65
+ ]);
66
+
67
+ const navigate = () => {
68
+ setStructureQuery(
69
+ structureSearchQuery({
70
+ structureCount,
71
+ searchParams,
72
+ allFilters,
73
+ actions,
74
+ })
75
+ );
76
+ history.push(STRUCTURES_BULK_UPDATE);
77
+ };
78
+
14
79
  return (
15
80
  authorized && (
16
81
  <Dropdown.Item
17
82
  icon="refresh"
18
- as={Link}
19
- to={STRUCTURES_BULK_UPDATE}
83
+ onClick={navigate}
20
84
  disabled={disabled}
21
85
  content={
22
86
  <>
@@ -36,11 +100,15 @@ export const StructuresUpdateOption = ({ disabled }) => {
36
100
  };
37
101
 
38
102
  StructuresUpdateOption.propTypes = {
39
- disabled: PropTypes.bool,
103
+ structureTypes: PropTypes.array,
104
+ structureTypesLoading: PropTypes.bool,
105
+ templates: PropTypes.array,
40
106
  };
41
107
 
42
108
  const mapStateToProps = (state) => ({
43
- disabled: bulkUpdateDisabledSelector(state),
109
+ structureTypes: state.structureTypes,
110
+ structureTypesLoading: state.structureTypesLoading,
111
+ templates: templateNamesSelector(state),
44
112
  });
45
113
 
46
114
  export default connect(mapStateToProps)(StructuresUpdateOption);