@truedat/dd 4.44.3 → 4.45.0
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 +10 -0
- package/package.json +24 -20
- package/src/api/mutations.js +27 -0
- package/src/api/queries.js +24 -0
- package/src/api.js +2 -0
- package/src/components/DictionaryRoutes.js +7 -5
- package/src/components/EditDomainPopup.js +1 -1
- package/src/components/FilteredNav.js +9 -9
- package/src/components/GrantFilters.js +1 -5
- package/src/components/GrantRequestApprovalPopup.js +0 -1
- package/src/components/PendingStructureNotes.js +1 -1
- package/src/components/ReferenceDataset.js +23 -0
- package/src/components/ReferenceDatasetActions.js +88 -0
- package/src/components/ReferenceDatasetBreadcrumbs.js +22 -0
- package/src/components/ReferenceDatasetCreate.js +36 -0
- package/src/components/ReferenceDatasetDetail.js +42 -0
- package/src/components/ReferenceDatasetForm.js +109 -0
- package/src/components/ReferenceDatasetHeader.js +32 -0
- package/src/components/ReferenceDatasetRoutes.js +56 -0
- package/src/components/ReferenceDatasetTable.js +42 -0
- package/src/components/ReferenceDatasets.js +61 -0
- package/src/components/ReferenceDatasetsTable.js +105 -0
- package/src/components/StructureConfidentialButton.js +1 -1
- package/src/components/StructureFilters.js +1 -5
- package/src/components/StructureNotesEdit.js +6 -6
- package/src/components/StructureProperties.js +4 -1
- package/src/components/StructureTabPane.js +4 -2
- package/src/components/StructureTagsRoutes.js +0 -1
- package/src/components/StructureTypesCrumbs.js +0 -1
- package/src/components/StructureVersionListItem.js +2 -2
- package/src/components/StructureView.js +1 -3
- package/src/components/SystemForm.js +1 -1
- package/src/components/__tests__/LineageRoutes.spec.js +4 -4
- package/src/components/__tests__/ReferenceDataset.spec.js +64 -0
- package/src/components/__tests__/ReferenceDatasetActions.spec.js +17 -0
- package/src/components/__tests__/ReferenceDatasetBreadcrumbs.spec.js +12 -0
- package/src/components/__tests__/ReferenceDatasetCreate.spec.js +12 -0
- package/src/components/__tests__/ReferenceDatasetDetail.spec.js +37 -0
- package/src/components/__tests__/ReferenceDatasetForm.spec.js +51 -0
- package/src/components/__tests__/ReferenceDatasetHeader.spec.js +17 -0
- package/src/components/__tests__/ReferenceDatasetRoutes.spec.js +74 -0
- package/src/components/__tests__/ReferenceDatasetTable.spec.js +18 -0
- package/src/components/__tests__/ReferenceDatasets.spec.js +32 -0
- package/src/components/__tests__/ReferenceDatasetsTable.spec.js +22 -0
- package/src/components/__tests__/StructureConfidentialButton.spec.js +26 -30
- package/src/components/__tests__/StructureNotesEdit.spec.js +2 -9
- package/src/components/__tests__/StructureProperties.spec.js +6 -8
- package/src/components/__tests__/StructureVersionListItem.spec.js +4 -4
- package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +4 -0
- package/src/components/__tests__/__snapshots__/LineageRoutes.spec.js.snap +1 -20
- package/src/components/__tests__/__snapshots__/ProfileExecution.spec.js.snap +2 -1
- package/src/components/__tests__/__snapshots__/ReferenceDataset.spec.js.snap +365 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetActions.spec.js.snap +65 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetBreadcrumbs.spec.js.snap +25 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetCreate.spec.js.snap +98 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetDetail.spec.js.snap +135 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetForm.spec.js.snap +61 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetHeader.spec.js.snap +95 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetRoutes.spec.js.snap +414 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetTable.spec.js.snap +75 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasets.spec.js.snap +128 -0
- package/src/components/__tests__/__snapshots__/ReferenceDatasetsTable.spec.js.snap +86 -0
- package/src/components/__tests__/__snapshots__/StructureConfidentialButton.spec.js.snap +13 -33
- package/src/components/__tests__/__snapshots__/StructureProperties.spec.js.snap +76 -71
- package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/StructureVersionListItem.spec.js.snap +31 -64
- package/src/components/index.js +0 -6
- package/src/messages/en.js +18 -0
- package/src/messages/es.js +20 -0
- package/src/reducers/__tests__/ddMessage.spec.js +26 -5
- package/src/reducers/__tests__/graph.spec.js +1 -6
- package/src/reducers/__tests__/referenceDatasetSaving.spec.js +44 -0
- package/src/reducers/__tests__/structureRedirect.spec.js +37 -13
- package/src/reducers/ddMessage.js +26 -1
- package/src/reducers/index.js +2 -0
- package/src/reducers/referenceDatasetSaving.js +16 -0
- package/src/reducers/structureRedirect.js +36 -15
- package/src/reducers/structuresUploadEvents.js +0 -1
- package/src/routines.js +35 -74
- package/src/sagas/__tests__/createReferenceDataset.spec.js +90 -0
- package/src/sagas/__tests__/deleteReferenceDataset.spec.js +81 -0
- package/src/sagas/__tests__/updateReferenceDataset.spec.js +116 -0
- package/src/sagas/createReferenceDataset.js +34 -0
- package/src/sagas/deleteReferenceDataset.js +29 -0
- package/src/sagas/downloadReferenceDataset.js +44 -0
- package/src/sagas/index.js +31 -22
- package/src/sagas/updateReferenceDataset.js +35 -0
- package/src/selectors/getRelationSortingCriteria.js +3 -5
- package/src/selectors/getTabVisibility.js +1 -4
- package/src/components/ProfilingElements.js +0 -89
- package/src/components/ProfilingGraph.js +0 -89
- package/src/components/ProfilingPatterns.js +0 -57
- package/src/components/StructureProfiling.js +0 -124
- package/src/components/__tests__/StructureProfiling.spec.js +0 -45
- package/src/components/__tests__/__snapshots__/StructureProfiling.spec.js.snap +0 -444
|
@@ -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
|
|
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,
|
|
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
|
-
|
|
27
|
+
selectDomains,
|
|
28
28
|
structureNotes,
|
|
29
29
|
latestDfContent,
|
|
30
30
|
}) => {
|
|
31
31
|
const [content, setContent] = useState(latestDfContent);
|
|
32
32
|
|
|
33
33
|
useEffect(() => {
|
|
34
|
-
|
|
34
|
+
selectDomains(structure.domain_ids);
|
|
35
35
|
if (template) selectTemplate(template);
|
|
36
|
-
}, [template, structure, selectTemplate,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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)}
|
|
@@ -18,7 +18,6 @@ import StructureLineage from "./StructureLineage";
|
|
|
18
18
|
import StructureNotes from "./StructureNotes";
|
|
19
19
|
import StructureNotesEdit from "./StructureNotesEdit";
|
|
20
20
|
import StructureParentRelations from "./StructureParentRelations";
|
|
21
|
-
import StructureProfiling from "./StructureProfiling";
|
|
22
21
|
import StructureVersions from "./StructureVersions";
|
|
23
22
|
import StructureMetadata from "./StructureMetadata";
|
|
24
23
|
import StructureNotesLoader from "./StructureNotesLoader";
|
|
@@ -26,6 +25,9 @@ import StructureNotesLoader from "./StructureNotesLoader";
|
|
|
26
25
|
const StructureLinks = React.lazy(() =>
|
|
27
26
|
import("@truedat/lm/components/StructureLinks")
|
|
28
27
|
);
|
|
28
|
+
|
|
29
|
+
const StructureProfile = React.lazy(() => import("@truedat/profile"));
|
|
30
|
+
|
|
29
31
|
const StructureRelationForm = React.lazy(() =>
|
|
30
32
|
import("@truedat/lm/components/StructureRelationForm")
|
|
31
33
|
);
|
|
@@ -59,7 +61,7 @@ export const StructureTabPane = ({ activeTab, tabVisibility }) => (
|
|
|
59
61
|
<Route render={() => <StructureLinks />} />
|
|
60
62
|
</Switch>
|
|
61
63
|
)}
|
|
62
|
-
{activeTab === "profile" && tabVisibility.profile && <
|
|
64
|
+
{activeTab === "profile" && tabVisibility.profile && <StructureProfile />}
|
|
63
65
|
{activeTab === "parents" && <StructureParentRelations />}
|
|
64
66
|
{activeTab === "children" && <StructureChildrenRelations />}
|
|
65
67
|
{activeTab === "versions" && <StructureVersions />}
|
|
@@ -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
|
|
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,14 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
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
|
|
12
|
-
expect(
|
|
11
|
+
const { container } = render(<LineageRoutes />);
|
|
12
|
+
expect(container).toMatchSnapshot();
|
|
13
13
|
});
|
|
14
14
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import { render } from "@truedat/test/render";
|
|
5
|
+
import ReferenceDataset from "../ReferenceDataset";
|
|
6
|
+
|
|
7
|
+
const dataset = {
|
|
8
|
+
id: "123",
|
|
9
|
+
name: "foo",
|
|
10
|
+
headers: ["foo", "bar", "baz"],
|
|
11
|
+
rows: [
|
|
12
|
+
["foo1", "bar1", "baz1"],
|
|
13
|
+
["foo2", "bar2", "baz2"],
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("<ReferenceDataset /> show dataset view", () => {
|
|
18
|
+
const renderOpts = { routes: ["/referenceDatasets/123"] };
|
|
19
|
+
const props = { dataset };
|
|
20
|
+
|
|
21
|
+
it("matches the latest snapshot", () => {
|
|
22
|
+
const { container } = render(<ReferenceDataset {...props} />, renderOpts);
|
|
23
|
+
expect(container).toMatchSnapshot();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("contains the right number of rows", () => {
|
|
27
|
+
const { queryAllByRole } = render(
|
|
28
|
+
<ReferenceDataset {...props} />,
|
|
29
|
+
renderOpts
|
|
30
|
+
);
|
|
31
|
+
expect(queryAllByRole("row")).toHaveLength(3);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("<ReferenceDataset /> edit dataset view", () => {
|
|
36
|
+
const renderOpts = { routes: ["/referenceDatasets/123/edit"] };
|
|
37
|
+
const props = { dataset };
|
|
38
|
+
|
|
39
|
+
it("matches the latest snapshot", async () => {
|
|
40
|
+
const { container, findByText } = render(
|
|
41
|
+
<ReferenceDataset {...props} />,
|
|
42
|
+
renderOpts
|
|
43
|
+
);
|
|
44
|
+
await findByText("Save");
|
|
45
|
+
expect(container).toMatchSnapshot();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("form is disabled until modified", async () => {
|
|
49
|
+
const { findByText, findByRole, getByRole, queryByRole } = render(
|
|
50
|
+
<ReferenceDataset {...props} />,
|
|
51
|
+
renderOpts
|
|
52
|
+
);
|
|
53
|
+
await findByText("Save");
|
|
54
|
+
|
|
55
|
+
// Form is disabled until modified
|
|
56
|
+
expect(queryByRole("button", { name: /Save/ })).toBeDisabled();
|
|
57
|
+
userEvent.type(await findByRole("textbox"), "bar");
|
|
58
|
+
|
|
59
|
+
// Form is now enabled
|
|
60
|
+
await waitFor(() =>
|
|
61
|
+
expect(getByRole("button", { name: /Save/ })).not.toBeDisabled()
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ReferenceDatasetActions from "../ReferenceDatasetActions";
|
|
4
|
+
|
|
5
|
+
const dataset = {
|
|
6
|
+
id: "123",
|
|
7
|
+
name: "foo",
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe("<ReferenceDatasetActions />", () => {
|
|
11
|
+
const props = { dataset };
|
|
12
|
+
|
|
13
|
+
it("matches the latest snapshot", () => {
|
|
14
|
+
const { container } = render(<ReferenceDatasetActions {...props} />);
|
|
15
|
+
expect(container).toMatchSnapshot();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ReferenceDatasetBreadcrumbs from "../ReferenceDatasetBreadcrumbs";
|
|
4
|
+
|
|
5
|
+
describe("<ReferenceDatasetBreadcrumbs />", () => {
|
|
6
|
+
const props = { text: "foo" };
|
|
7
|
+
|
|
8
|
+
it("matches the latest snapshot", () => {
|
|
9
|
+
const { container } = render(<ReferenceDatasetBreadcrumbs {...props} />);
|
|
10
|
+
expect(container).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ReferenceDatasetCreate from "../ReferenceDatasetCreate";
|
|
4
|
+
|
|
5
|
+
describe("<ReferenceDatasetCreate />", () => {
|
|
6
|
+
const props = { createReferenceDataset: jest.fn() };
|
|
7
|
+
|
|
8
|
+
it("matches the latest snapshot", () => {
|
|
9
|
+
const { container } = render(<ReferenceDatasetCreate {...props} />);
|
|
10
|
+
expect(container).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ReferenceDatasetDetail from "../ReferenceDatasetDetail";
|
|
4
|
+
|
|
5
|
+
const dataset = {
|
|
6
|
+
id: "123",
|
|
7
|
+
name: "foo",
|
|
8
|
+
headers: ["foo", "bar", "baz"],
|
|
9
|
+
rows: [
|
|
10
|
+
["foo1", "bar1", "baz1"],
|
|
11
|
+
["foo2", "bar2", "baz2"],
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe("<ReferenceDatasetDetail />", () => {
|
|
16
|
+
const props = { dataset };
|
|
17
|
+
|
|
18
|
+
it("matches the latest snapshot (edit route)", async () => {
|
|
19
|
+
const renderOpts = { routes: ["/referenceDatasets/123/edit"] };
|
|
20
|
+
const { container, findByRole } = render(
|
|
21
|
+
<ReferenceDatasetDetail {...props} />,
|
|
22
|
+
renderOpts
|
|
23
|
+
);
|
|
24
|
+
await findByRole("button", { name: "Save" });
|
|
25
|
+
expect(container).toMatchSnapshot();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("matches the latest snapshot (view route)", async () => {
|
|
29
|
+
const renderOpts = { routes: ["/referenceDatasets/123"] };
|
|
30
|
+
const { container, findByText } = render(
|
|
31
|
+
<ReferenceDatasetDetail {...props} />,
|
|
32
|
+
renderOpts
|
|
33
|
+
);
|
|
34
|
+
await findByText("foo");
|
|
35
|
+
expect(container).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import { render } from "@truedat/test/render";
|
|
5
|
+
import ReferenceDatasetForm from "../ReferenceDatasetForm";
|
|
6
|
+
|
|
7
|
+
const dataset = {
|
|
8
|
+
id: "123",
|
|
9
|
+
name: "foo",
|
|
10
|
+
headers: ["foo", "bar", "baz"],
|
|
11
|
+
rows: [
|
|
12
|
+
["foo1", "bar1", "baz1"],
|
|
13
|
+
["foo2", "bar2", "baz2"],
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("<ReferenceDatasetForm />", () => {
|
|
18
|
+
const onSubmit = jest.fn();
|
|
19
|
+
const props = { dataset, onSubmit };
|
|
20
|
+
|
|
21
|
+
it("matches the latest snapshot", async () => {
|
|
22
|
+
const { container, findByText } = render(
|
|
23
|
+
<ReferenceDatasetForm {...props} />
|
|
24
|
+
);
|
|
25
|
+
await findByText("Save");
|
|
26
|
+
expect(container).toMatchSnapshot();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("form is disabled until modified", async () => {
|
|
30
|
+
const { findByText, findByRole, getByRole, queryByRole } = render(
|
|
31
|
+
<ReferenceDatasetForm {...props} />
|
|
32
|
+
);
|
|
33
|
+
await findByText("Save");
|
|
34
|
+
|
|
35
|
+
// Form is disabled until modified
|
|
36
|
+
expect(queryByRole("button", { name: /Save/ })).toBeDisabled();
|
|
37
|
+
userEvent.type(await findByRole("textbox"), "bar");
|
|
38
|
+
|
|
39
|
+
// Form is now enabled
|
|
40
|
+
await waitFor(() =>
|
|
41
|
+
expect(getByRole("button", { name: /Save/ })).not.toBeDisabled()
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Submit
|
|
45
|
+
await waitFor(() => {
|
|
46
|
+
userEvent.click(getByRole("button", { name: /Save/ }));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(onSubmit).toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import ReferenceDatasetHeader from "../ReferenceDatasetHeader";
|
|
4
|
+
|
|
5
|
+
const dataset = {
|
|
6
|
+
id: "123",
|
|
7
|
+
name: "foo",
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe("<ReferenceDatasetHeader />", () => {
|
|
11
|
+
const props = { dataset };
|
|
12
|
+
|
|
13
|
+
it("matches the latest snapshot", () => {
|
|
14
|
+
const { container } = render(<ReferenceDatasetHeader {...props} />);
|
|
15
|
+
expect(container).toMatchSnapshot();
|
|
16
|
+
});
|
|
17
|
+
});
|