@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.
Files changed (95) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/package.json +24 -20
  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/PendingStructureNotes.js +1 -1
  12. package/src/components/ReferenceDataset.js +23 -0
  13. package/src/components/ReferenceDatasetActions.js +88 -0
  14. package/src/components/ReferenceDatasetBreadcrumbs.js +22 -0
  15. package/src/components/ReferenceDatasetCreate.js +36 -0
  16. package/src/components/ReferenceDatasetDetail.js +42 -0
  17. package/src/components/ReferenceDatasetForm.js +109 -0
  18. package/src/components/ReferenceDatasetHeader.js +32 -0
  19. package/src/components/ReferenceDatasetRoutes.js +56 -0
  20. package/src/components/ReferenceDatasetTable.js +42 -0
  21. package/src/components/ReferenceDatasets.js +61 -0
  22. package/src/components/ReferenceDatasetsTable.js +105 -0
  23. package/src/components/StructureConfidentialButton.js +1 -1
  24. package/src/components/StructureFilters.js +1 -5
  25. package/src/components/StructureNotesEdit.js +6 -6
  26. package/src/components/StructureProperties.js +4 -1
  27. package/src/components/StructureTabPane.js +4 -2
  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__/LineageRoutes.spec.js +4 -4
  34. package/src/components/__tests__/ReferenceDataset.spec.js +64 -0
  35. package/src/components/__tests__/ReferenceDatasetActions.spec.js +17 -0
  36. package/src/components/__tests__/ReferenceDatasetBreadcrumbs.spec.js +12 -0
  37. package/src/components/__tests__/ReferenceDatasetCreate.spec.js +12 -0
  38. package/src/components/__tests__/ReferenceDatasetDetail.spec.js +37 -0
  39. package/src/components/__tests__/ReferenceDatasetForm.spec.js +51 -0
  40. package/src/components/__tests__/ReferenceDatasetHeader.spec.js +17 -0
  41. package/src/components/__tests__/ReferenceDatasetRoutes.spec.js +74 -0
  42. package/src/components/__tests__/ReferenceDatasetTable.spec.js +18 -0
  43. package/src/components/__tests__/ReferenceDatasets.spec.js +32 -0
  44. package/src/components/__tests__/ReferenceDatasetsTable.spec.js +22 -0
  45. package/src/components/__tests__/StructureConfidentialButton.spec.js +26 -30
  46. package/src/components/__tests__/StructureNotesEdit.spec.js +2 -9
  47. package/src/components/__tests__/StructureProperties.spec.js +6 -8
  48. package/src/components/__tests__/StructureVersionListItem.spec.js +4 -4
  49. package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +4 -0
  50. package/src/components/__tests__/__snapshots__/LineageRoutes.spec.js.snap +1 -20
  51. package/src/components/__tests__/__snapshots__/ProfileExecution.spec.js.snap +2 -1
  52. package/src/components/__tests__/__snapshots__/ReferenceDataset.spec.js.snap +365 -0
  53. package/src/components/__tests__/__snapshots__/ReferenceDatasetActions.spec.js.snap +65 -0
  54. package/src/components/__tests__/__snapshots__/ReferenceDatasetBreadcrumbs.spec.js.snap +25 -0
  55. package/src/components/__tests__/__snapshots__/ReferenceDatasetCreate.spec.js.snap +98 -0
  56. package/src/components/__tests__/__snapshots__/ReferenceDatasetDetail.spec.js.snap +135 -0
  57. package/src/components/__tests__/__snapshots__/ReferenceDatasetForm.spec.js.snap +61 -0
  58. package/src/components/__tests__/__snapshots__/ReferenceDatasetHeader.spec.js.snap +95 -0
  59. package/src/components/__tests__/__snapshots__/ReferenceDatasetRoutes.spec.js.snap +414 -0
  60. package/src/components/__tests__/__snapshots__/ReferenceDatasetTable.spec.js.snap +75 -0
  61. package/src/components/__tests__/__snapshots__/ReferenceDatasets.spec.js.snap +128 -0
  62. package/src/components/__tests__/__snapshots__/ReferenceDatasetsTable.spec.js.snap +86 -0
  63. package/src/components/__tests__/__snapshots__/StructureConfidentialButton.spec.js.snap +13 -33
  64. package/src/components/__tests__/__snapshots__/StructureProperties.spec.js.snap +76 -71
  65. package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +1 -1
  66. package/src/components/__tests__/__snapshots__/StructureVersionListItem.spec.js.snap +31 -64
  67. package/src/components/index.js +0 -6
  68. package/src/messages/en.js +18 -0
  69. package/src/messages/es.js +20 -0
  70. package/src/reducers/__tests__/ddMessage.spec.js +26 -5
  71. package/src/reducers/__tests__/graph.spec.js +1 -6
  72. package/src/reducers/__tests__/referenceDatasetSaving.spec.js +44 -0
  73. package/src/reducers/__tests__/structureRedirect.spec.js +37 -13
  74. package/src/reducers/ddMessage.js +26 -1
  75. package/src/reducers/index.js +2 -0
  76. package/src/reducers/referenceDatasetSaving.js +16 -0
  77. package/src/reducers/structureRedirect.js +36 -15
  78. package/src/reducers/structuresUploadEvents.js +0 -1
  79. package/src/routines.js +35 -74
  80. package/src/sagas/__tests__/createReferenceDataset.spec.js +90 -0
  81. package/src/sagas/__tests__/deleteReferenceDataset.spec.js +81 -0
  82. package/src/sagas/__tests__/updateReferenceDataset.spec.js +116 -0
  83. package/src/sagas/createReferenceDataset.js +34 -0
  84. package/src/sagas/deleteReferenceDataset.js +29 -0
  85. package/src/sagas/downloadReferenceDataset.js +44 -0
  86. package/src/sagas/index.js +31 -22
  87. package/src/sagas/updateReferenceDataset.js +35 -0
  88. package/src/selectors/getRelationSortingCriteria.js +3 -5
  89. package/src/selectors/getTabVisibility.js +1 -4
  90. package/src/components/ProfilingElements.js +0 -89
  91. package/src/components/ProfilingGraph.js +0 -89
  92. package/src/components/ProfilingPatterns.js +0 -57
  93. package/src/components/StructureProfiling.js +0 -124
  94. package/src/components/__tests__/StructureProfiling.spec.js +0 -45
  95. package/src/components/__tests__/__snapshots__/StructureProfiling.spec.js.snap +0 -444
