@truedat/dd 4.44.2 → 4.44.5

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/CHANGELOG.md +10 -0
  2. package/package.json +23 -19
  3. package/src/api/mutations.js +27 -0
  4. package/src/api/queries.js +24 -0
  5. package/src/api.js +2 -0
  6. package/src/components/DictionaryRoutes.js +7 -5
  7. package/src/components/EditDomainPopup.js +1 -1
  8. package/src/components/FilteredNav.js +9 -9
  9. package/src/components/GrantFilters.js +1 -5
  10. package/src/components/GrantRequestApprovalPopup.js +0 -1
  11. package/src/components/ImplementationStructuresLoader.js +14 -11
  12. package/src/components/PendingStructureNotes.js +11 -5
  13. package/src/components/ReferenceDataset.js +23 -0
  14. package/src/components/ReferenceDatasetActions.js +88 -0
  15. package/src/components/ReferenceDatasetBreadcrumbs.js +22 -0
  16. package/src/components/ReferenceDatasetCreate.js +36 -0
  17. package/src/components/ReferenceDatasetDetail.js +42 -0
  18. package/src/components/ReferenceDatasetForm.js +109 -0
  19. package/src/components/ReferenceDatasetHeader.js +32 -0
  20. package/src/components/ReferenceDatasetRoutes.js +56 -0
  21. package/src/components/ReferenceDatasetTable.js +42 -0
  22. package/src/components/ReferenceDatasets.js +61 -0
  23. package/src/components/ReferenceDatasetsTable.js +105 -0
  24. package/src/components/StructureConfidentialButton.js +1 -1
  25. package/src/components/StructureFilters.js +1 -5
  26. package/src/components/StructureNotesEdit.js +6 -6
  27. package/src/components/StructureProperties.js +4 -1
  28. package/src/components/StructureTagsRoutes.js +0 -1
  29. package/src/components/StructureTypesCrumbs.js +0 -1
  30. package/src/components/StructureVersionListItem.js +2 -2
  31. package/src/components/StructureView.js +1 -3
  32. package/src/components/SystemForm.js +1 -1
  33. package/src/components/__tests__/ImplementationStructuresLoader.spec.js +12 -54
  34. package/src/components/__tests__/LineageEventsTable.spec.js +2 -7
  35. package/src/components/__tests__/LineageRoutes.spec.js +4 -4
  36. package/src/components/__tests__/PendingStructureNoteRow.spec.js +1 -17
  37. package/src/components/__tests__/PendingStructureNotes.spec.js +5 -33
  38. package/src/components/__tests__/ReferenceDataset.spec.js +64 -0
  39. package/src/components/__tests__/ReferenceDatasetActions.spec.js +17 -0
  40. package/src/components/__tests__/ReferenceDatasetBreadcrumbs.spec.js +12 -0
  41. package/src/components/__tests__/ReferenceDatasetCreate.spec.js +12 -0
  42. package/src/components/__tests__/ReferenceDatasetDetail.spec.js +37 -0
  43. package/src/components/__tests__/ReferenceDatasetForm.spec.js +51 -0
  44. package/src/components/__tests__/ReferenceDatasetHeader.spec.js +17 -0
  45. package/src/components/__tests__/ReferenceDatasetRoutes.spec.js +74 -0
  46. package/src/components/__tests__/ReferenceDatasetTable.spec.js +18 -0
  47. package/src/components/__tests__/ReferenceDatasets.spec.js +32 -0
  48. package/src/components/__tests__/ReferenceDatasetsTable.spec.js +22 -0
  49. package/src/components/__tests__/StructureConfidentialButton.spec.js +26 -30
  50. package/src/components/__tests__/StructureGrantRequestButton.spec.js +4 -23
  51. package/src/components/__tests__/StructureNoteActions.spec.js +2 -19
  52. package/src/components/__tests__/StructureNotes.spec.js +3 -15
  53. package/src/components/__tests__/StructureNotesEdit.spec.js +5 -25
  54. package/src/components/__tests__/StructureProperties.spec.js +6 -8
  55. package/src/components/__tests__/StructureTagForm.spec.js +1 -3
  56. package/src/components/__tests__/StructureVersionListItem.spec.js +4 -4
  57. package/src/components/__tests__/StructuresOptions.spec.js +1 -7
  58. package/src/components/__tests__/StructuresUploadEventsTable.spec.js +3 -4
  59. package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +4 -0
  60. package/src/components/__tests__/__snapshots__/LineageRoutes.spec.js.snap +1 -20
  61. package/src/components/__tests__/__snapshots__/PendingStructureNotes.spec.js.snap +3 -3
  62. package/src/components/__tests__/__snapshots__/ProfileExecution.spec.js.snap +2 -1
  63. package/src/components/__tests__/__snapshots__/ReferenceDataset.spec.js.snap +365 -0
  64. package/src/components/__tests__/__snapshots__/ReferenceDatasetActions.spec.js.snap +65 -0
  65. package/src/components/__tests__/__snapshots__/ReferenceDatasetBreadcrumbs.spec.js.snap +25 -0
  66. package/src/components/__tests__/__snapshots__/ReferenceDatasetCreate.spec.js.snap +98 -0
  67. package/src/components/__tests__/__snapshots__/ReferenceDatasetDetail.spec.js.snap +135 -0
  68. package/src/components/__tests__/__snapshots__/ReferenceDatasetForm.spec.js.snap +61 -0
  69. package/src/components/__tests__/__snapshots__/ReferenceDatasetHeader.spec.js.snap +95 -0
  70. package/src/components/__tests__/__snapshots__/ReferenceDatasetRoutes.spec.js.snap +414 -0
  71. package/src/components/__tests__/__snapshots__/ReferenceDatasetTable.spec.js.snap +75 -0
  72. package/src/components/__tests__/__snapshots__/ReferenceDatasets.spec.js.snap +128 -0
  73. package/src/components/__tests__/__snapshots__/ReferenceDatasetsTable.spec.js.snap +86 -0
  74. package/src/components/__tests__/__snapshots__/StructureConfidentialButton.spec.js.snap +13 -33
  75. package/src/components/__tests__/__snapshots__/StructureNavClassified.spec.js.snap +2 -2
  76. package/src/components/__tests__/__snapshots__/StructureNotes.spec.js.snap +9 -9
  77. package/src/components/__tests__/__snapshots__/StructureNotesEdit.spec.js.snap +2 -2
  78. package/src/components/__tests__/__snapshots__/StructureProperties.spec.js.snap +76 -71
  79. package/src/components/__tests__/__snapshots__/StructureVersionListItem.spec.js.snap +31 -64
  80. package/src/messages/en.js +18 -0
  81. package/src/messages/es.js +20 -0
  82. package/src/reducers/__tests__/ddMessage.spec.js +26 -5
  83. package/src/reducers/__tests__/graph.spec.js +1 -6
  84. package/src/reducers/__tests__/referenceDatasetSaving.spec.js +44 -0
  85. package/src/reducers/__tests__/structureRedirect.spec.js +37 -13
  86. package/src/reducers/ddMessage.js +26 -1
  87. package/src/reducers/index.js +2 -0
  88. package/src/reducers/referenceDatasetSaving.js +16 -0
  89. package/src/reducers/structureRedirect.js +36 -15
  90. package/src/reducers/structuresUploadEvents.js +0 -1
  91. package/src/routines.js +35 -74
  92. package/src/sagas/__tests__/createReferenceDataset.spec.js +90 -0
  93. package/src/sagas/__tests__/deleteReferenceDataset.spec.js +81 -0
  94. package/src/sagas/__tests__/updateReferenceDataset.spec.js +116 -0
  95. package/src/sagas/createReferenceDataset.js +34 -0
  96. package/src/sagas/deleteReferenceDataset.js +29 -0
  97. package/src/sagas/downloadReferenceDataset.js +44 -0
  98. package/src/sagas/index.js +31 -22
  99. package/src/sagas/updateReferenceDataset.js +35 -0
  100. package/src/selectors/getRelationSortingCriteria.js +3 -5
  101. package/src/selectors/getTabVisibility.js +1 -4
  102. package/src/components/__tests__/__snapshots__/ImplementationStructuresLoader.spec.js.snap +0 -30
