@truedat/dd 4.44.4 → 4.45.1

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 (30) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/package.json +24 -20
  3. package/src/components/EditDomainPopup.js +1 -1
  4. package/src/components/GrantFilters.js +1 -5
  5. package/src/components/PendingStructureNotes.js +1 -1
  6. package/src/components/StructureConfidentialButton.js +1 -1
  7. package/src/components/StructureFilters.js +1 -5
  8. package/src/components/StructureNotesEdit.js +6 -6
  9. package/src/components/StructureProperties.js +4 -1
  10. package/src/components/StructureTabPane.js +4 -2
  11. package/src/components/StructureVersionListItem.js +2 -2
  12. package/src/components/__tests__/LineageRoutes.spec.js +4 -4
  13. package/src/components/__tests__/StructureConfidentialButton.spec.js +26 -30
  14. package/src/components/__tests__/StructureNotesEdit.spec.js +2 -9
  15. package/src/components/__tests__/StructureProperties.spec.js +6 -8
  16. package/src/components/__tests__/StructureVersionListItem.spec.js +4 -4
  17. package/src/components/__tests__/__snapshots__/LineageRoutes.spec.js.snap +1 -20
  18. package/src/components/__tests__/__snapshots__/ProfileExecution.spec.js.snap +2 -1
  19. package/src/components/__tests__/__snapshots__/StructureConfidentialButton.spec.js.snap +13 -33
  20. package/src/components/__tests__/__snapshots__/StructureProperties.spec.js.snap +76 -71
  21. package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +1 -1
  22. package/src/components/__tests__/__snapshots__/StructureVersionListItem.spec.js.snap +31 -64
  23. package/src/components/index.js +0 -6
  24. package/src/selectors/getTabVisibility.js +1 -4
  25. package/src/components/ProfilingElements.js +0 -89
  26. package/src/components/ProfilingGraph.js +0 -89
  27. package/src/components/ProfilingPatterns.js +0 -57
  28. package/src/components/StructureProfiling.js +0 -124
  29. package/src/components/__tests__/StructureProfiling.spec.js +0 -45
  30. package/src/components/__tests__/__snapshots__/StructureProfiling.spec.js.snap +0 -444
@@ -1,96 +1,101 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<StructureProperties /> matches the latest snapshot (custom structureProperties) 1`] = `
4
- <Fragment>
4
+ <div>
5
5
  <p
6
- className="item-description"
6
+ class="item-description"
7
7
  />
8
- <Grid
9
- className="structure-properties"
10
- columns={5}
11
- divided={true}
8
+ <div
9
+ class="ui divided five column grid structure-properties"
12
10
  >
13
- <GridRow
14
- key="0"
11
+ <div
12
+ class="row"
15
13
  >
16
- <GridColumn
17
- key="0"
18
- width={3}
14
+ <div
15
+ class="three wide column"
19
16
  >
20
- <Item>
21
- <ItemContent>
22
- <ItemHeader
23
- as="h5"
17
+ <div
18
+ class="item"
19
+ >
20
+ <div
21
+ class="content"
22
+ >
23
+ <h5
24
+ class="header"
25
+ >
26
+ metadata.foo
27
+ </h5>
28
+ <div
29
+ class="description"
24
30
  >
25
- <MemoizedFormattedMessage
26
- id="structure.metadata.foo"
27
- />
28
- </ItemHeader>
29
- <ItemDescription>
30
31
  bar
31
- </ItemDescription>
32
- </ItemContent>
33
- </Item>
34
- </GridColumn>
35
- </GridRow>
36
- </Grid>
37
- </Fragment>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
38
39
  `;
39
40
 
40
41
  exports[`<StructureProperties /> matches the latest snapshot 1`] = `
41
- <Fragment>
42
+ <div>
42
43
  <p
43
- className="item-description"
44
+ class="item-description"
44
45
  >
45
46
  dd
46
47
  </p>
47
- <Grid
48
- className="structure-properties"
49
- columns={5}
50
- divided={true}
48
+ <div
49
+ class="ui divided five column grid structure-properties"
51
50
  >
52
- <GridRow
53
- key="0"
51
+ <div
52
+ class="row"
54
53
  >
55
- <GridColumn
56
- key="0"
57
- width={3}
54
+ <div
55
+ class="three wide column"
58
56
  >
59
- <Item>
60
- <ItemContent>
61
- <ItemHeader
62
- as="h5"
57
+ <div
58
+ class="item"
59
+ >
60
+ <div
61
+ class="content"
62
+ >
63
+ <h5
64
+ class="header"
65
+ >
66
+ Domain
67
+ </h5>
68
+ <div
69
+ class="description"
63
70
  >
