@truedat/dd 4.54.12 → 4.56.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 (44) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +6 -6
  3. package/src/api/mutations.js +28 -0
  4. package/src/api/queries.js +36 -0
  5. package/src/components/GrantApprovalRule.js +149 -0
  6. package/src/components/GrantApprovalRuleConditions.js +134 -0
  7. package/src/components/GrantApprovalRuleDeleteButton.js +44 -0
  8. package/src/components/GrantApprovalRuleEdit.js +38 -0
  9. package/src/components/GrantApprovalRuleForm.js +264 -0
  10. package/src/components/GrantApprovalRuleNew.js +15 -0
  11. package/src/components/GrantApprovalRules.js +113 -0
  12. package/src/components/GrantRequest.js +4 -3
  13. package/src/components/GrantRoutes.js +30 -0
  14. package/src/components/__tests__/GrantApprovalRule.spec.js +69 -0
  15. package/src/components/__tests__/GrantApprovalRuleConditions.spec.js +120 -0
  16. package/src/components/__tests__/GrantApprovalRuleDeleteButton.spec.js +56 -0
  17. package/src/components/__tests__/GrantApprovalRuleEdit.spec.js +76 -0
  18. package/src/components/__tests__/GrantApprovalRuleForm.spec.js +135 -0
  19. package/src/components/__tests__/GrantApprovalRuleNew.spec.js +40 -0
  20. package/src/components/__tests__/GrantApprovalRules.spec.js +107 -0
  21. package/src/components/__tests__/StructureGrantDropdown.spec.js +1 -1
  22. package/src/components/__tests__/__snapshots__/GrantApprovalRule.spec.js.snap +239 -0
  23. package/src/components/__tests__/__snapshots__/GrantApprovalRuleConditions.spec.js.snap +819 -0
  24. package/src/components/__tests__/__snapshots__/GrantApprovalRuleDeleteButton.spec.js.snap +11 -0
  25. package/src/components/__tests__/__snapshots__/GrantApprovalRuleEdit.spec.js.snap +487 -0
  26. package/src/components/__tests__/__snapshots__/GrantApprovalRuleForm.spec.js.snap +1036 -0
  27. package/src/components/__tests__/__snapshots__/GrantApprovalRuleNew.spec.js.snap +464 -0
  28. package/src/components/__tests__/__snapshots__/GrantApprovalRules.spec.js.snap +266 -0
  29. package/src/components/__tests__/__snapshots__/GrantRoutes.spec.js.snap +27 -5
  30. package/src/messages/en.js +40 -0
  31. package/src/messages/es.js +41 -0
  32. package/src/reducers/structureRedirect.js +23 -3
  33. package/src/routines.js +3 -0
  34. package/src/sagas/__tests__/createGrantApprovalRule.spec.js +96 -0
  35. package/src/sagas/__tests__/deleteGrantApprovalRule.spec.js +85 -0
  36. package/src/sagas/__tests__/updateGrantApprovalRule.spec.js +96 -0
  37. package/src/sagas/createGrantApprovalRule.js +26 -0
  38. package/src/sagas/deleteGrantApprovalRule.js +32 -0
  39. package/src/sagas/index.js +9 -0
  40. package/src/sagas/updateGrantApprovalRule.js +26 -0
  41. package/src/selectors/__tests__/getGrantsColumns.spec.js +4 -0
  42. package/src/components/GrantRequestCrumbs.js +0 -25
  43. package/src/components/__tests__/GrantRequestCrumbs.spec.js +0 -18
  44. package/src/components/__tests__/__snapshots__/GrantRequestCrumbs.spec.js.snap +0 -100
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.56.0] 2022-11-17
4
+
5
+ ### Added
6
+
7
+ - [TD-5258] Approve grants request rules
8
+
3
9
  ## [4.54.12] 2022-11-14
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "4.54.12",
3
+ "version": "4.56.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.4",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "4.54.12",
37
+ "@truedat/test": "4.56.0",
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",
@@ -88,9 +88,9 @@
88
88
  },