@@ -1,89 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React, { useState } from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Label } from "semantic-ui-react";
6
- import { FormattedMessage } from "react-intl";
7
- import { XYPlot, XAxis, YAxis, HorizontalBarSeries, Hint } from "react-vis";
8
-
9
- const getDistribution = _.flow(
10
- _.pathOr("[]", "most_frequent"),
11
- _.map(({ k, v }) => ({ x: v, y: k })),
12
- _.orderBy("x", "desc"),
13
- _.take(30),
14
- _.reverse
15
- );
16
-
17
- const getMinMax = _.flow(
18
- _.map("x"),
19
- (d) => [_.min(d) - 1, _.max(d)],
20
- _.defaultTo([-Infinity, Infinity])
21
- );
22
-
23
- const formatNumber = (num) =>
24
- num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
25
-
26
- export const ProfilingGraph = ({ count, distribution }) => {
27
- const [hintValue, setHintValue] = useState(null);
28
- const data = _.map((d) => ({ color: d.y == hintValue?.y ? 0 : 1, ...d }))(
29
- distribution
30
- );
31
- return (
32
- <XYPlot
33
- yType="ordinal"
34
- xType="linear"
35
- width={800}
36
- height={400}
37
- margin={{ left: 180 }}
38
- xDomain={getMinMax(data)}
39
- colorRange={["#ed5c17", "#002057"]}
40
- >
41
- <YAxis
42
- tickFormat={_.truncate({ length: 30 })}
43
- style={{ fontSize: "12px", width: "100px" }}
44
- />
45
- <XAxis style={{ fontSize: "12px" }} />
46
- <HorizontalBarSeries
47
- onValueMouseOver={setHintValue}
48
- onValueMouseOut={() => setHintValue(null)}
49
- data={data}
50
- />
51
- {hintValue ? (
52
- <Hint
53
- style={{ width: "500px", bottom: "190px" }}
54
- align={{ horizontal: "right", vertical: "top" }}
55
- value={hintValue}
56
- >
57
- <Label pointing="left" className="graph">
58
- <div>
59
- <div>
60
- <FormattedMessage id="structure.field.graph.value" />
61
- {hintValue.y}
62
- </div>
63
- <div>
64
- <FormattedMessage id="structure.field.graph.count" />
65
- {formatNumber(hintValue.x)}
66
- </div>
67
- <div>
68
- <FormattedMessage id="structure.field.graph.percentage" />
69
- {Math.floor((hintValue.x / count) * 100) + "%"}
70
- </div>
71
- </div>
72
- </Label>
73
- </Hint>
74
- ) : null}
75
- </XYPlot>
76
- );
77
- };
78
-
79
- ProfilingGraph.propTypes = {
80
- count: PropTypes.number,
81
- distribution: PropTypes.arrayOf(PropTypes.object),
82
- };
83
-
84
- const mapStateToProps = ({ structureProfile }) => ({
85
- count: structureProfile?.total_count,
86
- distribution: getDistribution(structureProfile),
87
- });
88
-
89
- export default connect(mapStateToProps)(ProfilingGraph);
@@ -1,57 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Table } from "semantic-ui-react";
6
- import { useIntl } from "react-intl";
7
-
8
- export const ProfilingPatterns = ({ patterns, totalCount }) => {
9
- const { formatNumber, formatMessage } = useIntl();
10
- const dataPatterns = _.flow(
11
- _.orderBy("v", "desc"),
12
- _.map(({ k, v }) => ({
13
- frecuency: k,
14
- count: formatNumber(v),
15
- percentage: parseFloat(((v / totalCount) * 100).toFixed(2)),
16
- }))
17
- )(patterns);
18
-
19
- return !_.isEmpty(dataPatterns) ? (
20
- <Table>
21
- <Table.Header>
22
- <Table.Row>
23
- <Table.HeaderCell>
24
- {formatMessage({ id: "structure.field.patterns.frecuency" })}
25
- </Table.HeaderCell>
26
- <Table.HeaderCell>
27
- {formatMessage({ id: "structure.field.patterns.count" })}
28
- </Table.HeaderCell>
29
- <Table.HeaderCell>
30
- {formatMessage({ id: "structure.field.patterns.percentage" })}
31
- </Table.HeaderCell>
32
- </Table.Row>
33
- </Table.Header>
34
- <Table.Body>
35
- {dataPatterns.map((pattern, i) => (
36
- <Table.Row key={i}>
37
- <Table.Cell>{pattern.frecuency}</Table.Cell>
38
- <Table.Cell>{pattern.count}</Table.Cell>
39
- <Table.Cell>{`${pattern.percentage} %`}</Table.Cell>
40
- </Table.Row>
41
- ))}
42
- </Table.Body>
43
- </Table>
44
- ) : null;
45
- };
46
-
47
- ProfilingPatterns.propTypes = {
48
- patterns: PropTypes.array,
49
- totalCount: PropTypes.number,
50
- };
51
-
52
- const mapStateToProps = ({ structureProfile }) => ({
53
- patterns: structureProfile?.patterns,
54
- totalCount: structureProfile?.total_count,
55
- });
56
-
57
- export default connect(mapStateToProps)(ProfilingPatterns);
@@ -1,124 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Table } from "semantic-ui-react";
6
- import { useIntl } from "react-intl";
7
- import { Link } from "react-router-dom";
8
- import { linkTo } from "@truedat/core/routes";
9
- import { getSortedFields } from "../selectors";
10
- import ProfilingElements from "./ProfilingElements";
11
-
12
- const calculatePercent = (value_count, total_count) =>
13
- ((parseFloat(value_count) / parseFloat(total_count)) * 100).toFixed(2) + "%";
14
-
15
- const calculateUniquePercent = ({ unique_count, total_count }) =>
16
- calculatePercent(unique_count, total_count);
17
- const calculateNullPercent = ({ null_count, total_count }) =>
18
- calculatePercent(null_count, total_count);
19
-
20
- const calculateMode = (distribution) =>
21
- _.isEmpty(distribution)
22
- ? "-"
23
- : _.flow(_.orderBy("v", "desc"), _.head, _.prop("k"))(distribution);
24
-
25
- export const FieldProfileRow = ({ profile, data_structure_id, name }) => {
26
- const { unique_count, null_count, total_count, min, max, most_frequent } =
27
- profile;
28
- const uniquePercent =
29
- !_.isNil(unique_count) && !_.isNil(total_count) && total_count > 0
30
- ? calculateUniquePercent(profile)
31
- : "-";
32
- const nullPercent =
33
- !_.isNil(null_count) && !_.isNil(total_count)
34
- ? calculateNullPercent(profile)
35
- : "-";
36
-
37
- const maxLength = 50;
38
- const truncFn = _.truncate({ length: maxLength });
39
- const minValue = _.isNil(min) ? "-" : truncFn(min);
40
- const maxValue = _.isNil(max) ? "-" : truncFn(max);
41
- const minTitle = !_.isNil(min) && min.length > maxLength ? min : "";
42
- const maxTitle = !_.isNil(max) && max.length > maxLength ? max : "";
43
- const modeValue = _.isNil(most_frequent) ? "-" : calculateMode(most_frequent);
44
-
45
- return (
46
- <Table.Row>
47
- <Table.Cell>
48
- <Link
49
- to={
50
- _.isNil(most_frequent)
51
- ? linkTo.STRUCTURE({ id: data_structure_id })
52
- : linkTo.STRUCTURE_PROFILE({ id: data_structure_id })
53
- }
54
- >
55
- {name}
56
- </Link>
57
- </Table.Cell>
58
- <Table.Cell className="text-right" content={uniquePercent} />
59
- <Table.Cell className="text-right" content={nullPercent} />
60
- <Table.Cell>
61
- <span title={minTitle}> {minValue} </span>
62
- </Table.Cell>
63
- <Table.Cell>
64
- <span title={maxTitle}> {maxValue} </span>
65
- </Table.Cell>
66
- <Table.Cell content={modeValue} />
67
- </Table.Row>
68
- );
69
- };
70
-
71
- FieldProfileRow.propTypes = {
72
- data_structure_id: PropTypes.number,
73
- name: PropTypes.string,
74
- profile: PropTypes.object,
75
- };
76
-
77
- export const StructureProfiling = ({ fields }) => {
78
- const { formatMessage } = useIntl();
79
- return _.isEmpty(fields) ? (
80
- <ProfilingElements />
81
- ) : (
82
- <Table>
83
- <Table.Header>
84
- <Table.Row>
85
- <Table.HeaderCell
86
- content={formatMessage({ id: "profiling.field.name" })}
87
- />
88
- <Table.HeaderCell
89
- className="text-right"
90
- content={formatMessage({ id: "profiling.field.unique" })}
91
- />
92
- <Table.HeaderCell
93
- className="text-right"
94
- content={formatMessage({ id: "profiling.field.null" })}
95
- />
96
- <Table.HeaderCell
97
- content={formatMessage({ id: "profiling.field.min" })}
98
- />
99
- <Table.HeaderCell
100
- content={formatMessage({ id: "profiling.field.max" })}
101
- />
102
- <Table.HeaderCell
103
- content={formatMessage({ id: "profiling.field.mode" })}
104
- />
105
- </Table.Row>
106
- </Table.Header>
107
- <Table.Body>
108
- {fields.map((field, i) => (
109
- <FieldProfileRow key={i} {...field} />
110
- ))}
111
- </Table.Body>
112
- </Table>
113
- );
114
- };
115
-
116
- StructureProfiling.propTypes = {
117
- fields: PropTypes.array,
118
- };
119
-
120
- const mapStateToProps = (state) => ({
121
- fields: _.filter(_.has("profile"))(getSortedFields(state)),
122
- });
123
-
124
- export default connect(mapStateToProps)(StructureProfiling);
@@ -1,45 +0,0 @@
1
- import React from "react";
2
- import { render } from "@truedat/test/render";
3
- import StructureProfiling from "../StructureProfiling";
4
-
5
- const profile = {
6
- unique_count: 5,
7
- null_count: 2,
8
- total_count: 10,
9
- min: "33",
10
- max: "40",
11
- most_frequent: [
12
- { k: "foo", v: 10 },
13
- { k: "bar", v: 42 },
14
- ],
15
- };
16
-
17
- const messages = {
18
- en: {
19
- "profiling.field.max": "max",
20
- "profiling.field.min": "min",
21
- "profiling.field.mode": "mode",
22
- "profiling.field.name": "name",
23
- "profiling.field.null": "null",
24
- "profiling.field.unique": "unique",
25
- "structure.field.graph.title": "Frequency chart",
26
- },
27
- };
28
-
29
- describe("<StructureProfiling />", () => {
30
- it("matches the latest snapshot (fields)", () => {
31
- const structureFields = [
32
- { data_structure_id: 123, name: "field1", profile },
33
- { data_structure_id: 122, name: "field2", profile },
34
- ];
35
- const state = { structureFields };
36
- const { container } = render(<StructureProfiling />, { messages, state });
37
- expect(container).toMatchSnapshot();
38
- });
39
-
40
- it("matches the latest snapshot (profile)", () => {
41
- const state = { structureProfile: profile };
42
- const { container } = render(<StructureProfiling />, { messages, state });
43
- expect(container).toMatchSnapshot();
44
- });
45
- });