64
- <MemoizedFormattedMessage
65
- id="structure.domain"
66
- />
67
- </ItemHeader>
68
- <ItemDescription>
69
- <Connect(EditDomainPopup) />
70
- </ItemDescription>
71
- </ItemContent>
72
- </Item>
73
- </GridColumn>
74
- <GridColumn
75
- key="1"
76
- width={3}
71
+
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ <div
77
+ class="three wide column"
77
78
  >
78
- <Item>
79
- <ItemContent>
80
- <ItemHeader
81
- as="h5"
79
+ <div
80
+ class="item"
81
+ >
82
+ <div
83
+ class="content"
84
+ >
85
+ <h5
86
+ class="header"
87
+ >
88
+ Group
89
+ </h5>
90
+ <div
91
+ class="description"
82
92
  >
83
- <MemoizedFormattedMessage
84
- id="structure.group"
85
- />
86
- </ItemHeader>
87
- <ItemDescription>
88
93
  gp
89
- </ItemDescription>
90
- </ItemContent>
91
- </Item>
92
- </GridColumn>
93
- </GridRow>
94
- </Grid>
95
- </Fragment>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
96
101
  `;
@@ -55,7 +55,7 @@ exports[`<StructureTabPane /> matches the latest snapshot: notes 1`] = `
55
55
 
56
56
  exports[`<StructureTabPane /> matches the latest snapshot: profile 1`] = `
57
57
  <ErrorBoundary>
58
- <Connect(StructureProfiling) />
58
+ <lazy />
59
59
  </ErrorBoundary>
60
60
  `;
61
61
 