89
89
  "dependencies": {
90
90
  "@apollo/client": "^3.7.0",
91
- "@truedat/auth": "4.54.12",
92
- "@truedat/core": "4.54.12",
93
- "@truedat/df": "4.54.12",
91
+ "@truedat/auth": "4.56.1",
92
+ "@truedat/core": "4.56.1",
93
+ "@truedat/df": "4.56.1",
94
94
  "lodash": "^4.17.21",
95
95
  "path-to-regexp": "^1.7.0",
96
96
  "prop-types": "^15.8.1",
@@ -112,5 +112,5 @@
112
112
  "react-dom": ">= 16.8.6 < 17",
113
113
  "semantic-ui-react": ">= 0.88.2 < 2.1"
114
114
  },
115
- "gitHead": "98b0eb7a9b7818b4c3879809fde0916f9b5f4ec9"
115
+ "gitHead": "d2b3dcb36b7d81889ee5642699595439750c0801"
116
116
  }
@@ -75,3 +75,31 @@ export const DELETE_STRUCTURE_TAG = gql`
75
75
  }
76
76
  }
77
77
  `;
78
+
79
+ export const CREATE_GRANT_APPROVAL_RULE = gql`
80
+ mutation CreateGrantApprovalRule(
81
+ $approvalRule: CreateGrantApprovalRuleInput!
82
+ ) {
83
+ createGrantApprovalRule(approvalRule: $approvalRule) {
84
+ id
85
+ }
86
+ }
87
+ `;
88
+
89
+ export const UPDATE_GRANT_APPROVAL_RULE = gql`
90
+ mutation UpdateGrantApprovalRule(
91
+ $approvalRule: UpdateGrantApprovalRuleInput!
92
+ ) {
93
+ updateGrantApprovalRule(approvalRule: $approvalRule) {
94
+ id
95
+ }
96
+ }
97
+ `;
98
+
99
+ export const DELETE_GRANT_APPROVAL_RULE = gql`
100
+ mutation DeleteGrantApprovalRule($id: ID!) {
101
+ deleteGrantApprovalRule(id: $id) {
102
+ id
103
+ }
104
+ }
105
+ `;
@@ -120,6 +120,42 @@ export const STRUCTURE_NOTES_QUERY = gql`
120
120
  }
121
121
  `;
122
122
 
