@truedat/dd 5.9.1 → 5.9.3
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 +6 -6
- package/src/api/mutations.js +28 -0
- package/src/api/queries.js +20 -0
- package/src/api.js +4 -0
- package/src/components/BucketView.js +92 -0
- package/src/components/CatalogCustomViewCards.js +89 -0
- package/src/components/CatalogViewConfigForm.js +130 -0
- package/src/components/CatalogViewConfigs.js +124 -0
- package/src/components/DictionaryRoutes.js +40 -9
- package/src/components/FilteredNav.js +47 -5
- package/src/components/StructureCrumbs.js +43 -15
- package/src/components/StructureItem.js +24 -2
- package/src/components/StructureItemRoot.js +34 -5
- package/src/components/StructureItems.js +3 -2
- package/src/components/StructureNav.js +1 -1
- package/src/components/StructureTabs.js +104 -102
- package/src/components/StructureTags.js +2 -2
- package/src/components/StructureView.js +56 -37
- package/src/components/StructuresRoutes.js +57 -49
- package/src/components/StructuresView.js +5 -0
- package/src/components/SystemCards.js +1 -0
- package/src/components/SystemFilteredNav.js +1 -1
- package/src/components/SystemStructures.js +40 -22
- package/src/components/SystemsRoutes.js +3 -3
- package/src/components/__tests__/BucketView.spec.js +49 -0
- package/src/components/__tests__/CatalogCustomViewCards.spec.js +56 -0
- package/src/components/__tests__/CatalogViewConfigForm.spec.js +75 -0
- package/src/components/__tests__/CatalogViewConfigs.spec.js +75 -0
- package/src/components/__tests__/FilteredNav.spec.js +73 -22
- package/src/components/__tests__/GrantApprovalRuleDeleteButton.spec.js +2 -2
- package/src/components/__tests__/StructureItemRoot.spec.js +5 -4
- package/src/components/__tests__/StructureNav.spec.js +3 -0
- package/src/components/__tests__/StructureStructureLinks.spec.js +1 -1
- package/src/components/__tests__/StructureView.spec.js +60 -12
- package/src/components/__tests__/StructuresView.spec.js +60 -15
- package/src/components/__tests__/SystemFilteredNav.spec.js +7 -1
- package/src/components/__tests__/SystemStructures.spec.js +5 -0
- package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +21 -1
- package/src/components/__tests__/__snapshots__/StructureCrumbs.spec.js.snap +4 -4
- package/src/components/__tests__/__snapshots__/StructuresRoutes.spec.js.snap +7 -1
- package/src/components/__tests__/__snapshots__/SystemStructures.spec.js.snap +1 -3
- package/src/components/index.js +2 -0
- package/src/hooks/useBucketStructures.js +10 -0
- package/src/messages/en.js +3 -0
- package/src/messages/es.js +3 -0
- package/src/reducers/bucketFilter.js +15 -0
- package/src/reducers/index.js +4 -1
- package/src/reducers/navFilter.js +14 -0
- package/src/reducers/structure.js +24 -1
- package/src/reducers/structureRedirect.js +7 -0
- package/src/routines.js +4 -0
- package/src/sagas/deleteCatalogViewConfig.js +37 -0
- package/src/sagas/index.js +6 -0
- package/src/sagas/upsertCatalogViewConfig.js +45 -0
- package/src/selectors/getStructureParent.js +17 -5
- package/src/components/__tests__/__snapshots__/FilteredNav.spec.js.snap +0 -23
- package/src/components/__tests__/__snapshots__/StructureView.spec.js.snap +0 -37
- package/src/components/__tests__/__snapshots__/StructuresView.spec.js.snap +0 -70
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "5.9.
|
|
3
|
+
"version": "5.9.3",
|
|
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.
|
|
37
|
+
"@truedat/test": "5.9.3",
|
|
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",
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
89
|
"@apollo/client": "^3.7.1",
|
|
90
|
-
"@truedat/auth": "5.9.
|
|
91
|
-
"@truedat/core": "5.9.
|
|
92
|
-
"@truedat/df": "5.9.
|
|
90
|
+
"@truedat/auth": "5.9.3",
|
|
91
|
+
"@truedat/core": "5.9.3",
|
|
92
|
+
"@truedat/df": "5.9.3",
|
|
93
93
|
"lodash": "^4.17.21",
|
|
94
94
|
"moment": "^2.29.4",
|
|
95
95
|
"path-to-regexp": "^1.7.0",
|
|
@@ -114,5 +114,5 @@
|
|
|
114
114
|
"react-dom": ">= 16.8.6 < 17",
|
|
115
115
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
116
116
|
},
|
|
117
|
-
"gitHead": "
|
|
117
|
+
"gitHead": "703abeeedf1ca0f6ecbc09c9633178e9dcd83e20"
|
|
118
118
|
}
|
package/src/api/mutations.js
CHANGED
|
@@ -103,3 +103,31 @@ export const DELETE_GRANT_APPROVAL_RULE = gql`
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
`;
|
|
106
|
+
|
|
107
|
+
export const UPDATE_CATALOG_VIEW_CONFIG = gql`
|
|
108
|
+
mutation UpdateCatalogViewConfig(
|
|
109
|
+
$catalogViewConfig: UpdateCatalogViewConfigInput!
|
|
110
|
+
) {
|
|
111
|
+
updateCatalogViewConfig(catalogViewConfig: $catalogViewConfig) {
|
|
112
|
+
id
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
116
|
+
|
|
117
|
+
export const CREATE_CATALOG_VIEW_CONFIG = gql`
|
|
118
|
+
mutation CreateCatalogViewConfig(
|
|
119
|
+
$catalogViewConfig: CreateCatalogViewConfigInput!
|
|
120
|
+
) {
|
|
121
|
+
createCatalogViewConfig(catalogViewConfig: $catalogViewConfig) {
|
|
122
|
+
id
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
|
|
127
|
+
export const DELETE_CATALOG_VIEW_CONFIG = gql`
|
|
128
|
+
mutation DeleteCatalogViewConfig($id: ID!) {
|
|
129
|
+
deleteCatalogViewConfig(id: $id) {
|
|
130
|
+
id
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`;
|
package/src/api/queries.js
CHANGED
|
@@ -499,3 +499,23 @@ export const TASK_QUERY = gql`
|
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
501
|
`;
|
|
502
|
+
|
|
503
|
+
export const CATALOG_VIEW_CONFIGS_QUERY = gql`
|
|
504
|
+
query CatalogViewConfigs {
|
|
505
|
+
catalogViewConfigs {
|
|
506
|
+
id
|
|
507
|
+
fieldType
|
|
508
|
+
fieldName
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
`;
|
|
512
|
+
|
|
513
|
+
export const CATALOG_VIEW_CONFIG_QUERY = gql`
|
|
514
|
+
query CatalogViewConfig($id: ID!) {
|
|
515
|
+
catalogViewConfig(id: $id) {
|
|
516
|
+
id
|
|
517
|
+
fieldType
|
|
518
|
+
fieldName
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
`;
|
package/src/api.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const API_BUCKET_STRUCTURES = "/api/buckets/structures";
|
|
2
|
+
const API_BUCKET_STRUCTURE = "/api/buckets/structures/:id";
|
|
1
3
|
const API_DATA_STRUCTURE = "/api/data_structures/:id";
|
|
2
4
|
const API_DATA_STRUCTURES_BULK_UPDATE = "/api/data_structures/bulk_update";
|
|
3
5
|
const API_DATA_STRUCTURES_EDITABLE_CSV = "/api/data_structures/editable_csv";
|
|
@@ -48,6 +50,8 @@ const API_STRUCTURE_NOTE = "/api/data_structures/:data_structure_id/notes/:id";
|
|
|
48
50
|
const API_STRUCTURE_NOTES = "/api/data_structures/:data_structure_id/notes";
|
|
49
51
|
|
|
50
52
|
export {
|
|
53
|
+
API_BUCKET_STRUCTURES,
|
|
54
|
+
API_BUCKET_STRUCTURE,
|
|
51
55
|
API_DATA_STRUCTURE,
|
|
52
56
|
API_DATA_STRUCTURES_BULK_UPDATE,
|
|
53
57
|
API_DATA_STRUCTURES_EDITABLE_CSV,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useEffect } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { Grid, Segment } from "semantic-ui-react";
|
|
6
|
+
import { useParams, useLocation } from "react-router-dom";
|
|
7
|
+
import { saveNavFilter as saveNavFilterRoutine } from "../routines";
|
|
8
|
+
import FilteredNav from "./FilteredNav";
|
|
9
|
+
import StructureCrumbs from "./StructureCrumbs";
|
|
10
|
+
import StructureGrantCart from "./StructureGrantCart";
|
|
11
|
+
import StructureSummary from "./StructureSummary";
|
|
12
|
+
import StructureTabPaneRoutes from "./StructureTabPaneRoutes";
|
|
13
|
+
import StructureTabRoutes from "./StructureTabRoutes";
|
|
14
|
+
|
|
15
|
+
const isBucketFilter = _.flow(
|
|
16
|
+
Object.keys,
|
|
17
|
+
// Both metadata and mutable_metadata are "metadata"
|
|
18
|
+
_.any((entry) => entry.startsWith("metadata", "note"))
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const BucketView = ({
|
|
22
|
+
showGrantRequestCart,
|
|
23
|
+
saveNavFilter,
|
|
24
|
+
navFilter,
|
|
25
|
+
}) => {
|
|
26
|
+
const params = useParams();
|
|
27
|
+
const { id: structureId } = params;
|
|
28
|
+
const location = useLocation();
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
_.flow(
|
|
32
|
+
_.path("search"),
|
|
33
|
+
(search) => new URLSearchParams(search).entries(),
|
|
34
|
+
(entries) => Object.fromEntries(entries),
|
|
35
|
+
_.pick(["propertyPath", "propertyValue"]),
|
|
36
|
+
_.values,
|
|
37
|
+
(keyValue) => Object.fromEntries(new Map([keyValue]).entries()),
|
|
38
|
+
saveNavFilter
|
|
39
|
+
)(location);
|
|
40
|
+
}, [location, saveNavFilter]);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Segment className="structures">
|
|
44
|
+
<Grid>
|
|
45
|
+
<Grid.Row stretched>
|
|
46
|
+
<Grid.Row>
|
|
47
|
+
<Grid.Column width={16}>
|
|
48
|
+
<StructureCrumbs />
|
|
49
|
+
</Grid.Column>
|
|
50
|
+
</Grid.Row>
|
|
51
|
+
<Grid.Column width={4}>
|
|
52
|
+
<Segment>
|
|
53
|
+
{isBucketFilter(navFilter) ? (
|
|
54
|
+
<FilteredNav filter={navFilter} />
|
|
55
|
+
) : null}
|
|
56
|
+
</Segment>
|
|
57
|
+
</Grid.Column>
|
|
58
|
+
<Grid.Column width={showGrantRequestCart ? 8 : 12}>
|
|
59
|
+
<Segment>
|
|
60
|
+
{structureId ? (
|
|
61
|
+
<>
|
|
62
|
+
<StructureSummary />
|
|
63
|
+
<StructureTabRoutes />
|
|
64
|
+
<StructureTabPaneRoutes />
|
|
65
|
+
</>
|
|
66
|
+
) : (
|
|
67
|
+
<p> {JSON.stringify(navFilter)} </p>
|
|
68
|
+
)}
|
|
69
|
+
</Segment>
|
|
70
|
+
</Grid.Column>
|
|
71
|
+
{showGrantRequestCart && (
|
|
72
|
+
<Grid.Column width={4}>
|
|
73
|
+
<StructureGrantCart />
|
|
74
|
+
</Grid.Column>
|
|
75
|
+
)}
|
|
76
|
+
</Grid.Row>
|
|
77
|
+
</Grid>
|
|
78
|
+
</Segment>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
BucketView.propTypes = {
|
|
83
|
+
navFilter: PropTypes.object,
|
|
84
|
+
saveNavFilter: PropTypes.func,
|
|
85
|
+
showGrantRequestCart: PropTypes.bool,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const mapStateToProps = ({ navFilter }) => ({ navFilter });
|
|
89
|
+
|
|
90
|
+
export default connect(mapStateToProps, {
|
|
91
|
+
saveNavFilter: saveNavFilterRoutine,
|
|
92
|
+
})(BucketView);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { Link, useParams } from "react-router-dom";
|
|
6
|
+
import { Card, Label } from "semantic-ui-react";
|
|
7
|
+
import { useIntl } from "react-intl";
|
|
8
|
+
import { FormattedNumber } from "react-intl";
|
|
9
|
+
import { CardGroupsAccordion } from "@truedat/core/components";
|
|
10
|
+
import { linkTo } from "@truedat/core/routes";
|
|
11
|
+
|
|
12
|
+
export const CatalogCustomViewCards = ({ structureFilters }) => {
|
|
13
|
+
const { propertyPath } = useParams();
|
|
14
|
+
const groups = [];
|
|
15
|
+
|
|
16
|
+
return Object.keys(groups).length > 1 ? (
|
|
17
|
+
<CardGroupsAccordion
|
|
18
|
+
groups={groups}
|
|
19
|
+
cardComponent={CatalogCustomViewCard}
|
|
20
|
+
/>
|
|
21
|
+
) : (
|
|
22
|
+
<Card.Group className="structures">
|
|
23
|
+
{_.map(({ doc_count: structures_count, key: name }) => (
|
|
24
|
+
<CatalogCustomViewCard
|
|
25
|
+
key={name}
|
|
26
|
+
id={name}
|
|
27
|
+
name={name}
|
|
28
|
+
structures_count={structures_count}
|
|
29
|
+
/>
|
|
30
|
+
))(structureFilters[propertyPath]?.buckets)}
|
|
31
|
+
</Card.Group>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
CatalogCustomViewCards.propTypes = {
|
|
36
|
+
structureFilters: PropTypes.object,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const CatalogCustomViewCard = ({
|
|
40
|
+
name,
|
|
41
|
+
structures_count,
|
|
42
|
+
structureTypes,
|
|
43
|
+
}) => {
|
|
44
|
+
const { formatMessage } = useIntl();
|
|
45
|
+
const { propertyPath } = useParams();
|
|
46
|
+
const queryParams = new URLSearchParams({
|
|
47
|
+
propertyPath,
|
|
48
|
+
propertyValue: name,
|
|
49
|
+
});
|
|
50
|
+
return (
|
|
51
|
+
<Card link as={Link} to={`${linkTo.BUCKET_VIEW()}?${queryParams}`}>
|
|
52
|
+
<Card.Content className="extra-bottom-padding">
|
|
53
|
+
<Card.Header style={name === "_missing" ? { color: "grey" } : null}>
|
|
54
|
+
{name === "_missing" ? formatMessage({ id: "missingBucket" }) : name}
|
|
55
|
+
</Card.Header>
|
|
56
|
+
{structures_count && (
|
|
57
|
+
<CatalogCustomViewCardPopup
|
|
58
|
+
structures_count={structures_count}
|
|
59
|
+
structureTypes={structureTypes}
|
|
60
|
+
/>
|
|
61
|
+
)}
|
|
62
|
+
</Card.Content>
|
|
63
|
+
</Card>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
CatalogCustomViewCard.propTypes = {
|
|
68
|
+
name: PropTypes.string,
|
|
69
|
+
structures_count: PropTypes.number,
|
|
70
|
+
structureTypes: PropTypes.object,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const CatalogCustomViewCardPopup = ({ structures_count }) => {
|
|
74
|
+
return (
|
|
75
|
+
<Label aria-label="count" attached="bottom right" className="overlapping">
|
|
76
|
+
<FormattedNumber value={structures_count} />
|
|
77
|
+
</Label>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
CatalogCustomViewCardPopup.propTypes = {
|
|
81
|
+
structures_count: PropTypes.number,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const mapStateToProps = ({ structures, structureFilters }) => ({
|
|
85
|
+
structures,
|
|
86
|
+
structureFilters,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export default connect(mapStateToProps)(CatalogCustomViewCards);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import React, { useEffect } from "react";
|
|
4
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
5
|
+
import { useParams } from "react-router-dom";
|
|
6
|
+
import { useForm, Controller } from "react-hook-form";
|
|
7
|
+
import { connect } from "react-redux";
|
|
8
|
+
|
|
9
|
+
import { Button, Header, Form, Icon } from "semantic-ui-react";
|
|
10
|
+
|
|
11
|
+
import { useQuery } from "@apollo/client";
|
|
12
|
+
import { CATALOG_VIEW_CONFIG_QUERY } from "../api/queries";
|
|
13
|
+
import { upsertCatalogViewConfig as upsertCatalogViewConfigRoutine } from "../routines";
|
|
14
|
+
|
|
15
|
+
export const CatalogViewConfigForm = ({
|
|
16
|
+
initialConfig,
|
|
17
|
+
upsertCatalogViewConfig,
|
|
18
|
+
loading,
|
|
19
|
+
}) => {
|
|
20
|
+
const { formatMessage } = useIntl();
|
|
21
|
+
|
|
22
|
+
const { handleSubmit, control, formState, reset } = useForm({
|
|
23
|
+
mode: "onChange",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const onSubmit = (config) => upsertCatalogViewConfig(config);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
reset(initialConfig);
|
|
30
|
+
}, [initialConfig, reset]);
|
|
31
|
+
|
|
32
|
+
return loading ? null : (
|
|
33
|
+
<>
|
|
34
|
+
<Header as="h2">
|
|
35
|
+
<Icon name="book" />
|
|
36
|
+
<Header.Content>
|
|
37
|
+
<FormattedMessage id="bucketViewConfigs.new" />
|
|
38
|
+
</Header.Content>
|
|
39
|
+
</Header>
|
|
40
|
+
<Form onSubmit={handleSubmit(onSubmit)} aria-label="form">
|
|
41
|
+
<Controller
|
|
42
|
+
control={control}
|
|
43
|
+
name="fieldType"
|
|
44
|
+
rules={{ required: true }}
|
|
45
|
+
render={({ field: { onBlur, onChange, value: fieldType } }) => (
|
|
46
|
+
<Form.Field>
|
|
47
|
+
<Form.Dropdown
|
|
48
|
+
aria-label="fieldType"
|
|
49
|
+
width={2}
|
|
50
|
+
name="fieldType"
|
|
51
|
+
onBlur={onBlur}
|
|
52
|
+
label={formatMessage({
|
|
53
|
+
id: "bucketViewConfig.fieldType",
|
|
54
|
+
})}
|
|
55
|
+
selection
|
|
56
|
+
options={["metadata", "note"].map((o) => ({
|
|
57
|
+
key: o,
|
|
58
|
+
value: o,
|
|
59
|
+
text: formatMessage({
|
|
60
|
+
id: `${o}`,
|
|
61
|
+
}),
|
|
62
|
+
}))}
|
|
63
|
+
onChange={(_e, { value }) => onChange(value)}
|
|
64
|
+
placeholder={formatMessage({
|
|
65
|
+
id: "grantApprovalRule.conditions.field_prefix.placeholder",
|
|
66
|
+
})}
|
|
67
|
+
value={fieldType}
|
|
68
|
+
required
|
|
69
|
+
/>
|
|
70
|
+
</Form.Field>
|
|
71
|
+
)}
|
|
72
|
+
/>
|
|
73
|
+
<Controller
|
|
74
|
+
control={control}
|
|
75
|
+
name="fieldName"
|
|
76
|
+
rules={{ required: true }}
|
|
77
|
+
render={({ field: { onBlur, onChange, value: fieldName } }) => (
|
|
78
|
+
<Form.Field>
|
|
79
|
+
<Form.Input
|
|
80
|
+
id={`fieldName-${fieldName}`}
|
|
81
|
+
width={2}
|
|
82
|
+
name="fieldName"
|
|
83
|
+
aria-label="fieldName"
|
|
84
|
+
label={formatMessage({
|
|
85
|
+
id: "bucketViewConfig.fieldName",
|
|
86
|
+
})}
|
|
87
|
+
value={fieldName || ""}
|
|
88
|
+
onBlur={onBlur}
|
|
89
|
+
onChange={(_e, { value }) => onChange(value)}
|
|
90
|
+
required
|
|
91
|
+
/>
|
|
92
|
+
</Form.Field>
|
|
93
|
+
)}
|
|
94
|
+
/>
|
|
95
|
+
<Button
|
|
96
|
+
type="submit"
|
|
97
|
+
disabled={!formState.isValid}
|
|
98
|
+
aria-label="save"
|
|
99
|
+
primary
|
|
100
|
+
content={formatMessage({ id: "actions.save" })}
|
|
101
|
+
/>
|
|
102
|
+
</Form>
|
|
103
|
+
</>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
CatalogViewConfigForm.propTypes = {
|
|
108
|
+
initialConfig: PropTypes.object,
|
|
109
|
+
upsertCatalogViewConfig: PropTypes.func,
|
|
110
|
+
loading: PropTypes.bool,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const CatalogViewConfigFormConnected = connect(null, {
|
|
114
|
+
upsertCatalogViewConfig: upsertCatalogViewConfigRoutine,
|
|
115
|
+
})(CatalogViewConfigForm);
|
|
116
|
+
|
|
117
|
+
export const CatalogViewConfigFormLoader = () => {
|
|
118
|
+
const { id } = useParams();
|
|
119
|
+
const { loading, error, data } = useQuery(CATALOG_VIEW_CONFIG_QUERY, {
|
|
120
|
+
fetchPolicy: "cache-and-network",
|
|
121
|
+
variables: { id },
|
|
122
|
+
});
|
|
123
|
+
if (error) return null;
|
|
124
|
+
const config = data?.catalogViewConfig;
|
|
125
|
+
return (
|
|
126
|
+
<CatalogViewConfigFormConnected loading={loading} initialConfig={config} />
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default CatalogViewConfigFormLoader;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import PropTypes from "prop-types";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
4
|
+
import { columnDecoratorComponent } from "@truedat/core/services";
|
|
5
|
+
import { Link, useHistory } from "react-router-dom";
|
|
6
|
+
import { BUCKET_VIEW_CONFIG_NEW, linkTo } from "@truedat/core/routes";
|
|
7
|
+
import { useQuery } from "@apollo/client";
|
|
8
|
+
import { Button, Segment, Table } from "semantic-ui-react";
|
|
9
|
+
import { ConfirmModal } from "@truedat/core/components";
|
|
10
|
+
import { connect } from "react-redux";
|
|
11
|
+
import { CATALOG_VIEW_CONFIGS_QUERY } from "../api/queries";
|
|
12
|
+
import { deleteCatalogViewConfig as deleteCatalogViewConfigRoutine } from "../routines";
|
|
13
|
+
|
|
14
|
+
export const CatalogViewConfigs = ({
|
|
15
|
+
deleteCatalogViewConfig,
|
|
16
|
+
configs,
|
|
17
|
+
loading,
|
|
18
|
+
}) => {
|
|
19
|
+
const { formatMessage } = useIntl();
|
|
20
|
+
const history = useHistory();
|
|
21
|
+
|
|
22
|
+
const columns = [
|
|
23
|
+
{ name: "Field type", fieldSelector: "fieldType" },
|
|
24
|
+
{ name: "Field name", fieldSelector: "fieldName" },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
return loading ? null : (
|
|
28
|
+
<Segment textAlign="right">
|
|
29
|
+
<Button
|
|
30
|
+
primary
|
|
31
|
+
as={Link}
|
|
32
|
+
to={BUCKET_VIEW_CONFIG_NEW}
|
|
33
|
+
content={formatMessage({
|
|
34
|
+
id: "bucketViewConfigs.new",
|
|
35
|
+
})}
|
|
36
|
+
/>
|
|
37
|
+
<Table>
|
|
38
|
+
<Table.Header>
|
|
39
|
+
<Table.Row>
|
|
40
|
+
{columns.map((column, i) => {
|
|
41
|
+
return (
|
|
42
|
+
<Table.HeaderCell
|
|
43
|
+
key={i}
|
|
44
|
+
width={column.width}
|
|
45
|
+
content={formatMessage({
|
|
46
|
+
id: `bucketViewConfig.${column.fieldSelector}`,
|
|
47
|
+
})}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
})}
|
|
51
|
+
<Table.HeaderCell textAlign="center">
|
|
52
|
+
<FormattedMessage id="actions.delete" />
|
|
53
|
+
</Table.HeaderCell>
|
|
54
|
+
</Table.Row>
|
|
55
|
+
</Table.Header>
|
|
56
|
+
<Table.Body>
|
|
57
|
+
{configs.map((config, rowNumber) => {
|
|
58
|
+
return (
|
|
59
|
+
<Table.Row style={{ cursor: "pointer" }} key={rowNumber}>
|
|
60
|
+
{columns.map((column, columnNumber) => (
|
|
61
|
+
<Table.Cell
|
|
62
|
+
key={`${rowNumber}_${columnNumber}`}
|
|
63
|
+
content={columnDecoratorComponent(column)(config)}
|
|
64
|
+
onClick={() =>
|
|
65
|
+
history.push(
|
|
66
|
+
linkTo.BUCKET_VIEW_CONFIG_EDIT({ id: config.id })
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
/>
|
|
70
|
+
))}
|
|
71
|
+
<Table.Cell
|
|
72
|
+
style={{ cursor: "default" }}
|
|
73
|
+
collapsing
|
|
74
|
+
width="1"
|
|
75
|
+
textAlign="center"
|
|
76
|
+
>
|
|
77
|
+
<ConfirmModal
|
|
78
|
+
icon="trash"
|
|
79
|
+
trigger={
|
|
80
|
+
<Button
|
|
81
|
+
aria-label="delete"
|
|
82
|
+
basic
|
|
83
|
+
icon="trash"
|
|
84
|
+
color="red"
|
|
85
|
+
/>
|
|
86
|
+
}
|
|
87
|
+
header={
|
|
88
|
+
<FormattedMessage id="relations.actions.data_field.delete.confirmation.header" />
|
|
89
|
+
}
|
|
90
|
+
content={
|
|
91
|
+
<FormattedMessage id="relations.actions.data_field.delete.confirmation.content" />
|
|
92
|
+
}
|
|
93
|
+
onConfirm={() => deleteCatalogViewConfig({ id: config.id })}
|
|
94
|
+
/>
|
|
95
|
+
</Table.Cell>
|
|
96
|
+
</Table.Row>
|
|
97
|
+
);
|
|
98
|
+
})}
|
|
99
|
+
</Table.Body>
|
|
100
|
+
</Table>
|
|
101
|
+
</Segment>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
CatalogViewConfigs.propTypes = {
|
|
106
|
+
configs: PropTypes.array,
|
|
107
|
+
deleteCatalogViewConfig: PropTypes.func,
|
|
108
|
+
loading: PropTypes.bool,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const CatalogViewConfigsConnected = connect(null, {
|
|
112
|
+
deleteCatalogViewConfig: deleteCatalogViewConfigRoutine,
|
|
113
|
+
})(CatalogViewConfigs);
|
|
114
|
+
|
|
115
|
+
export const CatalogViewConfigsLoader = () => {
|
|
116
|
+
const { loading, error, data } = useQuery(CATALOG_VIEW_CONFIGS_QUERY, {
|
|
117
|
+
fetchPolicy: "cache-and-network",
|
|
118
|
+
});
|
|
119
|
+
if (error) return null;
|
|
120
|
+
const configs = data?.catalogViewConfigs || [];
|
|
121
|
+
return <CatalogViewConfigsConnected loading={loading} configs={configs} />;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export default CatalogViewConfigsLoader;
|
|
@@ -2,6 +2,11 @@ import React from "react";
|
|
|
2
2
|
import { Route, Switch } from "react-router-dom";
|
|
3
3
|
import { useActiveRoute } from "@truedat/core/hooks";
|
|
4
4
|
import {
|
|
5
|
+
BUCKET_VIEW,
|
|
6
|
+
BUCKET_VIEW_CONFIG_EDIT,
|
|
7
|
+
BUCKET_VIEW_CONFIG_NEW,
|
|
8
|
+
BUCKET_VIEW_CONFIGS,
|
|
9
|
+
BUCKETS_VIEW,
|
|
5
10
|
PENDING_STRUCTURE_NOTES,
|
|
6
11
|
PROFILE_EXECUTION,
|
|
7
12
|
PROFILE_GROUP,
|
|
@@ -13,6 +18,7 @@ import {
|
|
|
13
18
|
SYSTEMS,
|
|
14
19
|
TASKS,
|
|
15
20
|
} from "@truedat/core/routes";
|
|
21
|
+
import CatalogViewConfigs from "./CatalogViewConfigs";
|
|
16
22
|
import PendingStructureNotes from "./PendingStructureNotes";
|
|
17
23
|
import ProfileExecution from "./ProfileExecution";
|
|
18
24
|
import ProfileExecutionBreadcrumbs from "./ProfileExecutionBreadcrumbs";
|
|
@@ -30,30 +36,55 @@ import SystemsRoutes from "./SystemsRoutes";
|
|
|
30
36
|
import SystemsLoader from "./SystemsLoader";
|
|
31
37
|
import TagsRoutes from "./TagsRoutes";
|
|
32
38
|
import TasksRoutes from "./TasksRoutes";
|
|
39
|
+
import {
|
|
40
|
+
CatalogViewConfigFormConnected,
|
|
41
|
+
CatalogViewConfigFormLoader,
|
|
42
|
+
} from "./CatalogViewConfigForm";
|
|
33
43
|
|
|
34
44
|
const TemplatesLoader = React.lazy(() =>
|
|
35
45
|
import("@truedat/df/templates/components/TemplatesLoader")
|
|
36
46
|
);
|
|
37
47
|
|
|
38
|
-
const Loaders = () =>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
const Loaders = () => {
|
|
49
|
+
return (
|
|
50
|
+
<>
|
|
51
|
+
<StructuresLoader />
|
|
52
|
+
<StructureFiltersLoader />
|
|
53
|
+
<TemplatesLoader scope="dd" />
|
|
54
|
+
</>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
45
57
|
|
|
46
58
|
export const DictionaryRoutes = () => {
|
|
47
59
|
const structuresActive = useActiveRoute(STRUCTURES);
|
|
48
60
|
const systemsActive = useActiveRoute(SYSTEMS);
|
|
49
61
|
const structureTypesActive = useActiveRoute(STRUCTURE_TYPES);
|
|
50
|
-
const
|
|
62
|
+
const customCatalogViewActive = useActiveRoute(BUCKETS_VIEW);
|
|
63
|
+
const active =
|
|
64
|
+
structuresActive ||
|
|
65
|
+
systemsActive ||
|
|
66
|
+
structureTypesActive ||
|
|
67
|
+
customCatalogViewActive;
|
|
51
68
|
|
|
52
69
|
return (
|
|
53
70
|
<>
|
|
54
71
|
<Route render={() => (active ? <Loaders /> : null)} />
|
|
72
|
+
<Switch>
|
|
73
|
+
<Route
|
|
74
|
+
path={BUCKET_VIEW_CONFIG_EDIT}
|
|
75
|
+
render={() => <CatalogViewConfigFormLoader />}
|
|
76
|
+
/>
|
|
77
|
+
<Route
|
|
78
|
+
path={BUCKET_VIEW_CONFIG_NEW}
|
|
79
|
+
render={() => <CatalogViewConfigFormConnected />}
|
|
80
|
+
/>
|
|
81
|
+
<Route
|
|
82
|
+
path={BUCKET_VIEW_CONFIGS}
|
|
83
|
+
render={() => <CatalogViewConfigs />}
|
|
84
|
+
/>
|
|
85
|
+
</Switch>
|
|
55
86
|
<Route
|
|
56
|
-
path={STRUCTURES}
|
|
87
|
+
path={[STRUCTURES, BUCKETS_VIEW, BUCKET_VIEW]}
|
|
57
88
|
render={() => (
|
|
58
89
|
<>
|
|
59
90
|
<StructureTypesLoader />
|