@@ -1,68 +1,35 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<StructureVersionListItem /> matches the latest snapshot 1`] = `
4
- <ListItem
5
- as={
6
- Object {
7
- "$$typeof": Symbol(react.forward_ref),
8
- "displayName": "Link",
9
- "propTypes": Object {
10
- "innerRef": [Function],
11
- "onClick": [Function],
12
- "replace": [Function],
13
- "target": [Function],
14
- "to": [Function],
15
- },
16
- "render": [Function],
17
- }
18
- }
19
- to="/structures/123/versions/42"
20
- >
21
- <ListIcon
22
- name="history"
23
- size="large"
24
- verticalAlign="middle"
25
- />
26
- <ListContent>
27
- <ListHeader>
28
- <MemoizedFormattedMessage
29
- id="structure.version.version"
30
- values={
31
- Object {
32
- "version": 42,
33
- }
34
- }
35
- />
36
- </ListHeader>
37
- <ListDescription>
38
- <MemoizedFormattedMessage
39
- id="structure.version.inserted_at"
40
- values={
41
- Object {
42
- "when": <t
43
- ago={false}
44
- calendar={false}
45
- date="2018-01-01T01:01:01.123456Z"
46
- decimal={false}
47
- element={null}
48
- filter={[Function]}
49
- format="YYYY-MM-DD HH:mm"
50
- fromNow={false}
51
- interval={60000}
52
- local={false}
53
- locale="es"
54
- onChange={[Function]}
55
- titleFormat=""
56
- toNow={false}
57
- unit={null}
58
- unix={false}
59
- utc={false}
60
- withTitle={false}
61
- />,
62
- }
63
- }
64
- />
65
- </ListDescription>
66
- </ListContent>
67
- </ListItem>
4
+ <div>
5
+ <a
6
+ class="item"
7
+ href="/structures/123/versions/42"
8
+ role="listitem"
9
+ >
10
+ <i
11
+ aria-hidden="true"
12
+ class="history large icon middle aligned"
13
+ />
14
+ <div
15
+ class="content"
16
+ >
17
+ <div
18
+ class="header"
19
+ >
20
+ Version 42
21
+ </div>
22
+ <div
23
+ class="description"
24
+ >
25
+ Imported
26
+ <time
27
+ datetime="1514768461123"
28
+ >
29
+ 2018-01-01 01:01
30
+ </time>
31
+ </div>
32
+ </div>
33
+ </a>
34
+ </div>
68
35
  `;
@@ -8,8 +8,6 @@ import LineageDownloadButton from "./LineageDownloadButton";
8
8
  import LineageGroup from "./LineageGroup";
9
9
  import LineageLink from "./LineageLink";
10
10
  import LineageRoutes from "./LineageRoutes";
11
- import ProfilingGraph from "./ProfilingGraph";
12
- import ProfilingPatterns from "./ProfilingPatterns";
13
11
  import StructureCrumbs from "./StructureCrumbs";
14
12
  import StructureEvents from "./StructureEvents";
15
13
  import StructureFieldRow from "./StructureFieldRow";
@@ -23,7 +21,6 @@ import StructureLoader from "./StructureLoader";
23
21
  import StructureNav from "./StructureNav";
24
22
  import StructureNotes from "./StructureNotes";
25
23
  import StructureNotesEdit from "./StructureNotesEdit";
26
- import StructureProfiling from "./StructureProfiling";
27
24
  import StructureProperties from "./StructureProperties";
28
25
  import StructureRow from "./StructureRow";
29
26
  import StructureSelectedFilters from "./StructureSelectedFilters";
@@ -64,8 +61,6 @@ export {
64
61
  LineageGroup,
65
62
  LineageLink,
66
63
  LineageRoutes,
67
- ProfilingGraph,
68
- ProfilingPatterns,
69
64
  StructureCrumbs,
70
65
  StructureEvents,
71
66
  StructureFieldRow,
@@ -79,7 +74,6 @@ export {
79
74
  StructureNav,
80
75
  StructureNotes,
81
76
  StructureNotesEdit,
82
- StructureProfiling,
83
77
  StructureProperties,
84
78
  StructureMetadata,
85
79
  StructureRow,
@@ -42,10 +42,7 @@ const impactTabVisible = _.anyPass([_.path("structure.degree.out")]);
42
42
  const parentsTabVisible = _.conformsTo({ parentRelations: notEmpty });
43
43
  const childrenTabVisible = _.conformsTo({ childrenRelations: notEmpty });
44
44
  const eventsTabVisible = _.flow(_.prop("structureVersion"), _.isEmpty);
45
- const grantsTabVisible = _.flow(
46
- _.path("structure.grants"),
47
- _.negate(_.isEmpty)
48
- );
45
+ const grantsTabVisible = _.flow(_.path("structure.grants"), notEmpty);
49
46
 
50
47
  export const getTabVisibility = (state) => ({
51
48
  fields: fieldsTabVisible(state),
@@ -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 { Button, Icon, Grid } from "semantic-ui-react";
6
- import { FormattedMessage } from "react-intl";
7
- import ProfilingGraph from "./ProfilingGraph";
8
- import ProfilingPatterns from "./ProfilingPatterns";
9
-
10
- export const ProfilingElements = ({ profile }) => {
11
- const { most_frequent, patterns } = profile || {};
12
- const [elementActive, setElementActive] = useState("graph");
13
- const titleElement =
14
- elementActive === "graph"
15
- ? "structure.field.graph.title"
16
- : "structure.field.patterns.title";
17
- return (
18
- <>
19
- {!_.isEmpty(most_frequent) && !_.isEmpty(patterns) && (
20
- <>
21
- <Grid>
22
- <Grid.Column width={8}>
23
- <p>
24
- <FormattedMessage id={titleElement} />:
25
- </p>
26
- </Grid.Column>
27
- <Grid.Column width={8} textAlign="right">
28
- <Button.Group floated="right">
29
- <Button
30
- active={elementActive === "graph"}
31
- icon
32
- onClick={() => setElementActive("graph")}
33
- >
34
- <Icon name="chart line" />
35
- </Button>
36
- <Button
37
- active={elementActive === "patterns"}
38
- icon
39
- onClick={() => setElementActive("patterns")}
40
- >
41
- <Icon name="list ul" />
42
- </Button>
43
- </Button.Group>
44
- </Grid.Column>
45
- </Grid>
46
-
47
- {elementActive === "graph" && <ProfilingGraph />}
48
- {elementActive === "patterns" && <ProfilingPatterns />}
49
- </>
50
- )}
51
-
52
- {!_.isEmpty(most_frequent) && _.isEmpty(patterns) && (
53
- <>
54
- <Grid>
55
- <Grid.Column width={16}>
56
- <p>
57
- <FormattedMessage id="structure.field.graph.title" />:
58
- </p>
59
- </Grid.Column>
60
- </Grid>
61
-
62
- <ProfilingGraph />
63
- </>
64
- )}
65
-
66
- {_.isEmpty(most_frequent) && !_.isEmpty(patterns) && (
67
- <>
68
- <Grid>
69
- <Grid.Column width={16}>
70
- <p>
71
- <FormattedMessage id="structure.field.patterns.title" />
72
- </p>
73
- </Grid.Column>
74
- </Grid>
75
-
76
- <ProfilingPatterns />
77
- </>
78
- )}
79
- </>
80
- );
81
- };
82
-
83
- ProfilingElements.propTypes = {
84
- profile: PropTypes.object,
85
- };
86
-
87
- const mapStateToProps = ({ structureProfile: profile }) => ({ profile });
88
-
89
- export default connect(mapStateToProps)(ProfilingElements);
@@ -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);