123
+ export const GRANT_APPROVAL_RULES_QUERY = gql`
124
+ query GrantApprovalRules {
125
+ grantApprovalRules {
126
+ id
127
+ name
128
+ action
129
+ role
130
+ domains {
131
+ name
132
+ }
133
+ }
134
+ }
135
+ `;
136
+
137
+ export const GRANT_APPROVAL_RULE_QUERY = gql`
138
+ query GrantApprovalRule($id: ID!) {
139
+ grantApprovalRule(id: $id) {
140
+ id
141
+ name
142
+ action
143
+ role
144
+ domainIds
145
+ userId
146
+ domains {
147
+ name
148
+ }
149
+ conditions {
150
+ field
151
+ operator
152
+ value
153
+ }
154
+ comment
155
+ }
156
+ }
157
+ `;
158
+
123
159
  export const STRUCTURE_STRUCTURE_LINKS_QUERY = gql`
124
160
  query DataStructureLinks($id: ID!) {
125
161
  dataStructure(id: $id) {
@@ -0,0 +1,149 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { useIntl } from "react-intl";
4
+ import { useParams } from "react-router-dom";
5
+ import { useQuery } from "@apollo/client";
6
+ import {
7
+ Button,
8
+ Header,
9
+ Grid,
10
+ Icon,
11
+ List,
12
+ Segment,
13
+ Table,
14
+ } from "semantic-ui-react";
15
+ import { Link } from "react-router-dom";
16
+ import { linkTo } from "@truedat/core/routes";
17
+ import GenericCrumbs from "@truedat/core/components/GenericCrumbs";
18
+ import { GRANT_APPROVAL_RULE_QUERY } from "../api/queries";
19
+ import GrantApprovalRuleDeleteButton from "./GrantApprovalRuleDeleteButton";
20
+
21
+ export const GrantApprovalRule = () => {
22
+ const { formatMessage } = useIntl();
23
+ const { id } = useParams();
24
+
25
+ const { loading, data } = useQuery(GRANT_APPROVAL_RULE_QUERY, {
26
+ variables: { id },
27
+ fetchPolicy: "cache-and-network",
28
+ });
29
+ const approvalRule = _.get("grantApprovalRule")(data);
30
+
31
+ const fields = [
32
+ { name: "name" },
33
+ { name: "domain", path: "domains[0].name" },
34
+ { name: "role" },
35
+ {
36
+ name: "action",
37
+ render: (action) =>
38
+ formatMessage({
39
+ id: `grantApprovalRule.action.${action}`,
40
+ }),
41
+ },
42
+ { name: "comment" },
43
+ ];
44
+
45
+ return approvalRule ? (
46
+ <>
47
+ <GenericCrumbs
48
+ header="grantApprovalRules.header"
49
+ title={approvalRule?.name}
50
+ />
51
+ <Segment loading={loading}>
52
+ <Grid>
53
+ <Grid.Column width={8}>
54
+ <Header as="h2">
55
+ <Icon circular name="key" />
56
+ <Header.Content>
57
+ {formatMessage({ id: "grantApprovalRule.subheader" })}
58
+ </Header.Content>
59
+ </Header>
60
+ </Grid.Column>
61
+ <Grid.Column width={8} textAlign="right">
62
+ <Button
63
+ primary
64
+ as={Link}
65
+ to={linkTo.GRANT_APPROVAL_RULE_EDIT({ id: approvalRule?.id })}
66
+ content={formatMessage({
67
+ id: "grantApprovalRules.edit",
68
+ })}
69
+ />
70
+ <GrantApprovalRuleDeleteButton approvalRule={approvalRule} />
71
+ </Grid.Column>
72
+ </Grid>
73
+ <List size="big" relaxed>
74
+ {fields.map(({ name, path, render = _.identity }, key) => (
75
+ <List.Item key={key}>
76
+ <List.Header>
77
+ {formatMessage({ id: `grantApprovalRule.${name}` })}
78
+ </List.Header>
79
+ <List.Content>
80
+ {render(_.prop(path || name)(approvalRule))}
81
+ </List.Content>
82
+ </List.Item>
83
+ ))}
84
+ <List.Item>
85
+ <List.Header>
86
+ {formatMessage({ id: "grantApprovalRule.conditions" })}
87
+ </List.Header>
88
+
89
+ <Table compact collapsing celled>
90
+ <Table.Header>
91
+ <Table.Row textAlign="center">
92
+ <Table.HeaderCell>
93
+ {formatMessage({
94
+ id: "grantApprovalRule.conditions.field_prefix",
95
+ })}
96
+ </Table.HeaderCell>
97
+ <Table.HeaderCell>
98
+ {formatMessage({
99
+ id: "grantApprovalRule.conditions.field_name",
100
+ })}
101
+ </Table.HeaderCell>
102
+ <Table.HeaderCell>
103
+ {formatMessage({
104
+ id: "grantApprovalRule.conditions.operator",
105
+ })}
106
+ </Table.HeaderCell>
107
+ <Table.HeaderCell>
108
+ {formatMessage({
109
+ id: "grantApprovalRule.conditions.value",
110
+ })}
111
+ </Table.HeaderCell>
112
+ </Table.Row>
113
+ </Table.Header>
114
+
115
+ <Table.Body>
116
+ {_.getOr(
117
+ [],
118
+ "conditions"
119
+ )(approvalRule).map(({ field, operator, value }, key) => {
120
+ const fields = field.match(/(\w+)\.(.*)/);
121
+ const fieldPrefix = fields ? fields[1] : null;
122
+ const fieldName = fields ? fields[2] : field;
123
+ return (
124
+ <Table.Row key={key} textAlign="center">
125
+ <Table.Cell>
126
+ {formatMessage({
127
+ id: `grantApprovalRule.conditions.field_prefix.${fieldPrefix}`,
128
+ })}
129
+ </Table.Cell>
130
+ <Table.Cell>{fieldName}</Table.Cell>
131
+ <Table.Cell>
132
+ {formatMessage({
133
+ id: `grantApprovalRule.conditions.operator.${operator}`,
134
+ })}
135
+ </Table.Cell>
136
+ <Table.Cell>{value}</Table.Cell>
137
+ </Table.Row>
138
+ );
139
+ })}
140
+ </Table.Body>
141
+ </Table>
142
+ </List.Item>
143
+ </List>
144
+ </Segment>
145
+ </>
146
+ ) : null;
147
+ };
148
+
149
+ export default GrantApprovalRule;
@@ -0,0 +1,134 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Button, Form, Icon, Grid } from "semantic-ui-react";
5
+ import { useIntl } from "react-intl";
6
+
7
+ export default function GrantApprovalRuleConditions({
8
+ onChange,
9
+ value,
10
+ disabled,
11
+ }) {
12
+ const { formatMessage } = useIntl();
13
+
14
+ const handleChange = (key, name, newValue) => {
15
+ const calculatedValue = _.update(`[${key}].${name}`, () => newValue)(value);
16
+ onChange(calculatedValue);
17
+ };
18
+
19
+ return (
20
+ <Grid verticalAlign="middle">
21
+ {value
22
+ ? value.map((condition, key) => (
23
+ <Grid.Row key={key} columns={2}>
24
+ <Grid.Column width={15}>
25
+ <Form.Group>
26
+ <Form.Dropdown
27
+ width={4}
28
+ disabled={disabled}
29
+ name="fieldPrefix"
30
+ label={formatMessage({
31
+ id: "grantApprovalRule.conditions.field_prefix",
32
+ })}
33
+ selection
34
+ options={["request", "note", "metadata"].map((o) => ({
35
+ key: o,
36
+ value: o,
37
+ text: formatMessage({
38
+ id: `grantApprovalRule.conditions.field_prefix.${o}`,
39
+ }),
40
+ }))}
41
+ onChange={(_e, { value, name }) =>
42
+ handleChange(key, name, value)
43
+ }
44
+ placeholder={formatMessage({
45
+ id: "grantApprovalRule.conditions.field_prefix.placeholder",
46
+ })}
47
+ value={condition.fieldPrefix}
48
+ />
49
+ <Form.Input
50
+ id={`fieldName-${key}`}
51
+ width={4}
52
+ disabled={disabled}
53
+ name="fieldName"
54
+ label={formatMessage({
55
+ id: "grantApprovalRule.conditions.field_name",
56
+ })}
57
+ value={condition.fieldName || ""}
58
+ onChange={(_e, { value, name }) =>
59
+ handleChange(key, name, value)
60
+ }
61
+ />
62
+ <Form.Dropdown
63
+ width={4}
64
+ disabled={disabled}
65
+ name="operator"
66
+ label={formatMessage({
67
+ id: "grantApprovalRule.conditions.operator",
68
+ })}
69
+ selection
70
+ options={["eq", "neq"].map((o) => ({
71
+ key: o,
72
+ value: o,
73
+ text: formatMessage({
74
+ id: `grantApprovalRule.conditions.operator.${o}`,
75
+ }),
76
+ }))}
77
+ onChange={(_e, { value, name }) =>
78
+ handleChange(key, name, value)
79
+ }
80
+ placeholder={formatMessage({
81
+ id: "grantApprovalRule.conditions.operator.placeholder",
82
+ })}
83
+ value={condition.operator}
84
+ />
85
+ <Form.Input
86
+ id={`value-${key}`}
87
+ width={4}
88
+ disabled={disabled}
89
+ name="value"
90
+ label={formatMessage({
91
+ id: "grantApprovalRule.conditions.value",
92
+ })}
93
+ value={condition.value || ""}
94
+ onChange={(_e, { value, name }) =>
95
+ handleChange(key, name, value)
96
+ }
97
+ />
98
+ </Form.Group>
99
+ </Grid.Column>
100
+ <Grid.Column width={1}>
101
+ {_.size(value) !== 1 ? (
102
+ <Icon
103
+ name="trash"
104
+ className="selectable"
105
+ onClick={() =>
106
+ onChange([
107
+ ..._.slice(0, key)(value),
108
+ ..._.slice(key + 1, _.size(value))(value),
109
+ ])
110
+ }
111
+ />
112
+ ) : null}
113
+ </Grid.Column>
114
+ </Grid.Row>
115
+ ))
116
+ : null}
117
+ <Grid.Row>
118
+ <Grid.Column>
119
+ <Button disabled={disabled} onClick={() => onChange([...value, {}])}>
120
+ {formatMessage({
121
+ id: "grantApprovalRule.conditions.addCondition",
122
+ })}
123
+ </Button>
124
+ </Grid.Column>
125
+ </Grid.Row>
126
+ </Grid>
127
+ );
128
+ }
129
+
130
+ GrantApprovalRuleConditions.propTypes = {
131
+ onChange: PropTypes.func,
132
+ value: PropTypes.array,
133
+ disabled: PropTypes.bool,
134
+ };
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { connect } from "react-redux";
4
+ import { useIntl } from "react-intl";
5
+ import { Button } from "semantic-ui-react";
6
+ import { ConfirmModal } from "@truedat/core/components";
7
+ import { deleteGrantApprovalRule } from "../routines";
8
+
9
+ export const GrantApprovalRuleDeleteButton = ({
10
+ approvalRule,
11
+ deleteGrantApprovalRule,
12
+ }) => {
13
+ const { formatMessage } = useIntl();
14
+
15
+ return (
16
+ <ConfirmModal
17
+ trigger={
18
+ <Button>
19
+ {formatMessage({
20
+ id: "grantApprovalRules.delete",
21
+ })}
22
+ </Button>
23
+ }
24
+ header={formatMessage({
25
+ id: "grantApprovalRule.actions.delete.confirmation.header",
26
+ })}
27
+ content={formatMessage({
28
+ id: "grantApprovalRule.actions.delete.confirmation.content",
29
+ })}
30
+ onConfirm={() => deleteGrantApprovalRule({ id: approvalRule.id })}
31
+ onOpen={(e) => e.stopPropagation()}
32
+ onClose={(e) => e.stopPropagation()}
33
+ />
34
+ );
35
+ };
36
+
37
+ GrantApprovalRuleDeleteButton.propTypes = {
38
+ approvalRule: PropTypes.object,
39
+ deleteGrantApprovalRule: PropTypes.func,
40
+ };
41
+
42
+ export default connect(null, { deleteGrantApprovalRule })(
43
+ GrantApprovalRuleDeleteButton
44
+ );
@@ -0,0 +1,38 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Loader } from "semantic-ui-react";
5
+ import { useQuery } from "@apollo/client";
6
+ import { useParams } from "react-router-dom";
7
+ import { connect } from "react-redux";
8
+ import { GRANT_APPROVAL_RULE_QUERY } from "../api/queries";
9
+ import { updateGrantApprovalRule } from "../routines";
10
+ import GrantApprovalRuleForm from "./GrantApprovalRuleForm";
11
+
12
+ export const GrantApprovalRuleEdit = ({ updateGrantApprovalRule }) => {
13
+ const { id } = useParams();
14
+
15
+ const { loading, data } = useQuery(GRANT_APPROVAL_RULE_QUERY, {
16
+ variables: { id },
17
+ fetchPolicy: "cache-and-network",
18
+ });
19
+
20
+ const approvalRule = _.get("grantApprovalRule")(data);
21
+
22
+ return !loading && approvalRule ? (
23
+ <GrantApprovalRuleForm
24
+ onSubmit={updateGrantApprovalRule}
25
+ approvalRule={approvalRule}
26
+ />
27
+ ) : (
28
+ <Loader />
29
+ );
30
+ };
31
+
32
+ GrantApprovalRuleEdit.propTypes = {
33
+ updateGrantApprovalRule: PropTypes.func,
34
+ };
35
+
36
+ export default connect(null, { updateGrantApprovalRule })(
37
+ GrantApprovalRuleEdit
38
+ );