@truedat/dd 5.9.3 → 5.9.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.
- package/package.json +8 -7
- package/src/__mocks__/fileMock.js +1 -0
- package/src/api/queries.js +1 -2
- package/src/components/BucketView.js +42 -7
- package/src/components/CatalogCustomViewCards.js +10 -1
- package/src/components/StructureCrumbs.js +21 -7
- package/src/components/StructureItem.js +10 -1
- package/src/components/StructureView.js +1 -3
- package/src/components/StructuresView.js +29 -12
- package/src/components/SystemStructures.js +14 -9
- package/src/components/__tests__/BucketView.spec.js +7 -0
- package/src/messages/en.js +2 -0
- package/src/messages/es.js +2 -0
- package/src/selectors/__tests__/getSystem.spec.js +1 -1
- package/src/selectors/getStructureParent.js +1 -1
- package/src/selectors/getSystem.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "5.9.
|
|
3
|
+
"version": "5.9.5",
|
|
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.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "5.9.
|
|
37
|
+
"@truedat/test": "5.9.5",
|
|
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",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"@truedat/test/setup"
|
|
63
63
|
],
|
|
64
64
|
"moduleNameMapper": {
|
|
65
|
-
"\\.(css|less
|
|
65
|
+
"\\.(css|less)$": "identity-obj-proxy",
|
|
66
|
+
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
|
|
66
67
|
"^@truedat/([^/]+)$": "<rootDir>/../$1/src/index",
|
|
67
68
|
"^@truedat/([^/]+)/(.*)$": "<rootDir>/../$1/src/$2"
|
|
68
69
|
},
|
|
@@ -87,9 +88,9 @@
|
|
|
87
88
|
},
|
|
88
89
|
"dependencies": {
|
|
89
90
|
"@apollo/client": "^3.7.1",
|
|
90
|
-
"@truedat/auth": "5.9.
|
|
91
|
-
"@truedat/core": "5.9.
|
|
92
|
-
"@truedat/df": "5.9.
|
|
91
|
+
"@truedat/auth": "5.9.5",
|
|
92
|
+
"@truedat/core": "5.9.5",
|
|
93
|
+
"@truedat/df": "5.9.5",
|
|
93
94
|
"lodash": "^4.17.21",
|
|
94
95
|
"moment": "^2.29.4",
|
|
95
96
|
"path-to-regexp": "^1.7.0",
|
|
@@ -114,5 +115,5 @@
|
|
|
114
115
|
"react-dom": ">= 16.8.6 < 17",
|
|
115
116
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
116
117
|
},
|
|
117
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "e5921f6b5e5a2142ac6be90ad269d5e1fecb1e2c"
|
|
118
119
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = "test-file-stub";
|
package/src/api/queries.js
CHANGED
|
@@ -382,7 +382,7 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
382
382
|
min
|
|
383
383
|
null_count
|
|
384
384
|
most_frequent
|
|
385
|
-
|
|
385
|
+
total_count
|
|
386
386
|
}
|
|
387
387
|
source {
|
|
388
388
|
id
|
|
@@ -428,7 +428,6 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
428
428
|
patterns
|
|
429
429
|
total_count
|
|
430
430
|
unique_count
|
|
431
|
-
value
|
|
432
431
|
}
|
|
433
432
|
note(select_fields: $note_fields)
|
|
434
433
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React, { useEffect } from "react";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import { Grid, Segment } from "semantic-ui-react";
|
|
5
|
+
import { Grid, Header, Image, Segment } from "semantic-ui-react";
|
|
6
6
|
import { useParams, useLocation } from "react-router-dom";
|
|
7
|
+
import searchImage from "assets/searching.png";
|
|
8
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
7
9
|
import { saveNavFilter as saveNavFilterRoutine } from "../routines";
|
|
8
10
|
import FilteredNav from "./FilteredNav";
|
|
9
11
|
import StructureCrumbs from "./StructureCrumbs";
|
|
@@ -18,6 +20,20 @@ const isBucketFilter = _.flow(
|
|
|
18
20
|
_.any((entry) => entry.startsWith("metadata", "note"))
|
|
19
21
|
);
|
|
20
22
|
|
|
23
|
+
const EmptyImage = () => (
|
|
24
|
+
<div
|
|
25
|
+
style={{
|
|
26
|
+
textAlign: "center",
|
|
27
|
+
paddingBottom: "100px",
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
<Image className="search" src={searchImage} />
|
|
31
|
+
<span className="system-structures-search__text">
|
|
32
|
+
<FormattedMessage id="sytems.structures.select_message" />
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
|
|
21
37
|
export const BucketView = ({
|
|
22
38
|
showGrantRequestCart,
|
|
23
39
|
saveNavFilter,
|
|
@@ -26,13 +42,20 @@ export const BucketView = ({
|
|
|
26
42
|
const params = useParams();
|
|
27
43
|
const { id: structureId } = params;
|
|
28
44
|
const location = useLocation();
|
|
45
|
+
const [navFilterOneProp, setNavFilterOneProp] = useState({});
|
|
46
|
+
const { formatMessage } = useIntl();
|
|
47
|
+
|
|
48
|
+
const getNavFilterURLParams = _.flow(
|
|
49
|
+
_.path("search"),
|
|
50
|
+
(search) => new URLSearchParams(search).entries(),
|
|
51
|
+
(entries) => Object.fromEntries(entries),
|
|
52
|
+
_.pick(["propertyPath", "propertyValue"])
|
|
53
|
+
);
|
|
29
54
|
|
|
30
55
|
useEffect(() => {
|
|
56
|
+
_.flow(getNavFilterURLParams, setNavFilterOneProp)(location);
|
|
31
57
|
_.flow(
|
|
32
|
-
|
|
33
|
-
(search) => new URLSearchParams(search).entries(),
|
|
34
|
-
(entries) => Object.fromEntries(entries),
|
|
35
|
-
_.pick(["propertyPath", "propertyValue"]),
|
|
58
|
+
getNavFilterURLParams,
|
|
36
59
|
_.values,
|
|
37
60
|
(keyValue) => Object.fromEntries(new Map([keyValue]).entries()),
|
|
38
61
|
saveNavFilter
|
|
@@ -64,7 +87,19 @@ export const BucketView = ({
|
|
|
64
87
|
<StructureTabPaneRoutes />
|
|
65
88
|
</>
|
|
66
89
|
) : (
|
|
67
|
-
|
|
90
|
+
<>
|
|
91
|
+
<Header as="h1">
|
|
92
|
+
<FormattedMessage id="bucketView.header" />
|
|
93
|
+
</Header>
|
|
94
|
+
<Header as="h2">
|
|
95
|
+
{navFilterOneProp?.propertyPath
|
|
96
|
+
? `${formatMessage({
|
|
97
|
+
id: navFilterOneProp.propertyPath,
|
|
98
|
+
})} > ${navFilterOneProp?.propertyValue}`
|
|
99
|
+
: null}
|
|
100
|
+
</Header>
|
|
101
|
+
<EmptyImage />
|
|
102
|
+
</>
|
|
68
103
|
)}
|
|
69
104
|
</Segment>
|
|
70
105
|
</Grid.Column>
|
|
@@ -9,6 +9,15 @@ import { FormattedNumber } from "react-intl";
|
|
|
9
9
|
import { CardGroupsAccordion } from "@truedat/core/components";
|
|
10
10
|
import { linkTo } from "@truedat/core/routes";
|
|
11
11
|
|
|
12
|
+
const moveMissingBucketToTheEnd = (buckets) =>
|
|
13
|
+
_.sortBy(({ key }) => (key === "_missing" ? 1 : 0))(buckets);
|
|
14
|
+
|
|
15
|
+
const orderBuckets = (buckets) =>
|
|
16
|
+
_.flow(
|
|
17
|
+
_.orderBy([({ key }) => key.toLowerCase()], ["asc"]),
|
|
18
|
+
moveMissingBucketToTheEnd
|
|
19
|
+
)(buckets);
|
|
20
|
+
|
|
12
21
|
export const CatalogCustomViewCards = ({ structureFilters }) => {
|
|
13
22
|
const { propertyPath } = useParams();
|
|
14
23
|
const groups = [];
|
|
@@ -27,7 +36,7 @@ export const CatalogCustomViewCards = ({ structureFilters }) => {
|
|
|
27
36
|
name={name}
|
|
28
37
|
structures_count={structures_count}
|
|
29
38
|
/>
|
|
30
|
-
))(structureFilters[propertyPath]?.buckets)}
|
|
39
|
+
))(orderBuckets(structureFilters[propertyPath]?.buckets))}
|
|
31
40
|
</Card.Group>
|
|
32
41
|
);
|
|
33
42
|
};
|
|
@@ -27,6 +27,9 @@ const filterQueryParams = _.flow(
|
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
export const SystemCrumb = ({ id, name, navFilter }) => {
|
|
30
|
+
const [propertyPath, propertyValue] = !_.isEmpty(navFilter)
|
|
31
|
+
? _.toPairs(navFilter)[0]
|
|
32
|
+
: [null, null];
|
|
30
33
|
return (
|
|
31
34
|
<>
|
|
32
35
|
{_.isEmpty(navFilter) || navFilter?.system_id ? (
|
|
@@ -38,13 +41,23 @@ export const SystemCrumb = ({ id, name, navFilter }) => {
|
|
|
38
41
|
{name}
|
|
39
42
|
</Breadcrumb.Section>
|
|
40
43
|
) : (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
<>
|
|
45
|
+
<Breadcrumb.Section
|
|
46
|
+
as={Link}
|
|
47
|
+
to={`${linkTo.BUCKETS_VIEW({ propertyPath })}`}
|
|
48
|
+
active={false}
|
|
49
|
+
>
|
|
50
|
+
<FormattedMessage id={propertyPath} />
|
|
51
|
+
</Breadcrumb.Section>
|
|
52
|
+
<Breadcrumb.Divider icon="right angle" />
|
|
53
|
+
<Breadcrumb.Section
|
|
54
|
+
as={Link}
|
|
55
|
+
to={`${linkTo.BUCKET_VIEW()}?${filterQueryParams(navFilter)}`}
|
|
56
|
+
active={false}
|
|
57
|
+
>
|
|
58
|
+
{propertyValue}
|
|
59
|
+
</Breadcrumb.Section>
|
|
60
|
+
</>
|
|
48
61
|
)}
|
|
49
62
|
<Breadcrumb.Divider icon="right angle" />
|
|
50
63
|
</>
|
|
@@ -53,6 +66,7 @@ export const SystemCrumb = ({ id, name, navFilter }) => {
|
|
|
53
66
|
|
|
54
67
|
SystemCrumb.propTypes = {
|
|
55
68
|
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
69
|
+
navFilter: PropTypes.object,
|
|
56
70
|
name: PropTypes.string,
|
|
57
71
|
};
|
|
58
72
|
|
|
@@ -23,6 +23,11 @@ const filterQueryParams = _.flow(
|
|
|
23
23
|
(queryParams) => new URLSearchParams(queryParams)
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
+
const bucketToBreadcrumbs = ({ navFilter, formatMessage }) => {
|
|
27
|
+
const [propertyPath, propertyValue] = _.toPairs(navFilter)[0];
|
|
28
|
+
return `${formatMessage({ id: propertyPath })} > ${propertyValue}`;
|
|
29
|
+
};
|
|
30
|
+
|
|
26
31
|
export const StructureItem = ({
|
|
27
32
|
name,
|
|
28
33
|
id,
|
|
@@ -53,7 +58,11 @@ export const StructureItem = ({
|
|
|
53
58
|
>
|
|
54
59
|
<List.Icon name={getIcon(formatMessage, type)} verticalAlign="middle" />
|
|
55
60
|
<List.Content>
|
|
56
|
-
<List.Description>
|
|
61
|
+
<List.Description>
|
|
62
|
+
{type == "bucket"
|
|
63
|
+
? bucketToBreadcrumbs({ navFilter, formatMessage })
|
|
64
|
+
: name}
|
|
65
|
+
</List.Description>
|
|
57
66
|
</List.Content>
|
|
58
67
|
</List.Item>
|
|
59
68
|
);
|
|
@@ -2,10 +2,11 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import { useHistory } from "react-router-dom";
|
|
5
|
+
import { useHistory, useRouteMatch } from "react-router-dom";
|
|
6
6
|
import { Header, Icon, Segment, Divider } from "semantic-ui-react";
|
|
7
7
|
import { FormattedMessage } from "react-intl";
|
|
8
8
|
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
import { BUCKETS_VIEW } from "@truedat/core/routes";
|
|
9
10
|
import { structureRowsSelector } from "../selectors";
|
|
10
11
|
import StructureSelectedFilters from "./StructureSelectedFilters";
|
|
11
12
|
import StructuresOptions from "./StructuresOptions";
|
|
@@ -15,17 +16,33 @@ import StructuresSearchResults from "./StructuresSearchResults";
|
|
|
15
16
|
import SystemCards from "./SystemCards";
|
|
16
17
|
import CatalogCustomViewCards from "./CatalogCustomViewCards";
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
const StructuresHeader = () => {
|
|
20
|
+
const match = useRouteMatch(BUCKETS_VIEW);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Header as="h2">
|
|
24
|
+
<Icon circular name="block layout" />
|
|
25
|
+
<Header.Content>
|
|
26
|
+
<FormattedMessage
|
|
27
|
+
id={
|
|
28
|
+
!match?.params?.propertyPath
|
|
29
|
+
? "structures.header"
|
|
30
|
+
: "bucketsView.header"
|
|
31
|
+
}
|
|
32
|
+
/>
|
|
33
|
+
<Header.Subheader>
|
|
34
|
+
<FormattedMessage
|
|
35
|
+
id={
|
|
36
|
+
!match?.params?.propertyPath
|
|
37
|
+
? "structures.subheader"
|
|
38
|
+
: match?.params?.propertyPath
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
</Header.Subheader>
|
|
42
|
+
</Header.Content>
|
|
43
|
+
</Header>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
29
46
|
|
|
30
47
|
const StructuresViewContent = ({
|
|
31
48
|
actions = {},
|
|
@@ -4,6 +4,7 @@ import PropTypes from "prop-types";
|
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
5
|
import { Grid, Segment } from "semantic-ui-react";
|
|
6
6
|
import { useParams } from "react-router-dom";
|
|
7
|
+
import { withRouter } from "react-router-dom";
|
|
7
8
|
import { getSystem, getSystemTemplate } from "../selectors";
|
|
8
9
|
import { saveNavFilter as saveNavFilterRoutine } from "../routines";
|
|
9
10
|
import FilteredNav from "./FilteredNav";
|
|
@@ -54,13 +55,17 @@ SystemStructures.propTypes = {
|
|
|
54
55
|
systemTemplate: PropTypes.object,
|
|
55
56
|
};
|
|
56
57
|
|
|
57
|
-
const mapStateToProps = (state) =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
const mapStateToProps = (state, props) => {
|
|
59
|
+
return {
|
|
60
|
+
navFilter: state?.navFilter,
|
|
61
|
+
system: getSystem(state, props.match.params.id),
|
|
62
|
+
systemStructuresLoading: _.prop("systemStructuresLoading")(state),
|
|
63
|
+
systemTemplate: getSystemTemplate(state),
|
|
64
|
+
};
|
|
65
|
+
};
|
|
63
66
|
|
|
64
|
-
export default
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
export default withRouter(
|
|
68
|
+
connect(mapStateToProps, {
|
|
69
|
+
saveNavFilter: saveNavFilterRoutine,
|
|
70
|
+
})(SystemStructures)
|
|
71
|
+
);
|
|
@@ -3,6 +3,7 @@ import { render } from "@truedat/test/render";
|
|
|
3
3
|
import { waitFor } from "@testing-library/react";
|
|
4
4
|
import { MemoryRouter } from "react-router-dom";
|
|
5
5
|
import { BucketView } from "../BucketView";
|
|
6
|
+
import en from "../../messages/en";
|
|
6
7
|
|
|
7
8
|
const state = {
|
|
8
9
|
authentication: { role: "admin" },
|
|
@@ -24,6 +25,12 @@ describe("<BucketView />", () => {
|
|
|
24
25
|
const navFilter = {};
|
|
25
26
|
const renderOpts = {
|
|
26
27
|
state,
|
|
28
|
+
messages: {
|
|
29
|
+
en: {
|
|
30
|
+
...en,
|
|
31
|
+
"metadata.region": "metadata.region",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
render(
|
package/src/messages/en.js
CHANGED
|
@@ -9,6 +9,8 @@ export default {
|
|
|
9
9
|
"alert.updateReferenceDataset.success.header": "Dataset updated",
|
|
10
10
|
"alert.updateTag.failed.header": "Error editing structure tag",
|
|
11
11
|
"alert.updateSystem.failed.header": "Error updating system",
|
|
12
|
+
"bucketView.header": "Catalog view",
|
|
13
|
+
"bucketsView.header": "Catalog views",
|
|
12
14
|
"createTag.error.name.has already been taken":
|
|
13
15
|
"A Structure Tag with this name already exists",
|
|
14
16
|
"execution.pending.content":
|
package/src/messages/es.js
CHANGED
|
@@ -11,6 +11,8 @@ export default {
|
|
|
11
11
|
"Dataset actualizado correctamente",
|
|
12
12
|
"alert.updateTag.failed.header": "Error al editar Etiqueta",
|
|
13
13
|
"alert.updateSystem.failed.header": "Error actualizando sistema",
|
|
14
|
+
"bucketView.header": "Catalog view",
|
|
15
|
+
"bucketsView.header": "Catalog views",
|
|
14
16
|
"createTag.error.name.has already been taken":
|
|
15
17
|
"Ya existe una Etiqueta de Estructura con ese nombre",
|
|
16
18
|
"execution.pending.content":
|
|
@@ -29,7 +29,7 @@ export const getStructureParent = createSelector(
|
|
|
29
29
|
(structure, structureParents, navFilter) =>
|
|
30
30
|
_.isEmpty(structureParents)
|
|
31
31
|
? !_.isEmpty(structure) && isBucketFilter(navFilter)
|
|
32
|
-
? { type: "bucket"
|
|
32
|
+
? { type: "bucket" }
|
|
33
33
|
: _.has("system")(structure)
|
|
34
34
|
? rootNavItem(structure)
|
|
35
35
|
: {}
|
|
@@ -2,6 +2,6 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import { createSelector } from "reselect";
|
|
3
3
|
|
|
4
4
|
export const getSystem = createSelector(
|
|
5
|
-
[
|
|
6
|
-
(systems, systemId) => _.find(
|
|
5
|
+
[(state) => state?.systems, (_, systemId) => systemId],
|
|
6
|
+
(systems, systemId) => _.find(({ id }) => id == systemId)(systems)
|
|
7
7
|
);
|