@truedat/dd 5.5.2 → 5.6.1

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 (40) hide show
  1. package/package.json +6 -6
  2. package/src/components/GrantRemoval.js +6 -3
  3. package/src/components/GrantRequestCancel.js +4 -2
  4. package/src/components/GrantRoutes.js +27 -0
  5. package/src/components/StructureGrantCart.js +19 -12
  6. package/src/components/StructureGrantDropdown.js +25 -35
  7. package/src/components/StructureGrantListButton.js +85 -0
  8. package/src/components/StructureGrantRequestButton.js +1 -21
  9. package/src/components/StructureGrantSummaryButton.js +87 -0
  10. package/src/components/StructureRow.js +10 -6
  11. package/src/components/StructureSummary.js +4 -2
  12. package/src/components/StructuresGrantRequest.js +0 -0
  13. package/src/components/StructuresGrantRequestView.js +68 -0
  14. package/src/components/StructuresLoader.js +4 -2
  15. package/src/components/StructuresSearch.js +1 -0
  16. package/src/components/StructuresSearchResults.js +3 -0
  17. package/src/components/StructuresTable.js +37 -24
  18. package/src/components/StructuresView.js +9 -10
  19. package/src/components/__tests__/StructureGrantDropdown.spec.js +66 -29
  20. package/src/components/__tests__/StructureGrantListButton.spec.js +77 -0
  21. package/src/components/__tests__/{StructureGrantButton.spec.js → StructureGrantSummaryButton.spec.js} +9 -9
  22. package/src/components/__tests__/StructureRow.spec.js +10 -10
  23. package/src/components/__tests__/StructuresGrantRequestView.spec.js +83 -0
  24. package/src/components/__tests__/StructuresLoader.spec.js +1 -1
  25. package/src/components/__tests__/__snapshots__/GrantRoutes.spec.js.snap +4 -0
  26. package/src/components/__tests__/__snapshots__/StructureGrantListButton.spec.js.snap +159 -0
  27. package/src/components/__tests__/__snapshots__/{StructureGrantButton.spec.js.snap → StructureGrantSummaryButton.spec.js.snap} +5 -5
  28. package/src/components/__tests__/__snapshots__/StructureRow.spec.js.snap +4 -1
  29. package/src/components/__tests__/__snapshots__/StructuresGrantRequestView.spec.js.snap +310 -0
  30. package/src/components/__tests__/__snapshots__/StructuresLoader.spec.js.snap +3 -1
  31. package/src/components/__tests__/__snapshots__/StructuresTable.spec.js.snap +21 -12
  32. package/src/messages/en.js +4 -0
  33. package/src/messages/es.js +5 -0
  34. package/src/reducers/structureActiveFilters.js +10 -9
  35. package/src/reducers/structureSelectedFilter.js +1 -1
  36. package/src/reducers/structures.js +5 -0
  37. package/src/sagas/createGrantRequestStatus.js +12 -3
  38. package/src/sagas/requestGrantRemoval.js +13 -3
  39. package/src/selectors/structureColumnsSelector.js +16 -6
  40. package/src/components/StructureGrantButton.js +0 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "5.5.2",
3
+ "version": "5.6.1",
4
4
  "description": "Truedat Web Data Dictionary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -34,7 +34,7 @@
34
34
  "@testing-library/jest-dom": "^5.16.5",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "5.5.1",
37
+ "@truedat/test": "5.6.1",
38
38
  "babel-jest": "^28.1.0",
39
39
  "babel-plugin-dynamic-import-node": "^2.3.3",
40
40
  "babel-plugin-lodash": "^3.3.4",
@@ -87,9 +87,9 @@
87
87
  },
88
88
  "dependencies": {
89
89
  "@apollo/client": "^3.7.1",
90
- "@truedat/auth": "5.5.1",
91
- "@truedat/core": "5.5.1",
92
- "@truedat/df": "5.5.1",
90
+ "@truedat/auth": "5.6.1",
91
+ "@truedat/core": "5.6.1",
92
+ "@truedat/df": "5.6.1",
93
93
  "lodash": "^4.17.21",
94
94
  "moment": "^2.29.4",
95
95
  "path-to-regexp": "^1.7.0",
@@ -114,5 +114,5 @@
114
114
  "react-dom": ">= 16.8.6 < 17",
115
115
  "semantic-ui-react": ">= 2.0.3 < 2.2"
116
116
  },
