@truedat/dd 4.35.7 → 4.36.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.36.0] 2022-01-13
4
+
5
+ ### Fixed
6
+
7
+ - [TD-4308] Grant request actions should be hidden unless request is pending
8
+
9
+ ## [4.35.8] 2022-01-07
10
+
11
+ ### Added
12
+
13
+ - [TD-4390] Support for alias on Implementation
14
+
3
15
  ## [4.35.7] 2021-01-07
4
16
 
5
17
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "4.35.7",
3
+ "version": "4.36.2",
4
4
  "description": "Truedat Web Data Dictionary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -84,9 +84,9 @@
84
84
  ]
85
85
  },
86
86
  "dependencies": {
87
- "@truedat/auth": "4.35.7",
88
- "@truedat/core": "4.35.7",
89
- "@truedat/df": "4.35.7",
87
+ "@truedat/auth": "4.36.2",
88
+ "@truedat/core": "4.36.2",
89
+ "@truedat/df": "4.36.2",
90
90
  "lodash": "^4.17.21",
91
91
  "path-to-regexp": "^1.7.0",
92
92
  "prop-types": "^15.7.2",
@@ -107,5 +107,5 @@
107
107
  "react-dom": ">= 16.8.6 < 17",
108
108
  "semantic-ui-react": ">= 0.88.2 < 2.1"
109
109
  },
110
- "gitHead": "99812619b928d7802bb2f33df3f3321c9c36995e"
110
+ "gitHead": "0f4c09d90582210ae7c98e945b8c0b7af0f9a61d"
111
111
  }
@@ -8,10 +8,9 @@ import GrantRequestApprovalPopup from "./GrantRequestApprovalPopup";
8
8
 