@@ -0,0 +1,109 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { useForm, Controller } from "react-hook-form";
5
+ import { connect } from "react-redux";
6
+ import { Button, Form } from "semantic-ui-react";
7
+ import { useIntl } from "react-intl";
8
+ import { HistoryBackButton } from "@truedat/core/components";
9
+
10
+ const MAX_SIZE_MB = 2;
11
+ const MAX_SIZE = MAX_SIZE_MB * 1024 * 1024; // 2MB
12
+
13
+ const datasetValidator = (formatMessage) => (value) =>
14
+ _.isNull(value)
15
+ ? true
16
+ : value.size > MAX_SIZE
17
+ ? formatMessage(
18
+ { id: "widget.image.error.too_big" },
19
+ { size_mb: MAX_SIZE_MB }
20
+ )
21
+ : true;
22
+
23
+ export const ReferenceDatasetForm = ({ saving, dataset = {}, onSubmit }) => {
24
+ const { formatMessage } = useIntl();
25
+ const { handleSubmit, control, formState } = useForm({
26
+ mode: "all",
27
+ defaultValues: { name: dataset?.name || "", file: null },
28
+ });
29
+ const { isDirty, isValid } = formState;
30
+ const disabled = saving || !isDirty || !isValid;
31
+ return (
32
+ <Form onSubmit={handleSubmit(onSubmit)}>
33
+ <Controller
34
+ control={control}
35
+ name="name"
36
+ rules={{
37
+ required: formatMessage(
38
+ { id: "form.validation.required" },
39
+ { prop: formatMessage({ id: "referenceDataset.name" }) }
40
+ ),
41
+ }}
42
+ render={({
43
+ field: { onBlur, onChange, value },
44
+ fieldState: { error },
45
+ }) => (
46
+ <Form.Input
47
+ autoComplete="off"
48
+ error={!!error}
49
+ label={formatMessage({ id: "referenceDataset.name" })}
50
+ onBlur={onBlur}
51
+ onChange={(_e, { value }) => onChange(value)}
52
+ value={value || ""}
53
+ required
54
+ />
55
+ )}
56
+ />
57
+ <Controller
58
+ control={control}
59
+ name="file"
60
+ rules={{
61
+ validate: datasetValidator(formatMessage),
62
+ required: dataset?.id
63
+ ? false
64
+ : formatMessage(
65
+ { id: "form.validation.required" },
66
+ { prop: formatMessage({ id: "referenceDataset.file" }) }
67
+ ),
68
+ }}
69
+ render={({ field: { onBlur, onChange }, fieldState: { error } }) => (
70
+ <Form.Input
71
+ type="file"
72
+ error={error?.message}
73
+ label={formatMessage({ id: "referenceDataset.file" })}
74
+ onBlur={onBlur}
75
+ onChange={(e) => onChange(e.target.files[0])}
76
+ required={!dataset?.id}
77
+ input={{ accept: "text/*,.csv,.txt" }}
78
+ />
79
+ )}
80
+ />
81
+ <div className="actions">
82
+ <Button
83
+ floated="right"
84
+ type="submit"
85
+ primary
86
+ loading={saving}
87
+ disabled={disabled}
88
+ content={formatMessage({ id: "actions.save" })}
89
+ />
90
+ <HistoryBackButton
91
+ content={formatMessage({ id: "actions.cancel" })}
92
+ disabled={saving}
93
+ />
94
+ </div>
95
+ </Form>
96
+ );
97
+ };
98
+
99
+ ReferenceDatasetForm.propTypes = {
100
+ onSubmit: PropTypes.func,
101
+ saving: PropTypes.bool,
102
+ dataset: PropTypes.object,
103
+ };
104
+
105
+ export const mapStateToProps = ({ referenceDatasetSaving }) => ({
106
+ saving: !!referenceDatasetSaving,
107
+ });
108
+
109
+ export default connect(mapStateToProps)(ReferenceDatasetForm);
@@ -0,0 +1,32 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { FormattedMessage } from "react-intl";
5
+ import { Header, Icon, Grid } from "semantic-ui-react";
6
+ import ReferenceDatasetActions from "./ReferenceDatasetActions";
7
+
8
+ export const ReferenceDatasetHeader = ({ dataset }) =>
9
+ _.isEmpty(dataset) ? null : (
10
+ <Grid>
11
+ <Grid.Column width={8}>
12
+ <Header as="h2">
13
+ <Icon circular name="list ol" />
14
+ <Header.Content>
15
+ {dataset.name}
16
+ <Header.Subheader>
17
+ <FormattedMessage id="referenceDataset" />
18
+ </Header.Subheader>
19
+ </Header.Content>
20
+ </Header>
21
+ </Grid.Column>
22
+ <Grid.Column width={8} textAlign="right">
23
+ <ReferenceDatasetActions dataset={dataset} />
24
+ </Grid.Column>
25
+ </Grid>
26
+ );
27
+
28
+ ReferenceDatasetHeader.propTypes = {
29
+ dataset: PropTypes.object.isRequired,
30
+ };
31
+
32
+ export default ReferenceDatasetHeader;
@@ -0,0 +1,56 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { Route, Switch, useParams } from "react-router-dom";
4
+ import { useQuery } from "@apollo/client";
5
+ import { Unauthorized, Loading } from "@truedat/core/components";
6
+ import { useAuthorized } from "@truedat/core/hooks";
7
+ import {
8
+ REFERENCE_DATASETS,
9
+ REFERENCE_DATASET_NEW,
10
+ REFERENCE_DATASET,
11
+ } from "@truedat/core/routes";
12
+ import { REFERENCE_DATASET_QUERY } from "../api/queries";
13
+ import ReferenceDataset from "./ReferenceDataset";
14
+ import ReferenceDatasets from "./ReferenceDatasets";
15
+ import ReferenceDatasetCreate from "./ReferenceDatasetCreate";
16
+
17
+ export const DatasetLoader = () => {
18
+ const { id } = useParams();
19
+ const { loading, error, data } = useQuery(REFERENCE_DATASET_QUERY, {
20
+ variables: { id },
21
+ });
22
+ if (error) return null;
23
+ if (loading) return <Loading />;
24
+ const dataset = data?.referenceDataset;
25
+ return _.isEmpty(dataset) ? null : <ReferenceDataset dataset={dataset} />;
26
+ };
27
+
28
+ export const AuthorizedReferenceDatasetRoutes = () => (
29
+ <Switch>
30
+ <Route
31
+ path={REFERENCE_DATASET_NEW}
32
+ exact
33
+ render={() => <ReferenceDatasetCreate />}
34
+ />
35
+ <Route
36
+ path={REFERENCE_DATASETS}
37
+ exact
38
+ render={() => <ReferenceDatasets />}
39
+ />
40
+ <Route path={REFERENCE_DATASET} render={() => <DatasetLoader />} />
41
+ </Switch>
42
+ );
43
+
44
+ export const ReferenceDatasetRoutes = () => {
45
+ const authorized = useAuthorized();
46
+ return (
47
+ <Route
48
+ path={REFERENCE_DATASETS}
49
+ render={() =>
50
+ authorized ? <AuthorizedReferenceDatasetRoutes /> : <Unauthorized />
51
+ }
52
+ />
53
+ );
54
+ };
55
+
56
+ export default ReferenceDatasetRoutes;
@@ -0,0 +1,42 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Table } from "semantic-ui-react";
5
+
6
+ const truncateOpts = { length: 100 };
7
+
8
+ export const DataRow = ({ values }) => (
9
+ <Table.Row>
10
+ {values.map((value, key) => (
11
+ <Table.Cell key={key}>{_.truncate(truncateOpts)(value)}</Table.Cell>
12
+ ))}
13
+ </Table.Row>
14
+ );
15
+
16
+ DataRow.propTypes = {
17
+ values: PropTypes.arrayOf(PropTypes.string),
18
+ };
19
+
20
+ export const ReferenceDatasetTable = ({ headers = [], rows = [] }) => (
21
+ <Table compact basic="very">
22
+ <Table.Header>
23
+ <Table.Row>
24
+ {headers.map((text, key) => (
25
+ <Table.HeaderCell key={key} content={text} />
26
+ ))}
27
+ </Table.Row>
28
+ </Table.Header>
29
+ <Table.Body>
30
+ {rows.map((values, key) => (
31
+ <DataRow key={key} values={values} />
32
+ ))}
33
+ </Table.Body>
34
+ </Table>
35
+ );
36
+
37
+ ReferenceDatasetTable.propTypes = {
38
+ headers: PropTypes.arrayOf(PropTypes.string).isRequired,
39
+ rows: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
40
+ };
41
+
42
+ export default ReferenceDatasetTable;
@@ -0,0 +1,61 @@
1
+ import _ from "lodash/fp";
2
+ import React, { useState } from "react";
3
+ import { matchSorter } from "match-sorter";
4
+ import { useIntl, FormattedMessage } from "react-intl";
5
+ import { Link } from "react-router-dom";
6
+ import { Button, Header, Icon, Input, Segment } from "semantic-ui-react";
7
+ import { useQuery } from "@apollo/client";
8
+ import { Loading } from "@truedat/core/components";
9
+ import { REFERENCE_DATASET_NEW } from "@truedat/core/routes";
10
+ import { lowerDeburrTrim } from "@truedat/core/services/sort";
11
+ import { REFERENCE_DATASETS_QUERY } from "../api/queries";
12
+ import ReferenceDatasetsTable from "./ReferenceDatasetsTable";
13
+
14
+ const sortByName = _.sortBy([({ name }) => lowerDeburrTrim(name), "name"]);
15
+
16
+ export const ReferenceDatasets = () => {
17
+ const [searchTerm, setSearchTerm] = useState("");
18
+ const { formatMessage } = useIntl();
19
+ const { loading, error, data } = useQuery(REFERENCE_DATASETS_QUERY);
20
+ if (error) return null;
21
+ if (loading) return <Loading />;
22
+ const items = data?.referenceDatasets;
23
+ const datasets =
24
+ searchTerm === ""
25
+ ? sortByName(items)
26
+ : matchSorter(items, searchTerm, {
27
+ keys: ["name", "headers", "rowCount", "updatedAt"],
28
+ threshold: matchSorter.rankings.CONTAINS,
29
+ });
30
+ return (
31
+ <Segment>
32
+ <Header as="h2">
33
+ <Button
34
+ floated="right"
35
+ primary
36
+ as={Link}
37
+ to={REFERENCE_DATASET_NEW}
38
+ content={formatMessage({ id: "referenceDatasets.actions.create" })}
39
+ />
40
+ <Icon name="list ol" circular />
41
+ <Header.Content>
42
+ <FormattedMessage id="referenceDatasets.header" />
43
+ <Header.Subheader>
44
+ <FormattedMessage id="referenceDatasets.subheader" />
45
+ </Header.Subheader>
46
+ </Header.Content>
47
+ </Header>
48
+ <Input
49
+ onChange={(_e, { value }) => setSearchTerm(value)}
50
+ value={searchTerm}
51
+ icon={{ name: "search", link: true }}
52
+ placeholder={formatMessage({
53
+ id: "referenceDatasets.search.placeholder",
54
+ })}
55
+ />
56
+ <ReferenceDatasetsTable datasets={datasets} />
57
+ </Segment>
58
+ );
59
+ };
60
+
61
+ export default ReferenceDatasets;
@@ -0,0 +1,105 @@
1
+ import _ from "lodash/fp";
2
+ import React, { useState } from "react";
3
+ import PropTypes from "prop-types";
4
+ import { Icon, Table } from "semantic-ui-react";
5
+ import { Link } from "react-router-dom";
6
+ import { useIntl } from "react-intl";
7
+ import Moment from "react-moment";
8
+ import { DateTime } from "@truedat/core/components";
9
+ import { linkTo } from "@truedat/core/routes";
10
+
11
+ export const HeaderRow = ({ onDateClick, relative }) => {
12
+ const { formatMessage } = useIntl();
13
+ return (
14
+ <Table.Row>
15
+ <Table.HeaderCell
16
+ content={formatMessage({ id: "referenceDataset.name" })}
17
+ />
18
+ <Table.HeaderCell
19
+ content={formatMessage({ id: "referenceDataset.headers" })}
20
+ />
21
+ <Table.HeaderCell
22
+ content={formatMessage({ id: "referenceDataset.rowCount" })}
23
+ textAlign="right"
24
+ />
25
+ <Table.HeaderCell textAlign="right">
26
+ {formatMessage({ id: "referenceDataset.updatedAt" })}{" "}
27
+ <a onClick={onDateClick}>
28
+ <Icon name={relative ? "calendar outline" : "clock outline"} />
29
+ </a>
30
+ </Table.HeaderCell>
31
+ </Table.Row>
32
+ );
33
+ };
34
+
35
+ HeaderRow.propTypes = {
36
+ relative: PropTypes.bool,
37
+ onDateClick: PropTypes.func,
38
+ };
39
+
40
+ export const DatasetRow = ({
41
+ name,
42
+ id,
43
+ relative,
44
+ rowCount,
45
+ headers,
46
+ updatedAt,
47
+ }) => {
48
+ const { locale } = useIntl();
49
+ return (
50
+ <Table.Row>
51
+ <Table.Cell>
52
+ <Link to={linkTo.REFERENCE_DATASET({ id })}>{name}</Link>
53
+ </Table.Cell>
54
+ <Table.Cell content={_.truncate({ length: 90 })(_.join(", ")(headers))} />
55
+ <Table.Cell textAlign="right" width={1} content={rowCount} />
56
+ <Table.Cell textAlign="right" width={3}>
57
+ {relative ? (
58
+ <Moment locale={locale} fromNow date={updatedAt} />
59
+ ) : (
60
+ <DateTime value={updatedAt} locale={locale} />
61
+ )}
62
+ </Table.Cell>
63
+ </Table.Row>
64
+ );
65
+ };
66
+
67
+ DatasetRow.propTypes = {
68
+ headers: PropTypes.arrayOf(PropTypes.string),
69
+ id: PropTypes.string,
70
+ name: PropTypes.string,
71
+ relative: PropTypes.bool,
72
+ rowCount: PropTypes.number,
73
+ updatedAt: PropTypes.string,
74
+ };
75
+
76
+ export const ReferenceDatasetsTable = ({ datasets }) => {
77
+ const { formatMessage } = useIntl();
78
+ const [relative, setRelative] = useState(true);
79
+
80
+ return (
81
+ <Table>
82
+ <caption className="text-right">
83
+ {formatMessage(
84
+ { id: "referenceDatasets.count" },
85
+ { count: _.size(datasets) }
86
+ )}
87
+ </caption>
88
+ <Table.Header>
89
+ <HeaderRow
90
+ relative={relative}
91
+ onDateClick={() => setRelative((value) => !value)}
92
+ />
93
+ </Table.Header>
94
+ <Table.Body>
95
+ {datasets.map((props, key) => (
96
+ <DatasetRow key={key} relative={relative} {...props} />
97
+ ))}
98
+ </Table.Body>
99
+ </Table>
100
+ );
101
+ };
102
+
103
+ ReferenceDatasetsTable.propTypes = { datasets: PropTypes.array };
104
+
105
+ export default ReferenceDatasetsTable;
@@ -34,7 +34,7 @@ export class StructureConfidentialButton extends React.Component {
34
34
  userPermissions,
35
35
  } = this.props;