117
- "gitHead": "e74477016a8b5de04718b465791ac608cd924c43"
117
+ "gitHead": "a8e5efaf772f212a10192b36d853529890dfdea2"
118
118
  }
@@ -11,10 +11,11 @@ export const GrantRemoval = ({
11
11
  requestGrantRemoval,
12
12
  children,
13
13
  onConfirm,
14
+ previousStructureQuery,
14
15
  }) => {
15
16
  const { formatMessage } = useIntl();
16
17
 
17
- if (!grant) return;
18
+ if (!grant) return null;
18
19
 
19
20
  const action = grant.pending_removal ? "cancel_removal" : "request_removal";
20
21
 
@@ -31,8 +32,9 @@ export const GrantRemoval = ({
31
32
  const onConfirmPayload = {
32
33
  id: grant.id,
33
34
  action,
34
- data_structure_id: grant.data_structure.id,
35
- version: grant.data_structure_version.id,
35
+ data_structure_id: _.prop("data_structure.id")(grant),
36
+ version: _.prop("data_structure_version.id")(grant),
37
+ previousStructureQuery,
36
38
  };
37
39
  if (_.isFunction(onConfirm)) onConfirm(onConfirmPayload);
38
40
  else requestGrantRemoval(onConfirmPayload);
@@ -48,6 +50,7 @@ GrantRemoval.propTypes = {
48
50
  requestGrantRemoval: PropTypes.func,
49
51
  children: PropTypes.node,
50
52
  onConfirm: PropTypes.func,
53
+ previousStructureQuery: PropTypes.object,
51
54
  };
52
55
 
53
56
  export default connect(null, { requestGrantRemoval })(GrantRemoval);
@@ -10,9 +10,9 @@ export const GrantRequestCancel = ({
10
10
  grantRequest,
11
11
  createGrantRequestStatus,
12
12
  children,
13
+ previousStructureQuery,
13
14
  }) => {
14
15
  const { formatMessage } = useIntl();
15
-
16
16
  if (!grantRequest) return;
17
17
 
18
18
  return (
@@ -29,6 +29,7 @@ export const GrantRequestCancel = ({
29
29
  structureId,
30
30
  grantRequestId: grantRequest.id,
31
31
  status: "cancelled",
32
+ previousStructureQuery,
32
33
  })
33
34
  }
34
35
  onOpen={(e) => e.stopPropagation()}
@@ -38,10 +39,11 @@ export const GrantRequestCancel = ({
38
39
  };
39
40
 
40
41
  GrantRequestCancel.propTypes = {
41
- structureId: PropTypes.number,
42
+ structureId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
42
43
  grantRequest: PropTypes.object,
43
44
  createGrantRequestStatus: PropTypes.func,
44
45
  children: PropTypes.node,
46
+ previousStructureQuery: PropTypes.object,
45
47
  };
46
48
 
47
49
  export default connect(null, { createGrantRequestStatus })(GrantRequestCancel);
@@ -16,6 +16,7 @@ import {
16
16
  GRANT_APPROVAL_RULES,
17
17
  MY_GRANT_REQUESTS,
18
18
  MY_GRANTS,
19
+ STRUCTURES_GRANT_REQUEST,
19
20
  } from "@truedat/core/routes";
20
21
  import GrantView from "./Grant";
21
22
  import GrantApprovalRule from "./GrantApprovalRule";
@@ -31,6 +32,10 @@ import Grants from "./Grants";
31
32
  import GrantsLoader from "./GrantsLoader";
32
33
  import MyGrantRequests from "./MyGrantRequests";
33
34
  import StructureGrantCartCheckout from "./StructureGrantCartCheckout";
35
+ import StructuresGrantRequestView from "./StructuresGrantRequestView";
36
+ import StructuresLoader from "./StructuresLoader";
37
+ import StructureFiltersLoader from "./StructureFiltersLoader";
38
+ import UserSearchFiltersLoader from "./UserSearchFiltersLoader";
34
39
 
35
40
  const TemplatesLoader = React.lazy(() =>
36
41
  import("@truedat/df/templates/components/TemplatesLoader")
@@ -117,6 +122,28 @@ export const GrantRoutes = ({ grantRequestLoaded }) => {
117
122
  render={() => <GrantApprovalRules />}
118
123
  />
119
124
  </Switch>
125
+
126
+ <Route
127
+ path={STRUCTURES_GRANT_REQUEST}
128
+ render={() => {
129
+ const defaultFilters = {
130
+ exists: {
131
+ field: "classes._grantable",
132
+ },
133
+ };
134
+ return (
135
+ <>
136
+ <StructuresLoader
137
+ defaultFilters={defaultFilters}
138
+ withGrantRequests
139
+ />
140
+ <StructureFiltersLoader defaultFilters={defaultFilters} />
141
+ <UserSearchFiltersLoader scope="data_structure" />
142
+ <StructuresGrantRequestView />
143
+ </>
144
+ );
145
+ }}
146
+ />
120
147
  <Route
121
148
  path={GRANT_REQUESTS}
122
149
  render={() => (
@@ -4,7 +4,7 @@ import React, { useState, useEffect } from "react";
4
4
  import { Link, useLocation, useHistory } from "react-router-dom";
5
5
  import PropTypes from "prop-types";
6
6
  import { connect } from "react-redux";
7
- import { useIntl } from "react-intl";
7
+ import { FormattedMessage, useIntl } from "react-intl";
8
8
  import {
9
9
  Segment,
10
10
  List,
@@ -36,6 +36,7 @@ export const StructureGrantCart = ({
36
36
  removeGrantRequestFromCart,
37
37
  updateGrantRequestFilter,
38
38
  typeOperators,
39
+ allowEmptyCart,
39
40
  }) => {
40
41
  const { formatMessage } = useIntl();
41
42
  const history = useHistory();
@@ -44,8 +45,8 @@ export const StructureGrantCart = ({
44
45
  const structures = _.pathOr([], "structures")(grantRequestsCart);
45
46
 
46
47
  useEffect(() => {
47
- if (_.isEmpty(structures)) history.push(STRUCTURES);
48
- }, [history, structures]);
48
+ if (_.isEmpty(structures) && !allowEmptyCart) history.push(STRUCTURES);
49
+ }, [history, structures, allowEmptyCart]);
49
50
 
50
51
  const removeRequest = (structure) => () =>
51
52
  removeGrantRequestFromCart(structure);
@@ -122,14 +123,19 @@ export const StructureGrantCart = ({
122
123
  />
123
124
  ))}
124
125
  </List.List>
125
- {!inCartCheckout && (
126
- <>
127
- <Divider />
128
- <Button as={Link} to={linkTo.GRANTS_REQUESTS_CHECKOUT()}>
129
- {formatMessage({ id: `structure.grant.cart.checkout` })}
130
- </Button>
131
- </>
132
- )}
126
+ {!inCartCheckout &&
127
+ (_.isEmpty(grantRequestsCart?.structures) ? (
128
+ <p>
129
+ <FormattedMessage id={`structure.grant.cart.empty`} />
130
+ </p>
131
+ ) : (
132
+ <>
133
+ <Divider />
134
+ <Button as={Link} to={linkTo.GRANTS_REQUESTS_CHECKOUT()}>
135
+ {formatMessage({ id: `structure.grant.cart.checkout` })}
136
+ </Button>
137
+ </>
138
+ ))}
133
139
  </Segment>
134
140
  );
135
141
  };
@@ -137,9 +143,10 @@ export const StructureGrantCart = ({
137
143
  StructureGrantCart.propTypes = {
138
144
  structure: PropTypes.object,
139
145
  grantRequestsCart: PropTypes.object,
140
- typeOperators: PropTypes.array,
146
+ typeOperators: PropTypes.object,
141
147
  removeGrantRequestFromCart: PropTypes.func,
142
148
  updateGrantRequestFilter: PropTypes.func,
149
+ allowEmptyCart: PropTypes.bool,
143
150
  };
144
151
 
145
152
  export const StructureGrantCartLoader = (props) => {
@@ -2,7 +2,6 @@ import _ from "lodash/fp";
2
2
  import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { Button, Dropdown, Popup, Header } from "semantic-ui-react";
5
- import { connect } from "react-redux";
6
5
  import { useIntl } from "react-intl";
7
6
  import { useHistory } from "react-router-dom";
8
7
  import { linkTo } from "@truedat/core/routes";
@@ -16,21 +15,23 @@ import StructureGrantRequestAddCart from "./StructureGrantRequestAddCart";
16
15
  const isNilOrEmpty = (value) => _.isEmpty(value) || _.isNil(value);
17
16
  export const StructureGrantDropdown = ({
18
17
  grantRequest,
18
+ grantRequestStatus,
19
19
  structure,
20
+ grant,
20
21
  structureGrantPopup,
21
22
  authorized,
22
23
  requested,
24
+ previousStructureQuery,
23
25
  }) => {
24
26
  const history = useHistory();
25
27
  const { formatMessage } = useIntl();
26
- const { grant } = structure;
27
28
 
28
- const hasPendingGrantRequest = _.includes(
29
- _.prop("status.status")(grantRequest)
30
- )(["pending", "approved"]);
29
+ const hasPendingGrantRequest = _.includes(grantRequestStatus)([
30
+ "pending",
31
+ "approved",
32
+ ]);
31
33
 
32
- const hasProcessingGrantRequest =
33
- _.prop("status.status")(grantRequest) === "processing";
34
+ const hasProcessingGrantRequest = grantRequestStatus === "processing";
34
35
 
35
36
  const isModification = _.prop("group.grant")(grantRequest);
36
37
 
@@ -58,7 +59,11 @@ export const StructureGrantDropdown = ({
58
59
  />
59
60
  ),
60
61
  requestRemoval: (
61
- <GrantRemoval grant={grant} key="requestRemoval">
62
+ <GrantRemoval
63
+ grant={grant}
64
+ previousStructureQuery={previousStructureQuery}
65
+ key="requestRemoval"
66
+ >
62
67
  <Dropdown.Item
63
68
  icon="delete"
64
69
  text={formatMessage({
@@ -68,7 +73,11 @@ export const StructureGrantDropdown = ({
68
73
  </GrantRemoval>
69
74
  ),
70
75
  cancelRemoval: (
71
- <GrantRemoval grant={grant} key="cancelRemoval">
76
+ <GrantRemoval
77
+ grant={grant}
78
+ previousStructureQuery={previousStructureQuery}
79
+ key="cancelRemoval"
80
+ >
72
81
  <Dropdown.Item
73
82
  icon="delete"
74
83
  text={formatMessage({
@@ -96,6 +105,7 @@ export const StructureGrantDropdown = ({
96
105
  key="cancelRequest"
97
106
  structureId={structure.id}
98
107
  grantRequest={grantRequest}
108
+ previousStructureQuery={previousStructureQuery}
99
109
  >
100
110
  <Dropdown.Item
101
111
  icon="delete"
@@ -157,10 +167,8 @@ export const StructureGrantDropdown = ({
157
167
  })
158
168
  )(structureGrantPopup);
159
169
 
160
- const status = _.prop("status.status")(grantRequest);
161
-
162
- const grantRequestDetails = status ? (
163
- <>{formatMessage({ id: `grantRequest.content.${status}` })}</>
170
+ const grantRequestDetails = grantRequestStatus ? (
171
+ <>{formatMessage({ id: `grantRequest.content.${grantRequestStatus}` })}</>
164
172
  ) : null;
165
173
 
166
174
  const popupContent = (
@@ -198,31 +206,13 @@ export const StructureGrantDropdown = ({
198
206
 
199
207
  StructureGrantDropdown.propTypes = {
200
208
  grantRequest: PropTypes.object,
209
+ grantRequestStatus: PropTypes.string,
201
210
  structure: PropTypes.object,
211
+ grant: PropTypes.object,
202
212
  structureGrantPopup: PropTypes.array,
203
213
  authorized: PropTypes.bool,
204
214
  requested: PropTypes.bool,
215
+ previousStructureQuery: PropTypes.object,
205
216
  };
206
217
 
207
- const mapStateToProps = ({
208
- structure,
209
- structureFields,
210
- structureGrantPopup,
211
- userPermissions,
212
- grantRequestsCart,
213
- }) => ({
214
- structure: {
215
- ...structure,
216
- hasDataFields: _.negate(_.isEmpty)(structureFields),
217
- structureFields,
218
- },
219
- structureGrantPopup,
220
- requested: _.flow(
221
- _.pathOr([], "structures"),
222
- _.find({ id: structure.id }),
223
- _.negate(_.isUndefined)
224
- )(grantRequestsCart),
225
- authorized: _.pathOr(false, "create_foreign_grant_request")(userPermissions),
226
- });
227
-
228
- export default connect(mapStateToProps)(StructureGrantDropdown);
218
+ export default StructureGrantDropdown;
@@ -0,0 +1,85 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { connect } from "react-redux";
5
+ import StructureGrantRequestButton from "./StructureGrantRequestButton";
6
+ import StructureGrantDropdown from "./StructureGrantDropdown";
7
+
8
+ export const StructureGrantListButton = ({
9
+ structure,
10
+ structureGrantPopup,
11
+ authorized_dropdown,
12
+ authorized_request,
13
+ requested,
14
+ previousStructureQuery,
15
+ }) => {
16
+ const grant = _.flow(_.prop("my_grants"), _.first)(structure);
17
+ const grantRequest = _.prop("my_grant_request")(structure);
18
+
19
+ const grantRequestStatus = _.prop("status")(grantRequest);
20
+ const isActiveRequest = _.includes(grantRequestStatus)([
21
+ "pending",
22
+ "approved",
23
+ "processing",
24
+ ]);
25
+
26
+ return grant || isActiveRequest ? (
27
+ <StructureGrantDropdown
28
+ structure={structure}
29
+ grant={grant}
30
+ structureGrantPopup={structureGrantPopup}
31
+ authorized={authorized_dropdown}
32
+ requested={requested}
33
+ grantRequest={isActiveRequest ? grantRequest : null}
34
+ grantRequestStatus={grantRequestStatus}
35
+ previousStructureQuery={previousStructureQuery}
36
+ />
37
+ ) : (
38
+ <StructureGrantRequestButton
39
+ structure={structure}
40
+ requested={requested}
41
+ authorized={authorized_request}
42
+ />
43
+ );
44
+ };
45
+
46
+ StructureGrantListButton.propTypes = {
47
+ structure: PropTypes.object,
48
+ structureGrantPopup: PropTypes.array,
49
+ authorized_dropdown: PropTypes.bool,
50
+ authorized_request: PropTypes.bool,
51
+ requested: PropTypes.bool,
52
+ previousStructureQuery: PropTypes.object,
53
+ };
54
+
55
+ const mapStateToProps = (
56
+ { structureGrantPopup, grantRequestsCart, previousStructureQuery },
57
+ { structure }
58
+ ) => ({
59
+ structureGrantPopup,
60
+ requested: _.flow(
61
+ _.pathOr([], "structures"),
62
+ _.find({ id: structure.id + "" }),
63
+ _.negate(_.isUndefined)
64
+ )(grantRequestsCart),
65
+ authorized_dropdown: _.pathOr(
66
+ false,
67
+ "create_foreign_grant_request"
68
+ )(structure.user_permissions),
69
+ authorized_request: _.pathOr(
70
+ false,
71
+ "request_grant"
72
+ )(structure.user_permissions),
73
+ previousStructureQuery,
74
+ structure: {
75
+ ...structure,
76
+ id: structure.id + "",
77
+ hasDataFields: _.negate(_.isEmpty)(structure.data_fields),
78
+ structureFields: _.flow(
79
+ _.prop("data_fields"),
80
+ _.map((dataField) => ({ ...dataField, data_structure_id: dataField.id }))
81
+ )(structure),
82
+ },
83
+ });
84
+
85
+ export default connect(mapStateToProps)(StructureGrantListButton);
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import PropTypes from "prop-types";
4
3
  import { Button, Icon, Popup } from "semantic-ui-react";
@@ -48,26 +47,7 @@ StructureGrantRequestButton.propTypes = {
48
47
  removeGrantRequestFromCart: PropTypes.func,
49
48
  };
50
49
 
51
- const mapStateToProps = ({
52
- structure,
53
- structureFields,
54
- grantRequestsCart,
55
- userPermissions,
56
- }) => ({
57
- structure: {
58
- ...structure,
59
- hasDataFields: _.negate(_.isEmpty)(structureFields),
60
- structureFields: structureFields,
61
- },
62
- requested: _.flow(
63
- _.pathOr([], "structures"),
64
- _.find({ id: structure.id }),
65
- _.negate(_.isUndefined)
66
- )(grantRequestsCart),
67
- authorized: _.pathOr(false, "request_grant")(userPermissions),
68
- });
69
-
70
- export default connect(mapStateToProps, {
50
+ export default connect(null, {
71
51
  addGrantRequestToCart,
72
52
  removeGrantRequestFromCart,
73
53
  })(StructureGrantRequestButton);
@@ -0,0 +1,87 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { useQuery } from "@apollo/client";
5
+ import { connect } from "react-redux";
6
+ import { Loading } from "@truedat/core/components";
7
+ import { LATEST_GRANT_REQUEST_QUERY } from "../api/queries";
8
+ import StructureGrantRequestButton from "./StructureGrantRequestButton";
9
+ import StructureGrantDropdown from "./StructureGrantDropdown";
10
+
11
+ export const StructureGrantSummaryButton = ({
12
+ structure,
13
+ structureGrantPopup,
14
+ authorizedDropdown,
15
+ authorizedRequest,
16
+ requested,
17
+ }) => {
18
+ const { grant, id } = structure;
19
+
20
+ const { loading, error, data } = useQuery(LATEST_GRANT_REQUEST_QUERY, {
21
+ fetchPolicy: "cache-and-network",
22
+ variables: { id },
23
+ });
24
+ if (error) return null;
25
+ if (loading) return <Loading />;
26
+
27
+ const grantRequest = _.prop("latestGrantRequest")(data);
28
+ const grantRequestStatus = _.prop("status.status")(grantRequest);
29
+ const isActiveRequest = _.includes(grantRequestStatus)([
30
+ "pending",
31
+ "approved",
32
+ "processing",
33
+ ]);
34
+
35
+ return grant || isActiveRequest ? (
36
+ <StructureGrantDropdown
37
+ structure={structure}
38
+ grant={grant}
39
+ structureGrantPopup={structureGrantPopup}
40
+ authorized={authorizedDropdown}
41
+ requested={requested}
42
+ grantRequest={isActiveRequest ? grantRequest : null}
43
+ grantRequestStatus={grantRequestStatus}
44
+ />
45
+ ) : (
46
+ <StructureGrantRequestButton
47
+ structure={structure}
48
+ requested={requested}
49
+ authorized={authorizedRequest}
50
+ />
51
+ );
52
+ };
53
+
54
+ StructureGrantSummaryButton.propTypes = {
55
+ structure: PropTypes.object,
56
+ structureGrantPopup: PropTypes.array,
57
+ authorizedDropdown: PropTypes.bool,
58
+ authorizedRequest: PropTypes.bool,
59
+ requested: PropTypes.bool,
60
+ };
61
+
62
+ const mapStateToProps = ({
63
+ structure,
64
+ structureFields,
65
+ structureGrantPopup,
66
+ userPermissions,
67
+ grantRequestsCart,
68
+ }) => ({
69
+ structure: {
70
+ ...structure,
71
+ hasDataFields: _.negate(_.isEmpty)(structureFields),
72
+ structureFields,
73
+ },
74
+ structureGrantPopup,
75
+ requested: _.flow(
76
+ _.pathOr([], "structures"),
77
+ _.find({ id: structure.id }),
78
+ _.negate(_.isUndefined)
79
+ )(grantRequestsCart),
80
+ authorizedDropdown: _.pathOr(
81
+ false,
82
+ "create_foreign_grant_request"
83
+ )(userPermissions),
84
+ authorizedRequest: _.pathOr(false, "request_grant")(userPermissions),
85
+ });
86
+
87
+ export default connect(mapStateToProps)(StructureGrantSummaryButton);
@@ -3,6 +3,7 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { Table } from "semantic-ui-react";
5
5
  import { columnDecorator } from "@truedat/core/services";
6
+ import StructureGrantListButton from "./StructureGrantListButton";
6
7
 
7
8
  export const StructureRow = ({
8
9
  structure,
@@ -11,21 +12,23 @@ export const StructureRow = ({
11
12
  active,
12
13
  disabled,
13
14
  positive,
15
+ grantable,
14
16
  }) =>
15
17
  _.isEmpty(columns) || _.isEmpty(structure) ? null : (
16
- <Table.Row
17
- active={active}
18
- disabled={disabled}
19
- positive={positive}
20
- onClick={() => onClick && onClick(structure)}
21
- >
18
+ <Table.Row active={active} disabled={disabled} positive={positive}>
22
19
  {columns.map((column, i) => (
23
20
  <Table.Cell
24
21
  key={i}
25
22
  textAlign={column.textAlign}
26
23
  content={columnDecorator(column)(structure)}
24
+ onClick={() => onClick && onClick(structure)}
27
25
  />
28
26
  ))}
27
+ {grantable && (
28
+ <Table.Cell collapsing width="1" textAlign="center">
29
+ <StructureGrantListButton structure={structure} />
30
+ </Table.Cell>
31
+ )}
29
32
  </Table.Row>
30
33
  );
31
34
 
@@ -36,6 +39,7 @@ StructureRow.propTypes = {
36
39
  active: PropTypes.bool,
37
40
  disabled: PropTypes.bool,
38
41
  positive: PropTypes.bool,
42
+ grantable: PropTypes.bool,
39
43
  };
40
44
 
41
45
  export default StructureRow;
@@ -10,7 +10,7 @@ import { getStructureUpdatedAt } from "../selectors";
10
10
  import StructureProperties from "./StructureProperties";
11
11
  import StructureConfidentialButton from "./StructureConfidentialButton";
12
12
  import StructureDeleteButton from "./StructureDeleteButton";
13
- import StructureGrantButton from "./StructureGrantButton";
13
+ import StructureGrantSummaryButton from "./StructureGrantSummaryButton";
14
14
  import StructureProfileButton from "./StructureProfileButton";
15
15
  import StructuresProfileButton from "./StructuresProfileButton";
16
16
  import StructureTags from "./StructureTags";
@@ -85,7 +85,9 @@ export const StructureSummary = ({
85
85
  <Date {...dateProperties(deleted_at, updatedAt)} />
86
86
  )}
87
87
  <Divider hidden fitted />
88
- {structureClasses?._grantable ? <StructureGrantButton /> : null}
88
+ {structureClasses?._grantable ? (
89
+ <StructureGrantSummaryButton />
90
+ ) : null}
89
91
  <ShareLinkPopup
90
92
  url={shareUrl}
91
93
  title={shareTitle}
File without changes
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { connect } from "react-redux";
4
+ import { useHistory } from "react-router-dom";
5
+ import { Grid, Header, Icon, Segment, Divider } from "semantic-ui-react";
6
+ import { FormattedMessage } from "react-intl";
7
+ import { linkTo } from "@truedat/core/routes";
8
+ import { structureRowsSelector } from "../selectors";
9
+ import StructureSelectedFilters from "./StructureSelectedFilters";
10
+ import StructureDateFilter from "./StructureDateFilter";
11
+ import StructuresSearch from "./StructuresSearch";
12
+ import StructuresSearchResults from "./StructuresSearchResults";
13
+ import StructureGrantCart from "./StructureGrantCart";
14
+
15
+ export const StructuresGrantRequestView = ({ loading, structures }) => {
16
+ const history = useHistory();
17
+
18
+ return (
19
+ <Grid>
20
+ <Grid.Row>
21
+ <Grid.Column width={11}>
22
+ <Segment>
23
+ <Header as="h2">
24
+ <Icon circular name="block layout" />
25
+ <Header.Content>
26
+ <FormattedMessage id="structuresGrantRequest.header" />
27
+ <Header.Subheader>
28
+ <FormattedMessage id="structuresGrantRequest.subheader" />
29
+ </Header.Subheader>
30
+ </Header.Content>
31
+ </Header>
32
+ <Divider hidden />
33
+ <StructuresSearch />
34
+ <StructureSelectedFilters />
35
+ <StructureDateFilter />
36
+ <StructuresSearchResults
37
+ structures={structures}
38
+ loading={loading}
39
+ grantable
40
+ onSelect={({ id }) => history.push(linkTo.STRUCTURE({ id }))}
41
+ />
42
+ </Segment>
43
+ </Grid.Column>
44
+ <Grid.Column width={5}>
45
+ <StructureGrantCart allowEmptyCart />
46
+ </Grid.Column>
47
+ </Grid.Row>
48
+ </Grid>
49
+ );
50
+ };
51
+
52
+ StructuresGrantRequestView.propTypes = {
53
+ structures: PropTypes.array,
54
+ loading: PropTypes.bool,
55
+ };
56
+
57
+ const mapStateToProps = (state) => ({
58
+ structures: structureRowsSelector(state, null, [
59
+ "my_grants",
60
+ "my_grant_request",
61
+ "external_id",
62
+ "data_fields",
63
+ "user_permissions",
64
+ ]),
65
+ loading: state.structuresLoading,
66
+ });
67
+
68
+ export default connect(mapStateToProps)(StructuresGrantRequestView);