9
9
  export const GrantRequestHeader = ({ grantRequest }) => {
10
10
  const { formatMessage } = useIntl();
11
- const canApprove = _.flow([
12
- _.getOr([], "pending_roles"),
13
- _.negate(_.isEmpty),
14
- ])(grantRequest);
11
+ const canApprove =
12
+ grantRequest?.status === "pending" &&
13
+ !_.isEmpty(grantRequest?.pending_roles);
15
14
  return (
16
15
  <Grid>
17
16
  <Grid.Column width={12}>
@@ -22,7 +21,7 @@ export const GrantRequestHeader = ({ grantRequest }) => {
22
21
  </Header.Content>
23
22
  </Header>
24
23
  </Grid.Column>
25
- {canApprove && (
24
+ {canApprove ? (
26
25
  <Grid.Column width={4} textAlign="right">
27
26
  <GrantRequestApprovalPopup
28
27
  content={formatMessage({ id: "grantRequest.actions.approve" })}
@@ -36,7 +35,7 @@ export const GrantRequestHeader = ({ grantRequest }) => {
36
35
  grantRequest={grantRequest}
37
36
  />
38
37
  </Grid.Column>
39
- )}
38
+ ) : null}
40
39
  </Grid>
41
40
  );
42
41
  };
@@ -8,6 +8,7 @@ import { getStructuresFields } from "../selectors/getStructuresFields";
8
8
 
9
9
  export const StructureFieldsDropdown = ({
10
10
  label,
11
+ fluid,
11
12
  inline,
12
13
  onSelectField,
13
14
  structureFields,
@@ -17,22 +18,33 @@ export const StructureFieldsDropdown = ({
17
18
  }) => {
18
19
  const { formatMessage } = useIntl();
19
20
  const onClick = ({ value, modifier }) => {
20
- const field = _.find(_.propEq("data_structure_id", value))(structureFields);
21
+ const [data_structure_id, parent_index] = _.isString(value)
22
+ ? value.split("/").map(Number)
23
+ : [value, undefined];
24
+ const field = _.isNil(parent_index)
25
+ ? _.find({ data_structure_id: data_structure_id })(structureFields)
26
+ : _.find({
27
+ data_structure_id: data_structure_id,
28
+ parent_index: parent_index,
29
+ })(structureFields);
21
30
  onSelectField(field, modifier);
22
31
  };
23
32
 
24
33
  const formatOption = (field) => {
34
+ const value = _.isNil(field?.parent_index)
35
+ ? field.data_structure_id
36
+ : `${field.data_structure_id}/${field.parent_index}`;
25
37
  const modifier = _.find({ sourceType: field.field_type })(
26
38
  typeCastModifiers
27
39
  );
28
40
  if (modifier) {
29
41
  return {
30
- key: field.data_structure_id,
42
+ key: value,
31
43
  text: `${field.name} (${formatMessage({
32
44
  id: `filtersGrid.field.modifier.${modifier.name}`,
33
45
  })})`,
34
46
  modifier,
35
- value: field.data_structure_id,
47
+ value: value,
36
48
  icon: formatMessage({
37
49
  id: `field_type.icon.${field.field_type}`,
38
50
  defaultMessage: "hashtag",
@@ -41,9 +53,9 @@ export const StructureFieldsDropdown = ({
41
53
  }
42
54
 
43
55
  return {
44
- key: field.data_structure_id,
56
+ key: value,
45
57
  text: field.name,
46
- value: field.data_structure_id,
58
+ value: value,
47
59
  icon: formatMessage({
48
60
  id: `field_type.icon.${field.field_type}`,
49
61
  defaultMessage: "hashtag",
@@ -88,6 +100,7 @@ export const StructureFieldsDropdown = ({
88
100
 
89
101
  return (
90
102
  <OptionGroup
103
+ fluid={fluid}
91
104
  inline={inline}
92
105
  label={label}
93
106
  value={value}
@@ -102,6 +115,7 @@ export const StructureFieldsDropdown = ({
102
115
 
103
116
  StructureFieldsDropdown.propTypes = {
104
117
  label: PropTypes.string,
118
+ fluid: PropTypes.bool,
105
119
  inline: PropTypes.bool,
106
120
  value: PropTypes.number,
107
121
  structureFields: PropTypes.array,
@@ -34,6 +34,12 @@ export const StructureSelectorInputField = ({
34
34
  onChangeField({ ...selectedStructure, clauses });
35
35
  };
36
36
 
37
+ const aliasIsNeeded =
38
+ _.flow(
39
+ _.map(_.path("structure.id")),
40
+ _.filter((s) => s === selectedStructure?.structure?.id)
41
+ )(structures).length > 1;
42
+
37
43
  return (
38
44
  <>
39
45
  <Form.Field>
@@ -74,6 +80,30 @@ export const StructureSelectorInputField = ({
74
80
  />
75
81
  )}
76
82
  </Form.Field>
83
+ {aliasIsNeeded && (
84
+ <Container style={{ paddingLeft: "8em" }}>
85
+ <Form.Field>
86
+ <label>
87
+ {formatMessage({
88
+ id: `ruleImplementation.props.structure.alias`,
89
+ })}
90
+ </label>
91
+ <Form.Input
92
+ width={fieldWidth ? fieldWidth : 7}
93
+ value={selectedStructure?.alias?.text || ""}
94
+ onChange={(e) =>
95
+ onChangeField({
96
+ ...selectedStructure,
97
+ alias: {
98
+ ...(selectedStructure?.alias || {}),
99
+ text: e.target.value,
100
+ },
101
+ })
102
+ }
103
+ />
104
+ </Form.Field>
105
+ </Container>
106
+ )}
77
107
  {joined && _.prop("structure")(selectedStructure) && (
78
108
  <Container style={{ paddingLeft: "8em" }}>
79
109
  <Form.Field>
@@ -2,10 +2,10 @@ import _ from "lodash/fp";
2
2
  import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { useIntl } from "react-intl";
5
- import { Form, Icon, Popup } from "semantic-ui-react";
5
+ import { Grid, Icon, Popup } from "semantic-ui-react";
6
6
  import StructureFieldsDropdown from "./StructureFieldsDropdown";
7
7
 
8
- const getClauses = selectedStructure => {
8
+ const getClauses = (selectedStructure) => {
9
9
  const clauses = _.getOr([], "clauses")(selectedStructure);
10
10
  return _.isEmpty(clauses) ? [{}] : clauses;
11
11
  };
@@ -14,15 +14,21 @@ const getParentStructures = (structures, selectedStructure) => {
14
14
  return structures && selectedStructure
15
15
  ? _.flow(
16
16
  _.filter(
17
- s =>
18
- _.path("structure.id")(s) !==
19
- _.path("structure.id")(selectedStructure)
17
+ (s) =>
18
+ _.path("alias.index")(s) !==
19
+ _.path("alias.index")(selectedStructure)
20
20
  ),
21
21
  _.defaultTo([])
22
22
  )(structures)
23
23
  : [];
24
24
  };
25
25
 
26
+ const structureToFieldDropdown = (structures) =>
27
+ _.map((s) => ({
28
+ ..._.prop("structure")(s),
29
+ alias: _.prop("alias")(s),
30
+ }))(structures);
31
+
26
32
  const JoinClause = ({
27
33
  createClause,
28
34
  deleteClause,
@@ -31,33 +37,43 @@ const JoinClause = ({
31
37
  left,
32
38
  parentStructures,
33
39
  right,
34
- selectedStructure
40
+ selectedStructure,
35
41
  }) => {
36
42
  const addActionDisabled = _.isEmpty(left) || _.isEmpty(right);
37
43
  const { formatMessage } = useIntl();
38
44
  return (
39
- <Form.Group inline>
40
- <Form.Field width={4}>
45
+ <Grid>
46
+ <Grid.Column width={4}>
41
47
  <StructureFieldsDropdown
42
- parentStructures={[_.prop("structure")(selectedStructure)]}
48
+ fluid
49
+ parentStructures={structureToFieldDropdown([selectedStructure])}
43
50
  onSelectField={handleChange("left", idx)}
44
- value={_.prop("id")(left)}
51
+ value={
52
+ _.isNil(_.prop("parent_index")(left))
53
+ ? _.prop("id")(left)
54
+ : `${_.prop("id")(left)}/${_.prop("parent_index")(left)}`
55
+ }
45
56
  />
46
- </Form.Field>
47
- <Form.Field width={1}>{"="}</Form.Field>
48
- <Form.Field width={4}>
57
+ </Grid.Column>
58
+ <Grid.Column width={1}>{"="}</Grid.Column>
59
+ <Grid.Column width={4}>
49
60
  <StructureFieldsDropdown
50
- parentStructures={_.map(_.prop("structure"))(parentStructures)}
61
+ fluid
62
+ parentStructures={structureToFieldDropdown(parentStructures)}
51
63
  onSelectField={handleChange("right", idx)}
52
- value={_.prop("id")(right)}
64
+ value={
65
+ _.isNil(_.prop("parent_index")(right))
66
+ ? _.prop("id")(right)
67
+ : `${_.prop("id")(right)}/${_.prop("parent_index")(right)}`
68
+ }
53
69
  />
54
- </Form.Field>
55
- <Form.Field width={1}>
70
+ </Grid.Column>
71
+ <Grid.Column width={1}>
56
72
  {
57
73
  <Popup
58
74
  disabled={!addActionDisabled}
59
75
  content={formatMessage({
60
- id: "dataset.form.button.add_join.popup"
76
+ id: "dataset.form.button.add_join.popup",
61
77
  })}
62
78
  trigger={
63
79
  <Icon
@@ -69,8 +85,8 @@ const JoinClause = ({
69
85
  }
70
86
  />
71
87
  }
72
- </Form.Field>
73
- <Form.Field width={1}>
88
+ </Grid.Column>
89
+ <Grid.Column width={1}>
74
90
  {idx > 0 && (
75
91
  <Icon
76
92
  name="trash"
@@ -78,8 +94,8 @@ const JoinClause = ({
78
94
  onClick={() => deleteClause(idx)}
79
95
  />
80
96
  )}
81
- </Form.Field>
82
- </Form.Group>
97
+ </Grid.Column>
98
+ </Grid>
83
99
  );
84
100
  };
85
101
 
@@ -91,24 +107,31 @@ JoinClause.propTypes = {
91
107
  selectedStructure: PropTypes.object,
92
108
  createClause: PropTypes.func,
93
109
  deleteClause: PropTypes.func,
94
- handleChange: PropTypes.func
110
+ handleChange: PropTypes.func,
95
111
  };
96
112
 
97
113
  export const StructureSelectorInputFieldJoin = ({
98
114
  structures,
99
115
  selectedStructure,
100
- handleSelectField
116
+ handleSelectField,
101
117
  }) => {
102
118
  const clauses = getClauses(selectedStructure);
103
119
  const parentStructures = getParentStructures(structures, selectedStructure);
104
120
  const createClause = () => handleSelectField([...clauses, {}]);
105
121
  const removeAt = (arr, idx) => [
106
122
  ..._.slice(0, idx)(arr),
107
- ..._.slice(idx + 1, arr.length)(arr)
123
+ ..._.slice(idx + 1, arr.length)(arr),
108
124
  ];
109
- const deleteClause = idx => handleSelectField(removeAt(clauses, idx));
110
- const handleChange = (prop, idx) => ({ data_structure_id: id }) => {
111
- const newClause = { ...clauses[idx], [prop]: { id } };
125
+ const deleteClause = (idx) => handleSelectField(removeAt(clauses, idx));
126
+ const handleChange = (prop, idx) => (data) => {
127
+ const {
128
+ data_structure_id: id,
129
+ parent_index: parent_index,
130
+ name: name,
131
+ } = data;
132
+ const newClause = _.isNil(parent_index)
133
+ ? { ...clauses[idx], [prop]: { id, name } }
134
+ : { ...clauses[idx], [prop]: { id, parent_index, name } };
112
135
  const newClauses = _.set(`[${idx}]`, newClause)(clauses);
113
136
  handleSelectField(newClauses);
114
137
  };
@@ -134,7 +157,7 @@ export const StructureSelectorInputFieldJoin = ({
134
157
  StructureSelectorInputFieldJoin.propTypes = {
135
158
  structures: PropTypes.array,
136
159
  selectedStructure: PropTypes.object,
137
- handleSelectField: PropTypes.func
160
+ handleSelectField: PropTypes.func,
138
161
  };
139
162
 
140
163
  export default StructureSelectorInputFieldJoin;
@@ -3,16 +3,29 @@ import { render } from "@truedat/test/render";
3
3
  import { GrantRequestHeader } from "../GrantRequestHeader";
4
4
 
5
5
  describe("<GrantRequestHeader />", () => {
6
- const grantRequest = {};
7
6
  const renderOpts = {
8
7
  messages: {
9
8
  en: {
10
9
  "grantRequest.header": "header",
10
+ "grantRequest.actions.approve": "approve",
11
+ "grantRequest.actions.reject": "reject",
11
12
  },
12
13
  },
13
14
  };
14
15
 
15
16
  it("matches the latest snapshot", () => {
17
+ const grantRequest = {};
18
+ const { container } = render(
19
+ <Suspense fallback={null}>
20
+ <GrantRequestHeader grantRequest={grantRequest} />
21
+ </Suspense>,
22
+ renderOpts
23
+ );
24
+ expect(container).toMatchSnapshot();
25
+ });
26
+
27
+ it("matches the latest snapshot (pending)", () => {
28
+ const grantRequest = { status: "pending", pending_roles: ["foo", "bar"] };
16
29
  const { container } = render(
17
30
  <Suspense fallback={null}>
18
31
  <GrantRequestHeader grantRequest={grantRequest} />
@@ -294,6 +294,7 @@ exports[`<GrantRequest /> matches the latest snapshot with approve actions 1`] =
294
294
  <span
295
295
  class="highlighted"
296
296
  >
297
+
297
298
  "foo"
298
299
  </span>
299
300
  </a>
@@ -560,6 +561,7 @@ exports[`<GrantRequest /> matches the latest snapshot with failed status 1`] = `
560
561
  <span
561
562
  class="highlighted"
562
563
  >
564
+
563
565
  "foo"
564
566
  </span>
565
567
  </a>
@@ -1,5 +1,45 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`<GrantRequestHeader /> matches the latest snapshot (pending) 1`] = `
4
+ <div>
5
+ <div
6
+ class="ui grid"
7
+ >
8
+ <div
9
+ class="twelve wide column"
10
+ >
11
+ <h2
12
+ class="ui header"
13
+ >
14
+ <i
15
+ aria-hidden="true"
16
+ class="key circular icon"
17
+ />
18
+ <div
19
+ class="content"
20
+ >
21
+ header
22
+ </div>
23
+ </h2>
24
+ </div>
25
+ <div
26
+ class="right aligned four wide column"
27
+ >
28
+ <button
29
+ class="ui primary button button icon group-actions"
30
+ >
31
+ approve
32
+ </button>
33
+ <button
34
+ class="ui secondary button button icon group-actions"
35
+ >
36
+ reject
37
+ </button>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ `;
42
+
3
43
  exports[`<GrantRequestHeader /> matches the latest snapshot 1`] = `
4
44
  <div>
5
45
  <div
@@ -1,37 +1,39 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<StructureSelectorInputFieldJoin /> matches the latest JoinClause snapshot 1`] = `
4
- <FormGroup
5
- inline={true}
6
- >
7
- <FormField
4
+ <Grid>
5
+ <GridColumn
8
6
  width={4}
9
7
  >
10
8
  <Connect(StructureFieldsDropdown)
9
+ fluid={true}
11
10
  onSelectField={[Function]}
12
11
  parentStructures={
13
12
  Array [
14
- undefined,
13
+ Object {
14
+ "alias": undefined,
15
+ },
15
16
  ]
16
17
  }
17
18
  value="7"
18
19
  />
19
- </FormField>
20
- <FormField
20
+ </GridColumn>
21
+ <GridColumn
21
22
  width={1}
22
23
  >
23
24
  =
24
- </FormField>
25
- <FormField
25
+ </GridColumn>
26
+ <GridColumn
26
27
  width={4}
27
28
  >
28
29
  <Connect(StructureFieldsDropdown)
30
+ fluid={true}
29
31
  onSelectField={[Function]}
30
32
  parentStructures={Array []}
31
33
  value="8"
32
34
  />
33
- </FormField>
34
- <FormField
35
+ </GridColumn>
36
+ <GridColumn
35
37
  width={1}
36
38
  >
37
39
  <Popup
@@ -57,8 +59,8 @@ exports[`<StructureSelectorInputFieldJoin /> matches the latest JoinClause snaps
57
59
  />
58
60
  }
59
61
  />
60
- </FormField>
61
- <FormField
62
+ </GridColumn>
63
+ <GridColumn
62
64
  width={1}
63
65
  >
64
66
  <Icon
@@ -67,8 +69,8 @@ exports[`<StructureSelectorInputFieldJoin /> matches the latest JoinClause snaps
67
69
  name="trash"
68
70
  onClick={[Function]}
69
71
  />
70
- </FormField>
71
- </FormGroup>
72
+ </GridColumn>
73
+ </Grid>
72
74
  `;
73
75
 
74
76
  exports[`<StructureSelectorInputFieldJoin /> matches the latest snapshot 1`] = `
@@ -12,7 +12,8 @@ const getFields = (parent, structuresFields) =>
12
12
  _.propOr([], _.path("id")(parent)),
13
13
  _.map((sf) => ({
14
14
  ...sf,
15
- label: _.prop("name")(parent),
15
+ label: _.prop("alias.text")(parent) || _.prop("name")(parent),
16
+ parent_index: _.prop("alias.index")(parent),
16
17
  }))
17
18
  )(structuresFields);
18
19
 
@@ -20,7 +21,7 @@ const getFieldsFromStructures = (structuresFields, parentStructures) =>
20
21
  _.flow(
21
22
  _.map((parent) => getFields(parent, structuresFields)),
22
23
  _.flatten,
23
- _.uniqBy("data_structure_id"),
24
+ _.uniqBy((s) => `${s.data_structure_id}/${s.parent_index}`),
24
25
  _.map(withFieldType)
25
26
  )(parentStructures);
26
27