36
36
 
37
- if (!userPermissions.confidential || !userPermissions.update) return null;
37
+ if (!userPermissions?.confidential || !userPermissions?.update) return null;
38
38
 
39
39
  const buttonText = structure.confidential
40
40
  ? formatMessage({ id: "structure.mark_as_public" })
@@ -1,13 +1,9 @@
1
- import React from "react";
2
1
  import { bindActionCreators } from "redux";
3
2
  import { connect } from "react-redux";
3
+ import { AvailableFilters } from "@truedat/core/components";
4
4
  import { addStructureFilter, resetStructureFilters } from "../routines";
5
5
  import { getStructureAvailableFilters } from "../selectors";
6
6
 
7
- const AvailableFilters = React.lazy(() =>
8
- import("@truedat/core/components/AvailableFilters")
9
- );
10
-
11
7
  const mapStateToProps = (state) => ({
12
8
  filters: getStructureAvailableFilters(state),
13
9
  disabled: state.structureFiltersLoading,
@@ -5,7 +5,7 @@ import { connect } from "react-redux";
5
5
  import { Button, Form, Segment } from "semantic-ui-react";
6
6
  import { useIntl } from "react-intl";
7
7
  import { HistoryBackButton } from "@truedat/core/components";
8
- import { selectTemplate, selectDomain } from "@truedat/df/routines";
8
+ import { selectTemplate, selectDomains } from "@truedat/df/routines";
9
9
  import { applyTemplate, validateContent } from "@truedat/df/utils";
10
10
  import { doStructureNoteAction } from "../routines";
11
11
  import { getLatestDfContent } from "../selectors/getSortedStructureNotes";
@@ -24,16 +24,16 @@ export const StructureNotesEdit = ({
24
24
  template,
25
25
  doStructureNoteAction,
26
26
  selectTemplate,
27
- selectDomain,
27
+ selectDomains,
28
28
  structureNotes,
29
29
  latestDfContent,
30
30
  }) => {
31
31
  const [content, setContent] = useState(latestDfContent);
32
32
 
33
33
  useEffect(() => {
34
- selectDomain({ id: structure.domain_id });
34
+ selectDomains(structure.domain_ids);
35
35
  if (template) selectTemplate(template);
36
- }, [template, structure, selectTemplate, selectDomain]);
36
+ }, [template, structure, selectTemplate, selectDomains]);
37
37
 
38
38
  useEffect(() => {
39
39
  if (template && latestDfContent) {
@@ -90,7 +90,7 @@ StructureNotesEdit.propTypes = {
90
90
  template: PropTypes.object,
91
91
  doStructureNoteAction: PropTypes.func,
92
92
  selectTemplate: PropTypes.func,
93
- selectDomain: PropTypes.func,
93
+ selectDomains: PropTypes.func,
94
94
  structureNotes: PropTypes.object,
95
95
  latestDfContent: PropTypes.object,
96
96
  };
@@ -118,6 +118,6 @@ const mapStateToProps = (state) => {
118
118
 
119
119
  export default connect(mapStateToProps, {
120
120
  selectTemplate,
121
- selectDomain,
121
+ selectDomains,
122
122
  doStructureNoteAction,
123
123
  })(StructureNotesEdit);
@@ -21,7 +21,10 @@ export const StructureProperties = ({ properties, structure }) => {
21
21
  <Item>
22
22
  <Item.Content>
23
23
  <Item.Header as="h5">
24
- <FormattedMessage id={`structure.${property.name}`} />
24
+ <FormattedMessage
25
+ id={`structure.${property.name}`}
26
+ defaultMessage={property.name}
27
+ />
25
28
  </Item.Header>
26
29
  <Item.Description>
27
30
  {columnDecorator(property)(structure)}
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import { Route, Switch, useParams } from "react-router-dom";
4
3
  import { useQuery } from "@apollo/client";
@@ -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 { Breadcrumb } from "semantic-ui-react";
@@ -6,7 +6,7 @@ import { List } from "semantic-ui-react";
6
6
  import Moment from "react-moment";
7
7
  import { linkTo } from "@truedat/core/routes";
8
8
 
9
- const dateDecorator = date => (
9
+ const dateDecorator = (date) => (
10
10
  <Moment locale="es" date={date} format="YYYY-MM-DD HH:mm" />
11
11
  );
12
12
 
@@ -30,7 +30,7 @@ export const StructureVersionListItem = ({ id, version, inserted_at }) => (
30
30
  StructureVersionListItem.propTypes = {
31
31
  id: PropTypes.number,
32
32
  version: PropTypes.number,
33
- inserted_at: PropTypes.string
33
+ inserted_at: PropTypes.string,
34
34
  };
35
35
 
36
36
  export default StructureVersionListItem;
@@ -1,10 +1,8 @@
1
1
  import _ from "lodash/fp";
2
- import { linkTo } from "@truedat/core/routes";
3
- import { Link } from "react-router-dom";
4
2
  import React from "react";
5
3
  import PropTypes from "prop-types";
6
4
  import { connect } from "react-redux";
7
- import { Grid, Segment, Button } from "semantic-ui-react";
5
+ import { Grid, Segment } from "semantic-ui-react";
8
6
  import FilteredNav from "./FilteredNav";
9
7
  import StructureCrumbs from "./StructureCrumbs";
10
8
  import StructureGrantCart from "./StructureGrantCart";
@@ -1,5 +1,5 @@
1
1
  import _ from "lodash/fp";
2
- import React, { useEffect, useState } from "react";
2
+ import React, { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { FormattedMessage, useIntl } from "react-intl";
5
5
  import { connect } from "react-redux";
@@ -1,63 +1,21 @@
1
1
  import React from "react";
2
- import { mount } from "enzyme";
2
+ import { render } from "@truedat/test/render";
3
3
  import { ImplementationStructuresLoader } from "../ImplementationStructuresLoader";
4
4
 
5
- jest.mock("@fluentui/react-component-event-listener", () => ({
6
- documentRef: null,
7
- windowRef: null,
8
- }));
9
-
10
- jest.mock("react-redux", () => ({
11
- ...jest.requireActual("react-redux"),
12
- useSelector: jest.fn(() => [1]),
13
- }));
14
-
15
- const getProps = () => ({
16
- fetchStructure: jest.fn(),
17
- structureIds: [1, 2],
18
- clearStructure: jest.fn(),
19
- });
20
-
21
5
  describe("<ImplementationStructuresLoader/>", () => {
22
- it("matches the latest snapshot", () => {
23
- const props = getProps();
24
- const wrapper = mount(<ImplementationStructuresLoader {...props} />);
25
- expect(wrapper).toMatchSnapshot();
26
- });
27
-
28
- it("calls fetchStructure when component mounts but not when it unmounts", () => {
29
- const props = getProps();
30
- const wrapper = mount(<ImplementationStructuresLoader {...props} />);
31
- expect(props.fetchStructure).toHaveBeenCalledTimes(1);
32
- expect(props.fetchStructure).toHaveBeenCalledWith({ id: 2 });
33
-
34
- wrapper.unmount();
35
- expect(props.fetchStructure).toHaveBeenCalledTimes(1);
36
- });
37
-
38
- it("call fetchStructure when next id of structures when field id is already in structures fields", () => {
39
- const props = { ...getProps(), structureIds: [1, 2] };
40
- const wrapper = mount(<ImplementationStructuresLoader {...props} />);
41
- expect(props.fetchStructure).toHaveBeenCalledTimes(1);
42
- expect(props.fetchStructure).toHaveBeenCalledWith({ id: 2 });
43
-
44
- wrapper.unmount();
6
+ it("calls fetchStructure on mount and clearStructure on unmount", () => {
7
+ const props = {
8
+ clearStructure: jest.fn(),
9
+ fetchStructure: jest.fn(),
10
+ structureIds: [42],
11
+ };
12
+ const { unmount } = render(<ImplementationStructuresLoader {...props} />);
13
+ expect(props.clearStructure).toHaveBeenCalledTimes(0);
45
14
  expect(props.fetchStructure).toHaveBeenCalledTimes(1);
46
- });
15
+ expect(props.fetchStructure).toHaveBeenCalledWith({ id: 42 });
47
16
 
48
- it("calls clearStructure when component unmounts but not when it mounts", () => {
49
- const props = getProps();
50
- const wrapper = mount(<ImplementationStructuresLoader {...props} />);
51
- expect(props.clearStructure).toHaveBeenCalledTimes(0);
52
- wrapper.unmount();
17
+ unmount();
53
18
  expect(props.clearStructure).toHaveBeenCalledTimes(1);
54
- });
55
-
56
- it("calls fetchStructures when structureIds is updated", () => {
57
- const props = getProps();
58
- const wrapper = mount(<ImplementationStructuresLoader {...props} />);
59
- wrapper.setProps({ structureIds: [6, 5] });
60
- expect(props.fetchStructure).toHaveBeenCalledTimes(2);
61
- expect(props.fetchStructure).toHaveBeenCalledWith({ id: 5 });
19
+ expect(props.fetchStructure).toHaveBeenCalledTimes(1);
62
20
  });
63
21
  });
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { render } from "@truedat/test/render";
3
3
  import { LineageEventsTable } from "../LineageEventsTable";
4
- import en from "../../messages/en";
5
4
 
6
5
  describe("<LineageEventsTable />", () => {
7
6
  const lineageEvents = [
@@ -19,9 +18,7 @@ describe("<LineageEventsTable />", () => {
19
18
 
20
19
  it("matches the latest snapshot", () => {
21
20
  const props = { fetchLineageEvents, lineageEvents, lineageEventsLoading };
22
- const { container } = render(<LineageEventsTable {...props} />, {
23
- messages: { en },
24
- });
21
+ const { container } = render(<LineageEventsTable {...props} />);
25
22
  expect(container).toMatchSnapshot();
26
23
  });
27
24
 
@@ -31,9 +28,7 @@ describe("<LineageEventsTable />", () => {
31
28
  lineageEvents: [],
32
29
  lineageEventsLoading,
33
30
  };
34
- const { container } = render(<LineageEventsTable {...props} />, {
35
- messages: { en },
36
- });
31
+ const { container } = render(<LineageEventsTable {...props} />);
37
32
  expect(container).toMatchSnapshot();
38
33
  });
39
34
  });
@@ -1,14 +1,14 @@
1
1
  import React from "react";
2
- import { shallowWithIntl } from "@truedat/test/intl-stub";
2
+ import { render } from "@truedat/test/render";
3
3
  import { LineageRoutes } from "../LineageRoutes";
4
4
 
5
5
  jest.mock("@truedat/core/hooks", () => ({
6
- useAuthorized: jest.fn(() => true)
6
+ useAuthorized: jest.fn(() => true),
7
7
  }));
8
8
 
9
9
  describe("<LineageRoutes />", () => {
10
10
  it("matches the latest snapshot", () => {
11
- const wrapper = shallowWithIntl(<LineageRoutes />);
12
- expect(wrapper).toMatchSnapshot();
11
+ const { container } = render(<LineageRoutes />);
12
+ expect(container).toMatchSnapshot();
13
13
  });
14
14
  });