@truedat/dd 5.2.9 → 5.3.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
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
89
|
"@apollo/client": "^3.7.1",
|
|
90
|
-
"@truedat/auth": "5.
|
|
91
|
-
"@truedat/core": "5.
|
|
92
|
-
"@truedat/df": "5.
|
|
90
|
+
"@truedat/auth": "5.3.0",
|
|
91
|
+
"@truedat/core": "5.3.0",
|
|
92
|
+
"@truedat/df": "5.3.0",
|
|
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": "4893c314084a4ea7ca48a4e251d4e47565f3f030"
|
|
118
118
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import React, { useEffect, useState } from "react";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { useQuery } from "@apollo/client";
|
|
6
|
+
import { Loading } from "@truedat/core/components";
|
|
7
|
+
import { Dropdown } from "semantic-ui-react";
|
|
8
|
+
import { REFERENCE_DATASETS_QUERY } from "@truedat/dd/api/queries";
|
|
9
|
+
|
|
10
|
+
const refDatasetsToOptions = (referenceDatasets) => {
|
|
11
|
+
return _.map(({ id, name }) => {
|
|
12
|
+
return { key: id, text: name, value: id };
|
|
13
|
+
})(referenceDatasets);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const headersToOptions = (refDatasetId) => (headers) => {
|
|
17
|
+
return _.map((header) => {
|
|
18
|
+
return {
|
|
19
|
+
key: `${refDatasetId}_${header}`,
|
|
20
|
+
text: header,
|
|
21
|
+
value: header,
|
|
22
|
+
};
|
|
23
|
+
})(headers);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const onReferenceDatasetChange =
|
|
27
|
+
(referenceDatasets, setHeaders, setSelectedRefDataset, onChange) =>
|
|
28
|
+
(_e, { value: refDatasetId }) => {
|
|
29
|
+
/* Only reference dataset selected, its field is still yet to be chosen.
|
|
30
|
+
* Therefore:
|
|
31
|
+
* Clear any previously selected field still showing in ConditionSummary
|
|
32
|
+
* Make validation fail using field nulled name so that "Next"
|
|
33
|
+
* RuleImplementationForm button is disabled.
|
|
34
|
+
*/
|
|
35
|
+
onChange(
|
|
36
|
+
null,
|
|
37
|
+
{
|
|
38
|
+
type: "reference_dataset_field",
|
|
39
|
+
name: null,
|
|
40
|
+
referenceDataset: { id: refDatasetId },
|
|
41
|
+
},
|
|
42
|
+
null
|
|
43
|
+
);
|
|
44
|
+
setSelectedRefDataset(_.find({ id: refDatasetId })(referenceDatasets));
|
|
45
|
+
_.flow(
|
|
46
|
+
_.find({ id: refDatasetId }),
|
|
47
|
+
_.prop("headers"),
|
|
48
|
+
setHeaders
|
|
49
|
+
)(referenceDatasets);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const ReferenceDatasetFieldSelector = ({
|
|
53
|
+
referenceDatasets,
|
|
54
|
+
referenceDataset,
|
|
55
|
+
header,
|
|
56
|
+
onChange,
|
|
57
|
+
}) => {
|
|
58
|
+
const { formatMessage } = useIntl();
|
|
59
|
+
const [headers, setHeaders] = useState(
|
|
60
|
+
_.find({ id: referenceDataset?.id })(referenceDatasets)?.headers || []
|
|
61
|
+
);
|
|
62
|
+
const [selectedRefDataset, setSelectedRefDataset] =
|
|
63
|
+
useState(referenceDataset);
|
|
64
|
+
|
|
65
|
+
const [selectedHeader, setSelectedHeader] = useState(header);
|
|
66
|
+
|
|
67
|
+
// if the operator dropdown changes, referenceDataset will come as undefined
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (referenceDataset == null) {
|
|
70
|
+
setSelectedRefDataset(null);
|
|
71
|
+
setSelectedHeader(null);
|
|
72
|
+
setHeaders([]);
|
|
73
|
+
}
|
|
74
|
+
}, [referenceDataset]);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
<label>
|
|
79
|
+
{formatMessage({
|
|
80
|
+
id: "referenceDatasetFields.dropdown.placeholder",
|
|
81
|
+
})}
|
|
82
|
+
</label>
|
|
83
|
+
<Dropdown
|
|
84
|
+
className="reference-dataset"
|
|
85
|
+
selection
|
|
86
|
+
placeholder={formatMessage({
|
|
87
|
+
id: "referenceDataset.dropdown.placeholder",
|
|
88
|
+
})}
|
|
89
|
+
options={refDatasetsToOptions(referenceDatasets)}
|
|
90
|
+
value={selectedRefDataset?.id || ""}
|
|
91
|
+
onChange={onReferenceDatasetChange(
|
|
92
|
+
referenceDatasets,
|
|
93
|
+
setHeaders,
|
|
94
|
+
setSelectedRefDataset,
|
|
95
|
+
onChange
|
|
96
|
+
)}
|
|
97
|
+
/>
|
|
98
|
+
<Dropdown
|
|
99
|
+
selection
|
|
100
|
+
placeholder={formatMessage({
|
|
101
|
+
id: "referenceDatasetFields.dropdown.placeholder",
|
|
102
|
+
})}
|
|
103
|
+
disabled={!selectedRefDataset}
|
|
104
|
+
options={headersToOptions(selectedRefDataset?.id)(headers)}
|
|
105
|
+
value={selectedHeader || ""}
|
|
106
|
+
onChange={(e, { value: newHeader }) => {
|
|
107
|
+
setSelectedHeader(newHeader);
|
|
108
|
+
onChange(
|
|
109
|
+
null,
|
|
110
|
+
{
|
|
111
|
+
referenceDataset: _.pick(["id", "name"], selectedRefDataset),
|
|
112
|
+
name: newHeader,
|
|
113
|
+
type: "reference_dataset_field",
|
|
114
|
+
},
|
|
115
|
+
null
|
|
116
|
+
);
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
ReferenceDatasetFieldSelector.propTypes = {
|
|
124
|
+
header: PropTypes.string,
|
|
125
|
+
onChange: PropTypes.func,
|
|
126
|
+
referenceDatasets: PropTypes.array,
|
|
127
|
+
referenceDataset: PropTypes.object,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const ReferenceDatasetFieldSelectorLoader = (props) => {
|
|
131
|
+
const { loading, error, data } = useQuery(REFERENCE_DATASETS_QUERY, {
|
|
132
|
+
fetchPolicy: "cache-and-network",
|
|
133
|
+
});
|
|
134
|
+
if (error) return null;
|
|
135
|
+
if (loading) return <Loading />;
|
|
136
|
+
const referenceDatasets = data?.referenceDatasets || [];
|
|
137
|
+
return (
|
|
138
|
+
<ReferenceDatasetFieldSelector
|
|
139
|
+
loading={loading}
|
|
140
|
+
referenceDatasets={referenceDatasets}
|
|
141
|
+
{...props}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export default ReferenceDatasetFieldSelectorLoader;
|
|
@@ -0,0 +1,86 @@
|
|
|
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 { REFERENCE_DATASETS_QUERY } from "../../api/queries";
|
|
6
|
+
import ReferenceDatasetFieldSelector from "../ReferenceDatasetFieldSelector";
|
|
7
|
+
|
|
8
|
+
const referenceDatasets = [
|
|
9
|
+
{
|
|
10
|
+
__typename: "ReferenceDataset",
|
|
11
|
+
id: "1",
|
|
12
|
+
name: "countries",
|
|
13
|
+
headers: ["CODE", "DESC_ES", "DESC_EN"],
|
|
14
|
+
rowCount: 9,
|
|
15
|
+
updatedAt: "2023-03-04T12:10:53.245332Z",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
__typename: "ReferenceDataset",
|
|
19
|
+
id: "2",
|
|
20
|
+
name: "currencies",
|
|
21
|
+
headers: ["ENTITY", "Currency", "Alphabetic Code", "Numeric Code"],
|
|
22
|
+
rowCount: 5,
|
|
23
|
+
updatedAt: "2023-03-05T09:57:59.765822Z",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const referenceDatasetsMock = {
|
|
28
|
+
request: {
|
|
29
|
+
query: REFERENCE_DATASETS_QUERY,
|
|
30
|
+
},
|
|
31
|
+
result: { data: { referenceDatasets } },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
describe("<ReferenceDatasetFieldSelector />", () => {
|
|
35
|
+
it("selecting reference dataset fills fields dropdown; clicking a field calls onChange", async () => {
|
|
36
|
+
const onChange = jest.fn();
|
|
37
|
+
const renderOpts = {
|
|
38
|
+
mocks: [referenceDatasetsMock],
|
|
39
|
+
};
|
|
40
|
+
const { queryAllByText, getByRole } = render(
|
|
41
|
+
<ReferenceDatasetFieldSelector onChange={onChange} />,
|
|
42
|
+
renderOpts
|
|
43
|
+
);
|
|
44
|
+
const countriesOptionQuery = () =>
|
|
45
|
+
getByRole("option", { name: /countries/i });
|
|
46
|
+
await waitFor(() => {
|
|
47
|
+
// also matches "reference dataset field", get first
|
|
48
|
+
expect(queryAllByText(/Reference dataset/i)[0]).toBeInTheDocument();
|
|
49
|
+
// same text for label and dropdown, match the second one, the dropdown
|
|
50
|
+
expect(queryAllByText(/Reference dataset field/i)[1]).toBeInTheDocument();
|
|
51
|
+
expect(countriesOptionQuery()).toBeInTheDocument();
|
|
52
|
+
expect(getByRole("option", { name: /currencies/i })).toBeInTheDocument();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
userEvent.click(countriesOptionQuery());
|
|
56
|
+
|
|
57
|
+
const optionQuery = () => getByRole("option", { name: /CODE/i });
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
expect(optionQuery()).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
userEvent.click(optionQuery());
|
|
62
|
+
expect(onChange).toHaveBeenNthCalledWith(
|
|
63
|
+
1,
|
|
64
|
+
null,
|
|
65
|
+
{
|
|
66
|
+
name: null,
|
|
67
|
+
referenceDataset: { id: "1" },
|
|
68
|
+
type: "reference_dataset_field",
|
|
69
|
+
},
|
|
70
|
+
null
|
|
71
|
+
);
|
|
72
|
+
expect(onChange).toHaveBeenNthCalledWith(
|
|
73
|
+
2,
|
|
74
|
+
null,
|
|
75
|
+
{
|
|
76
|
+
name: "CODE",
|
|
77
|
+
referenceDataset: {
|
|
78
|
+
id: "1",
|
|
79
|
+
name: "countries",
|
|
80
|
+
},
|
|
81
|
+
type: "reference_dataset_field",
|
|
82
|
+
},
|
|
83
|
+
null
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
});
|