@truedat/dd 5.19.0 → 5.20.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.
- package/package.json +5 -5
- package/src/api/queries.js +19 -1
- package/src/components/Grant.js +9 -27
- package/src/components/GrantRemoval.js +26 -34
- package/src/components/GrantRemovalDirectButton.js +89 -0
- package/src/components/GrantRemovalWorkflow.js +107 -0
- package/src/components/GrantRemovalWorkflowDropdown.js +144 -0
- package/src/components/GrantRequest.js +2 -1
- package/src/components/GrantRequestCancel.js +5 -2
- package/src/components/GrantRequestHeader.js +13 -7
- package/src/components/GrantRequestRow.js +8 -1
- package/src/components/GrantRequests.js +8 -3
- package/src/components/GrantRequestsTable.js +1 -1
- package/src/components/StructureGrantDropdown.js +7 -40
- package/src/components/StructureGrantSummaryButton.js +2 -2
- package/src/components/StructureGrants.js +21 -17
- package/src/components/__tests__/Grant.spec.js +11 -7
- package/src/components/__tests__/GrantRemoval.spec.js +19 -54
- package/src/components/__tests__/GrantRemovalDirectButton.spec.js +66 -0
- package/src/components/__tests__/GrantRemovalWorkflow.spec.js +157 -0
- package/src/components/__tests__/GrantRequest.spec.js +2 -0
- package/src/components/__tests__/GrantRequestHeader.spec.js +2 -5
- package/src/components/__tests__/StructureGrantDropdown.spec.js +1 -16
- package/src/components/__tests__/StructureGrantSummaryButton.spec.js +3 -2
- package/src/components/__tests__/StructureGrants.spec.js +5 -1
- package/src/components/__tests__/__snapshots__/Grant.spec.js.snap +5 -4
- package/src/components/__tests__/__snapshots__/GrantRequest.spec.js.snap +3 -3
- package/src/components/__tests__/__snapshots__/GrantRequestHeader.spec.js.snap +4 -4
- package/src/components/__tests__/__snapshots__/GrantRequestsSearchResults.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/StructureGrantDropdown.spec.js.snap +0 -52
- package/src/components/__tests__/__snapshots__/StructureGrantListButton.spec.js.snap +0 -14
- package/src/components/__tests__/__snapshots__/StructureGrantSummaryButton.spec.js.snap +0 -14
- package/src/components/__tests__/__snapshots__/StructureGrants.spec.js.snap +4 -5
- package/src/hooks/useGrantRequest.js +10 -1
- package/src/messages/en.js +23 -8
- package/src/messages/es.js +26 -9
- package/src/reducers/structure.js +1 -0
- package/src/sagas/__tests__/createGrantRequestStatus.spec.js +1 -1
- package/src/sagas/createGrantRequestStatus.js +24 -8
- package/src/selectors/getGrantRequestsColumns.js +32 -5
- package/src/selectors/getGrantRequestsSearchColumns.js +20 -14
- package/src/selectors/utils/decorators.js +68 -0
- package/src/components/__tests__/__snapshots__/GrantRemoval.spec.js.snap +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.20.1",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@apollo/client": "^3.7.1",
|
|
91
|
-
"@truedat/auth": "5.
|
|
92
|
-
"@truedat/core": "5.
|
|
93
|
-
"@truedat/df": "5.
|
|
91
|
+
"@truedat/auth": "5.20.1",
|
|
92
|
+
"@truedat/core": "5.20.1",
|
|
93
|
+
"@truedat/df": "5.20.1",
|
|
94
94
|
"lodash": "^4.17.21",
|
|
95
95
|
"moment": "^2.29.4",
|
|
96
96
|
"path-to-regexp": "^1.7.0",
|
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
"react-dom": ">= 16.8.6 < 17",
|
|
116
116
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
117
117
|
},
|
|
118
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "a7197e02a1b1a88c375fe044dee65c7e96ccd618"
|
|
119
119
|
}
|
package/src/api/queries.js
CHANGED
|
@@ -94,7 +94,7 @@ export const REFERENCE_DATASET_QUERY = gql`
|
|
|
94
94
|
}
|
|
95
95
|
`;
|
|
96
96
|
|
|
97
|
-
export const
|
|
97
|
+
export const LATEST_GRANT_REQUEST_BY_DS_QUERY = gql`
|
|
98
98
|
query latestGrantRequest($id: ID!) {
|
|
99
99
|
latestGrantRequest(data_structure_id: $id) {
|
|
100
100
|
id
|
|
@@ -103,6 +103,24 @@ export const LATEST_GRANT_REQUEST_QUERY = gql`
|
|
|
103
103
|
id
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
+
requestType
|
|
107
|
+
status {
|
|
108
|
+
status
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
|
|
114
|
+
export const LATEST_GRANT_REQUEST_BY_GRANT_QUERY = gql`
|
|
115
|
+
query latestGrantRequest($id: ID!, $requestType: RequestTypeEnum!) {
|
|
116
|
+
latestGrantRequest(grant_id: $id, requestType: $requestType) {
|
|
117
|
+
id
|
|
118
|
+
group {
|
|
119
|
+
grant {
|
|
120
|
+
id
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
requestType
|
|
106
124
|
status {
|
|
107
125
|
status
|
|
108
126
|
}
|
package/src/components/Grant.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import Moment from "react-moment";
|
|
4
5
|
import { useIntl } from "react-intl";
|
|
5
6
|
import { Link, useParams } from "react-router-dom";
|
|
6
|
-
|
|
7
|
-
import Moment from "react-moment";
|
|
8
7
|
import { Grid, Segment, Header, Icon, List, Button } from "semantic-ui-react";
|
|
9
|
-
|
|
10
8
|
import { linkTo } from "@truedat/core/routes";
|
|
11
9
|
import { useGrant, useGrantRemoval, useStructure } from "../hooks/useGrant";
|
|
12
10
|
import GrantCrumbs from "./GrantCrumbs";
|
|
13
11
|
import GrantRemoval from "./GrantRemoval";
|
|
14
12
|
import GrantChangeRequest from "./GrantChangeRequest";
|
|
13
|
+
|
|
15
14
|
const DynamicFieldValue = React.lazy(() =>
|
|
16
15
|
import("@truedat/df/components/DynamicFieldValue")
|
|
17
16
|
);
|
|
@@ -52,6 +51,8 @@ export const GrantHeader = ({ grant, title, actions, onStatusChange }) => {
|
|
|
52
51
|
})} ${title}`}
|
|
53
52
|
</Header.Content>
|
|
54
53
|
</Header>
|
|
54
|
+
</Grid.Column>
|
|
55
|
+
<Grid.Column width={4} textAlign="right">
|
|
55
56
|
{actions?.update && !loading ? (
|
|
56
57
|
<GrantChangeRequest
|
|
57
58
|
structure={data_structure}
|
|
@@ -66,30 +67,11 @@ export const GrantHeader = ({ grant, title, actions, onStatusChange }) => {
|
|
|
66
67
|
/>
|
|
67
68
|
</GrantChangeRequest>
|
|
68
69
|
) : null}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
className="button icon group-actions"
|
|
75
|
-
color="red"
|
|
76
|
-
content={formatMessage({
|
|
77
|
-
id: "grant.actions.request_removal.button",
|
|
78
|
-
})}
|
|
79
|
-
/>
|
|
80
|
-
</GrantRemoval>
|
|
81
|
-
) : null}
|
|
82
|
-
{actions?.cancel_removal ? (
|
|
83
|
-
<GrantRemoval grant={grant} onConfirm={onStatusChange}>
|
|
84
|
-
<Button
|
|
85
|
-
className="button icon group-actions"
|
|
86
|
-
color="olive"
|
|
87
|
-
content={formatMessage({
|
|
88
|
-
id: "grant.actions.cancel_removal.button",
|
|
89
|
-
})}
|
|
90
|
-
/>
|
|
91
|
-
</GrantRemoval>
|
|
92
|
-
) : null}
|
|
70
|
+
<GrantRemoval
|
|
71
|
+
actions={actions}
|
|
72
|
+
grant={grant}
|
|
73
|
+
onConfirm={onStatusChange}
|
|
74
|
+
/>
|
|
93
75
|
</Grid.Column>
|
|
94
76
|
</Grid.Row>
|
|
95
77
|
</Grid>
|
|
@@ -1,56 +1,48 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
|
-
import { ConfirmModal } from "@truedat/core/components";
|
|
6
|
-
import _ from "lodash";
|
|
7
4
|
import { requestGrantRemoval } from "../routines";
|
|
5
|
+
import GrantRemovalDirectButton from "./GrantRemovalDirectButton";
|
|
6
|
+
import GrantRemovalWorkflow from "./GrantRemovalWorkflow";
|
|
8
7
|
|
|
9
8
|
export const GrantRemoval = ({
|
|
10
9
|
grant,
|
|
10
|
+
actions,
|
|
11
11
|
requestGrantRemoval,
|
|
12
|
-
children,
|
|
13
12
|
onConfirm,
|
|
14
|
-
|
|
13
|
+
userPermissions,
|
|
15
14
|
}) => {
|
|
16
|
-
const { formatMessage } = useIntl();
|
|
17
|
-
|
|
18
15
|
if (!grant) return null;
|
|
19
16
|
|
|
20
|
-
const
|
|
17
|
+
const directButtonProps = ({ pending_removal }) => ({
|
|
18
|
+
actions,
|
|
19
|
+
grant,
|
|
20
|
+
requestGrantRemoval,
|
|
21
|
+
onConfirm,
|
|
22
|
+
operation: !pending_removal ? "markPendingRemoval" : "unmarkPendingRemoval",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// from StructureAccess
|
|
26
|
+
if (userPermissions?.update_grant_removal) {
|
|
27
|
+
return <GrantRemovalDirectButton {...directButtonProps(grant)} />;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// from Grant
|
|
31
|
+
if (actions?.manage_grant_removal) {
|
|
32
|
+
return <GrantRemovalDirectButton {...directButtonProps(grant)} />;
|
|
33
|
+
} else if (actions?.manage_grant_removal_request) {
|
|
34
|
+
return <GrantRemovalWorkflow grant={grant} actions={actions} />;
|
|
35
|
+
}
|
|
21
36
|
|
|
22
|
-
return
|
|
23
|
-
<ConfirmModal
|
|
24
|
-
trigger={children}
|
|
25
|
-
header={formatMessage({
|
|
26
|
-
id: `grant.actions.${action}.confirmation.header`,
|
|
27
|
-
})}
|
|
28
|
-
content={formatMessage({
|
|
29
|
-
id: `grant.actions.${action}.confirmation.content`,
|
|
30
|
-
})}
|
|
31
|
-
onConfirm={() => {
|
|
32
|
-
const onConfirmPayload = {
|
|
33
|
-
id: grant.id,
|
|
34
|
-
action,
|
|
35
|
-
data_structure_id: _.prop("data_structure.id")(grant),
|
|
36
|
-
version: _.prop("data_structure_version.id")(grant),
|
|
37
|
-
previousStructureQuery,
|
|
38
|
-
};
|
|
39
|
-
if (_.isFunction(onConfirm)) onConfirm(onConfirmPayload);
|
|
40
|
-
else requestGrantRemoval(onConfirmPayload);
|
|
41
|
-
}}
|
|
42
|
-
onOpen={(e) => e.stopPropagation()}
|
|
43
|
-
onClose={(e) => e.stopPropagation()}
|
|
44
|
-
/>
|
|
45
|
-
);
|
|
37
|
+
return null;
|
|
46
38
|
};
|
|
47
39
|
|
|
48
40
|
GrantRemoval.propTypes = {
|
|
49
41
|
grant: PropTypes.object,
|
|
42
|
+
actions: PropTypes.object,
|
|
50
43
|
requestGrantRemoval: PropTypes.func,
|
|
51
|
-
|
|
44
|
+
userPermissions: PropTypes.object,
|
|
52
45
|
onConfirm: PropTypes.func,
|
|
53
|
-
previousStructureQuery: PropTypes.object,
|
|
54
46
|
};
|
|
55
47
|
|
|
56
48
|
export default connect(null, { requestGrantRemoval })(GrantRemoval);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { ConfirmModal } from "@truedat/core/components";
|
|
6
|
+
import { Button } from "semantic-ui-react";
|
|
7
|
+
|
|
8
|
+
export const GrantRemovalDirectButton = ({
|
|
9
|
+
actions,
|
|
10
|
+
grant,
|
|
11
|
+
requestGrantRemoval,
|
|
12
|
+
onConfirm,
|
|
13
|
+
previousStructureQuery,
|
|
14
|
+
operation,
|
|
15
|
+
}) => {
|
|
16
|
+
const { formatMessage } = useIntl();
|
|
17
|
+
const [button, setButton] = useState(null);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const { color, translation } =
|
|
21
|
+
operation === "markPendingRemoval"
|
|
22
|
+
? {
|
|
23
|
+
color: "red",
|
|
24
|
+
translation: "grant.actions.markPendingRemoval.button",
|
|
25
|
+
}
|
|
26
|
+
: operation === "unmarkPendingRemoval"
|
|
27
|
+
? {
|
|
28
|
+
color: "olive",
|
|
29
|
+
translation: "grant.actions.unmarkPendingRemoval.button",
|
|
30
|
+
}
|
|
31
|
+
: { color: null, translation: null };
|
|
32
|
+
|
|
33
|
+
setButton(
|
|
34
|
+
<Button
|
|
35
|
+
className="button icon group-actions"
|
|
36
|
+
color={color}
|
|
37
|
+
content={formatMessage({
|
|
38
|
+
id: translation,
|
|
39
|
+
})}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}, [operation, formatMessage]);
|
|
43
|
+
|
|
44
|
+
if (!grant) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const action = grant.pending_removal
|
|
49
|
+
? "unmarkPendingRemoval"
|
|
50
|
+
: "markPendingRemoval";
|
|
51
|
+
|
|
52
|
+
const removeGrant = _.isFunction(onConfirm) ? onConfirm : requestGrantRemoval;
|
|
53
|
+
const payload = {
|
|
54
|
+
id: grant.id,
|
|
55
|
+
action: _.snakeCase(action),
|
|
56
|
+
data_structure_id: _.prop("data_structure.id")(grant),
|
|
57
|
+
version: _.prop("data_structure_version.id")(grant),
|
|
58
|
+
previousStructureQuery,
|
|
59
|
+
version: grant?.data_structure_version?.id,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<ConfirmModal
|
|
64
|
+
trigger={button}
|
|
65
|
+
header={formatMessage({
|
|
66
|
+
id: `grant.actions.${action}.confirmation.header`,
|
|
67
|
+
})}
|
|
68
|
+
content={formatMessage({
|
|
69
|
+
id: `grant.actions.${action}.confirmation.content`,
|
|
70
|
+
})}
|
|
71
|
+
onConfirm={() => {
|
|
72
|
+
removeGrant(payload)
|
|
73
|
+
}}
|
|
74
|
+
onOpen={(e) => e.stopPropagation()}
|
|
75
|
+
onClose={(e) => e.stopPropagation()}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
GrantRemovalDirectButton.propTypes = {
|
|
81
|
+
actions: PropTypes.object,
|
|
82
|
+
grant: PropTypes.object,
|
|
83
|
+
requestGrantRemoval: PropTypes.func,
|
|
84
|
+
onConfirm: PropTypes.func,
|
|
85
|
+
previousStructureQuery: PropTypes.object,
|
|
86
|
+
operation: PropTypes.string,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export default GrantRemovalDirectButton;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useQuery } from "@apollo/client";
|
|
5
|
+
import { Button, Loader, Popup } from "semantic-ui-react";
|
|
6
|
+
import { useHistory } from "react-router-dom";
|
|
7
|
+
import { useIntl } from "react-intl";
|
|
8
|
+
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
import { LATEST_GRANT_REQUEST_BY_GRANT_QUERY } from "@truedat/dd/api/queries";
|
|
10
|
+
import { useGrantRequestGroup } from "../hooks/useGrantRequest";
|
|
11
|
+
import GrantRemovalWorkflowDropdown from "./GrantRemovalWorkflowDropdown";
|
|
12
|
+
|
|
13
|
+
export const GrantRemovalWorkflow = ({
|
|
14
|
+
latestGrantRequest: latestGrantRequestProp,
|
|
15
|
+
grant,
|
|
16
|
+
}) => {
|
|
17
|
+
const history = useHistory();
|
|
18
|
+
const { formatMessage } = useIntl();
|
|
19
|
+
const [latestGrantRequest, setLatestGrantRequest] = useState(
|
|
20
|
+
latestGrantRequestProp
|
|
21
|
+
);
|
|
22
|
+
const grantRequestStatus = _.prop("status.status")(latestGrantRequest);
|
|
23
|
+
const { trigger: createGrantRequestGroupTrigger } = useGrantRequestGroup();
|
|
24
|
+
|
|
25
|
+
const createGrantRequestGroupAndRedirect = (payload) => async (e) => {
|
|
26
|
+
const {
|
|
27
|
+
data: {
|
|
28
|
+
data: {
|
|
29
|
+
_embedded: {
|
|
30
|
+
requests: [{ id: grantDeletionRequestId }],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
} = await createGrantRequestGroupTrigger(payload);
|
|
35
|
+
history.push(linkTo.GRANT_REQUEST({ id: grantDeletionRequestId }));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const payload = {
|
|
39
|
+
grant_request_group: {
|
|
40
|
+
requests: [
|
|
41
|
+
{
|
|
42
|
+
grant_id: grant?.id,
|
|
43
|
+
filters: {},
|
|
44
|
+
request_type: "grant_removal",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const requestButton = (
|
|
51
|
+
<Button
|
|
52
|
+
className="button basic icon group-actions"
|
|
53
|
+
icon="shield"
|
|
54
|
+
color="orange"
|
|
55
|
+
onClick={createGrantRequestGroupAndRedirect(payload)}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return (!grantRequestStatus || grantRequestStatus === "cancelled") &&
|
|
60
|
+
!grant.pending_removal ? (
|
|
61
|
+
<Popup
|
|
62
|
+
content={formatMessage({
|
|
63
|
+
id: "request.grantRemoval.action.start.description",
|
|
64
|
+
})}
|
|
65
|
+
trigger={requestButton}
|
|
66
|
+
/>
|
|
67
|
+
) : (
|
|
68
|
+
<GrantRemovalWorkflowDropdown
|
|
69
|
+
latestGrantRequest={latestGrantRequest}
|
|
70
|
+
setLatestGrantRequest={setLatestGrantRequest}
|
|
71
|
+
grant={grant}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
GrantRemovalWorkflow.propTypes = {
|
|
77
|
+
latestGrantRequest: PropTypes.object,
|
|
78
|
+
grant: PropTypes.object,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const GrantRemovalWorkflowLoader = (props) => {
|
|
82
|
+
const { loading, error, data } = useQuery(
|
|
83
|
+
LATEST_GRANT_REQUEST_BY_GRANT_QUERY,
|
|
84
|
+
{
|
|
85
|
+
fetchPolicy: "cache-and-network",
|
|
86
|
+
skip: props?.actions?.hasOwnProperty("manage_grant_removal"),
|
|
87
|
+
variables: { id: props.grant.id, requestType: "GRANT_REMOVAL" },
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
if (error) return null;
|
|
91
|
+
if (loading) return <Loader />;
|
|
92
|
+
const latestGrantRequest = data?.latestGrantRequest;
|
|
93
|
+
return (
|
|
94
|
+
<GrantRemovalWorkflow
|
|
95
|
+
loading={loading}
|
|
96
|
+
latestGrantRequest={latestGrantRequest}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
GrantRemovalWorkflowLoader.propTypes = {
|
|
103
|
+
actions: PropTypes.object,
|
|
104
|
+
grant: PropTypes.object,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export default GrantRemovalWorkflowLoader;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Button, Dropdown, Popup, Header } from "semantic-ui-react";
|
|
5
|
+
import { useHistory } from "react-router-dom";
|
|
6
|
+
import { useIntl } from "react-intl";
|
|
7
|
+
import { linkTo } from "@truedat/core/routes";
|
|
8
|
+
|
|
9
|
+
import GrantRequestCancel from "./GrantRequestCancel";
|
|
10
|
+
|
|
11
|
+
export const GrantRemovalWorkflowDropdown = ({
|
|
12
|
+
latestGrantRequest,
|
|
13
|
+
setLatestGrantRequest,
|
|
14
|
+
grant,
|
|
15
|
+
}) => {
|
|
16
|
+
const history = useHistory();
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
|
|
19
|
+
const grantRequestStatus = _.prop("status.status")(latestGrantRequest);
|
|
20
|
+
|
|
21
|
+
const actions = {
|
|
22
|
+
viewRequest: latestGrantRequest ? (
|
|
23
|
+
<Dropdown.Item
|
|
24
|
+
key="viewRequest"
|
|
25
|
+
onClick={() =>
|
|
26
|
+
history.push(linkTo.GRANT_REQUEST({ id: latestGrantRequest.id }))
|
|
27
|
+
}
|
|
28
|
+
icon="info"
|
|
29
|
+
text={formatMessage({
|
|
30
|
+
id: `grant.actions.viewRequest.confirmation.header`,
|
|
31
|
+
})}
|
|
32
|
+
/>
|
|
33
|
+
) : null,
|
|
34
|
+
cancelRequest: (
|
|
35
|
+
<GrantRequestCancel
|
|
36
|
+
key="cancelRequest"
|
|
37
|
+
grantRequest={latestGrantRequest}
|
|
38
|
+
setLatestGrantRequest={setLatestGrantRequest}
|
|
39
|
+
>
|
|
40
|
+
<Dropdown.Item
|
|
41
|
+
icon="delete"
|
|
42
|
+
text={formatMessage({
|
|
43
|
+
id: "structure.grant.cancel_grant_request",
|
|
44
|
+
})}
|
|
45
|
+
/>
|
|
46
|
+
</GrantRequestCancel>
|
|
47
|
+
),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const dropdownStates = {
|
|
51
|
+
pending: {
|
|
52
|
+
color: "yellow",
|
|
53
|
+
options: [actions["viewRequest"], actions["cancelRequest"]],
|
|
54
|
+
header: "request.grantRemoval.state.pending.description",
|
|
55
|
+
},
|
|
56
|
+
rejected: {
|
|
57
|
+
color: "red",
|
|
58
|
+
options: [actions["viewRequest"]],
|
|
59
|
+
header: "request.grantRemoval.state.rejected.description",
|
|
60
|
+
},
|
|
61
|
+
processing: {
|
|
62
|
+
color: "grey",
|
|
63
|
+
options: [actions["viewRequest"]],
|
|
64
|
+
header: "request.grantRemoval.state.processing.description",
|
|
65
|
+
},
|
|
66
|
+
approved: {
|
|
67
|
+
color: "brown",
|
|
68
|
+
options: [actions["viewRequest"]],
|
|
69
|
+
header:
|
|
70
|
+
"request.grantRemoval.state.approvedAndGrantPendingRemoval.description",
|
|
71
|
+
},
|
|
72
|
+
workflowBypassedActive: {
|
|
73
|
+
color: "grey",
|
|
74
|
+
options: [actions["viewRequest"]],
|
|
75
|
+
header: "request.grantRemoval.state.workflowBypassedActive.description",
|
|
76
|
+
},
|
|
77
|
+
workflowBypassedPendingRemoval: {
|
|
78
|
+
color: "grey",
|
|
79
|
+
options: [actions["viewRequest"]],
|
|
80
|
+
header:
|
|
81
|
+
"request.grantRemoval.state.workflowBypassedPendingRemoval.description",
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const currentState = (() => {
|
|
86
|
+
if (!grant.pending_removal) {
|
|
87
|
+
if (["pending", "rejected", "processing"].includes(grantRequestStatus))
|
|
88
|
+
return grantRequestStatus;
|
|
89
|
+
else return "workflowBypassedActive";
|
|
90
|
+
} else {
|
|
91
|
+
if (grantRequestStatus === "approved") return "approved";
|
|
92
|
+
else return "workflowBypassedPendingRemoval";
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
95
|
+
|
|
96
|
+
const stateProps = dropdownStates[currentState];
|
|
97
|
+
const grantRequestDetails = grantRequestStatus ? (
|
|
98
|
+
<>{formatMessage({ id: `grantRequest.content.${grantRequestStatus}` })}</>
|
|
99
|
+
) : null;
|
|
100
|
+
const popupContent = (
|
|
101
|
+
<>
|
|
102
|
+
{stateProps?.header ? (
|
|
103
|
+
<Header as="h6">{formatMessage({ id: stateProps.header })}</Header>
|
|
104
|
+
) : null}
|
|
105
|
+
{!["workflowBypassedActive", "workflowBypassedPendingRemoval"].includes(
|
|
106
|
+
currentState
|
|
107
|
+
) && latestGrantRequest
|
|
108
|
+
? grantRequestDetails
|
|
109
|
+
: null}
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const dropdown = (
|
|
114
|
+
<Dropdown
|
|
115
|
+
icon={null}
|
|
116
|
+
floating
|
|
117
|
+
direction="left"
|
|
118
|
+
trigger={
|
|
119
|
+
<Button
|
|
120
|
+
color={stateProps?.color}
|
|
121
|
+
className="button basic icon group-actions"
|
|
122
|
+
icon="shield"
|
|
123
|
+
/>
|
|
124
|
+
}
|
|
125
|
+
>
|
|
126
|
+
<Dropdown.Menu>
|
|
127
|
+
<>{stateProps?.options}</>
|
|
128
|
+
</Dropdown.Menu>
|
|
129
|
+
</Dropdown>
|
|
130
|
+
);
|
|
131
|
+
return currentState ? (
|
|
132
|
+
<Popup content={popupContent} trigger={dropdown} />
|
|
133
|
+
) : (
|
|
134
|
+
<p>Error: undefined currentState</p>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
GrantRemovalWorkflowDropdown.propTypes = {
|
|
139
|
+
latestGrantRequest: PropTypes.object,
|
|
140
|
+
setLatestGrantRequest: PropTypes.func,
|
|
141
|
+
grant: PropTypes.object,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export default GrantRemovalWorkflowDropdown;
|
|
@@ -4,7 +4,7 @@ import PropTypes from "prop-types";
|
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
5
|
import { Link } from "react-router-dom";
|
|
6
6
|
import { linkTo } from "@truedat/core/routes";
|
|
7
|
-
import { useIntl } from "react-intl";
|
|
7
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
8
8
|
import { Grid, Segment, List, Label } from "semantic-ui-react";
|
|
9
9
|
import GenericCrumbs from "@truedat/core/components/GenericCrumbs";
|
|
10
10
|
import { getGrantRequestTemplate } from "../selectors";
|
|
@@ -19,6 +19,7 @@ const ConditionSummary = React.lazy(() =>
|
|
|
19
19
|
import("@truedat/dq/components/ConditionSummary")
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
export const GrantRequest = ({ grantRequest, template }) => {
|
|
23
24
|
const { formatMessage } = useIntl();
|
|
24
25
|
const metadata = grantRequest?.metadata;
|
|
@@ -8,6 +8,7 @@ import { createGrantRequestStatus } from "../routines";
|
|
|
8
8
|
export const GrantRequestCancel = ({
|
|
9
9
|
structureId,
|
|
10
10
|
grantRequest,
|
|
11
|
+
setLatestGrantRequest,
|
|
11
12
|
createGrantRequestStatus,
|
|
12
13
|
children,
|
|
13
14
|
previousStructureQuery,
|
|
@@ -27,7 +28,8 @@ export const GrantRequestCancel = ({
|
|
|
27
28
|
onConfirm={() =>
|
|
28
29
|
createGrantRequestStatus({
|
|
29
30
|
structureId,
|
|
30
|
-
|
|
31
|
+
grantRequest,
|
|
32
|
+
setLatestGrantRequest,
|
|
31
33
|
status: "cancelled",
|
|
32
34
|
previousStructureQuery,
|
|
33
35
|
})
|
|
@@ -44,6 +46,7 @@ GrantRequestCancel.propTypes = {
|
|
|
44
46
|
createGrantRequestStatus: PropTypes.func,
|
|
45
47
|
children: PropTypes.node,
|
|
46
48
|
previousStructureQuery: PropTypes.object,
|
|
49
|
+
setLatestGrantRequest: PropTypes.func,
|
|
47
50
|
};
|
|
48
51
|
|
|
49
|
-
export default connect(null, { createGrantRequestStatus })(GrantRequestCancel);
|
|
52
|
+
export default connect(null, { createGrantRequestStatus })(GrantRequestCancel);
|
|
@@ -6,12 +6,20 @@ import { useIntl } from "react-intl";
|
|
|
6
6
|
import { Header, Grid, Icon } from "semantic-ui-react";
|
|
7
7
|
import GrantRequestApprovalPopup from "./GrantRequestApprovalPopup";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
grantRequest
|
|
12
|
-
|
|
9
|
+
const selectGrantTypeOptions = (grantRequest) => {
|
|
10
|
+
const [color, translationId] =
|
|
11
|
+
grantRequest?.request_type === "grant_removal"
|
|
12
|
+
? ["red", "request.grantRemoval"]
|
|
13
|
+
: grantRequest?._embedded?.group?._embedded.modification_grant
|
|
14
|
+
? ["yellow", "grantRequest.header.modification"]
|
|
15
|
+
: [undefined, "request.grantAccess"];
|
|
16
|
+
return { color, translationId };
|
|
17
|
+
};
|
|
13
18
|
|
|
19
|
+
export const GrantRequestHeader = ({ grantRequest }) => {
|
|
14
20
|
const { formatMessage } = useIntl();
|
|
21
|
+
const { translationId: grantTypeTranslationId } =
|
|
22
|
+
selectGrantTypeOptions(grantRequest);
|
|
15
23
|
const canApprove =
|
|
16
24
|
grantRequest?.status === "pending" &&
|
|
17
25
|
!_.isEmpty(grantRequest?.pending_roles);
|
|
@@ -22,9 +30,7 @@ export const GrantRequestHeader = ({ grantRequest }) => {
|
|
|
22
30
|
<Icon circular name="key" />
|
|
23
31
|
<Header.Content>
|
|
24
32
|
{formatMessage({
|
|
25
|
-
id:
|
|
26
|
-
? "grantRequest.header.modification"
|
|
27
|
-
: "grantRequest.header",
|
|
33
|
+
id: grantTypeTranslationId,
|
|
28
34
|
})}
|
|
29
35
|
</Header.Content>
|
|
30
36
|
</Header>
|
|
@@ -40,7 +40,14 @@ export const GrantRequestRow = ({
|
|
|
40
40
|
<Table.Cell
|
|
41
41
|
key={key}
|
|
42
42
|
textAlign={column.textAlign}
|
|
43
|
-
onClick={() =>
|
|
43
|
+
onClick={(ev) => {
|
|
44
|
+
/* Only do history.push if the table cell but not
|
|
45
|
+
* some possibly contained anchor (or an element
|
|
46
|
+
* inside an anchor, such as an icon) is clicked
|
|
47
|
+
*/
|
|
48
|
+
!ev.target.closest("a") &&
|
|
49
|
+
history.push(linkTo.GRANT_REQUEST(grantRequest))
|
|
50
|
+
}}
|
|
44
51
|
content={columnDecoratorComponent(column)(grantRequest)}
|
|
45
52
|
/>
|
|
46
53
|
))}
|
|
@@ -51,9 +51,14 @@ export const GrantRequests = ({
|
|
|
51
51
|
<Table.Cell
|
|
52
52
|
key={key}
|
|
53
53
|
textAlign={column.textAlign}
|
|
54
|
-
onClick={() =>
|
|
55
|
-
history.push
|
|
56
|
-
|
|
54
|
+
onClick={(ev) => {
|
|
55
|
+
/* Only do history.push if the table cell but not
|
|
56
|
+
* some possibly contained anchor (or an element
|
|
57
|
+
* inside an anchor, such as an icon) is clicked
|
|
58
|
+
*/
|
|
59
|
+
!ev.target.closest("a") &&
|
|
60
|
+
history.push(linkTo.GRANT_REQUEST(grantRequest));
|
|
61
|
+
}}
|
|
57
62
|
content={columnDecoratorComponent(column)(grantRequest)}
|
|
58
63
|
/>
|
|
59
64
|
))}
|