@truedat/dd 4.44.5 → 4.45.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/CHANGELOG.md +7 -1
- package/package.json +7 -7
- package/src/components/StructureCrumbs.js +28 -11
- package/src/components/StructureItem.js +2 -1
- package/src/components/StructureSummary.js +7 -9
- package/src/components/StructureTabPane.js +4 -2
- package/src/components/__tests__/StructureItem.spec.js +23 -6
- package/src/components/__tests__/StructureItems.spec.js +14 -4
- package/src/components/__tests__/StructureProperties.spec.js +1 -1
- package/src/components/__tests__/StructureSummary.spec.js +13 -0
- package/src/components/__tests__/__snapshots__/StructureItem.spec.js.snap +68 -43
- package/src/components/__tests__/__snapshots__/StructureItems.spec.js.snap +47 -4
- package/src/components/__tests__/__snapshots__/StructureProperties.spec.js.snap +22 -0
- package/src/components/__tests__/__snapshots__/StructureSummary.spec.js.snap +102 -11
- package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +1 -1
- package/src/components/index.js +0 -6
- package/src/reducers/structure.js +1 -0
- package/src/reducers/structures.js +2 -0
- package/src/selectors/__tests__/getStructureParent.spec.js +13 -4
- package/src/selectors/__tests__/getStructureProperties.spec.js +2 -2
- package/src/selectors/getSortedStructureChildren.js +1 -1
- package/src/selectors/getStructureFieldColumns.js +20 -14
- package/src/selectors/getStructureParent.js +9 -4
- package/src/selectors/getStructureProperties.js +12 -0
- package/src/selectors/structureColumnsSelector.js +11 -3
- package/src/components/ProfilingElements.js +0 -89
- package/src/components/ProfilingGraph.js +0 -89
- package/src/components/ProfilingPatterns.js +0 -57
- package/src/components/StructureProfiling.js +0 -124
- package/src/components/__tests__/StructureProfiling.spec.js +0 -45
- package/src/components/__tests__/__snapshots__/StructureProfiling.spec.js.snap +0 -444
|
@@ -16,8 +16,65 @@ exports[`<StructureSummary /> matches the latest snapshot 1`] = `
|
|
|
16
16
|
<HeaderContent>
|
|
17
17
|
s1
|
|
18
18
|
<Connect(StructureGrantRequestButton) />
|
|
19
|
+
</HeaderContent>
|
|
20
|
+
</Header>
|
|
21
|
+
<Dimmer
|
|
22
|
+
active={false}
|
|
23
|
+
inverted={true}
|
|
24
|
+
>
|
|
25
|
+
<Loader />
|
|
26
|
+
</Dimmer>
|
|
27
|
+
</DimmerDimmable>
|
|
28
|
+
</GridColumn>
|
|
29
|
+
<GridColumn
|
|
30
|
+
textAlign="right"
|
|
31
|
+
width={6}
|
|
32
|
+
>
|
|
33
|
+
<Date
|
|
34
|
+
className="alert warning"
|
|
35
|
+
date="2019-01-02T03:04:05Z"
|
|
36
|
+
icon={
|
|
37
|
+
<Icon
|
|
38
|
+
as="i"
|
|
39
|
+
color="red"
|
|
40
|
+
name="warning circle"
|
|
41
|
+
/>
|
|
42
|
+
}
|
|
43
|
+
label="deleted_at"
|
|
44
|
+
/>
|
|
45
|
+
<Connect(ShareLinkPopup)
|
|
46
|
+
description="dd"
|
|
47
|
+
name="s1"
|
|
48
|
+
title="structure.share.title"
|
|
49
|
+
url="http://localhost/"
|
|
50
|
+
/>
|
|
51
|
+
<injectIntl(Connect(StructureConfidentialButton)) />
|
|
52
|
+
</GridColumn>
|
|
53
|
+
</GridRow>
|
|
54
|
+
</Grid>
|
|
55
|
+
<Connect(TagsHeader) />
|
|
56
|
+
<Connect(StructureProperties) />
|
|
57
|
+
</Fragment>
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
exports[`<StructureSummary /> matches the latest snapshot with alias 1`] = `
|
|
61
|
+
<Fragment>
|
|
62
|
+
<Grid>
|
|
63
|
+
<GridRow>
|
|
64
|
+
<GridColumn
|
|
65
|
+
width={10}
|
|
66
|
+
>
|
|
67
|
+
<DimmerDimmable
|
|
68
|
+
dimmed={false}
|
|
69
|
+
>
|
|
70
|
+
<Header
|
|
71
|
+
as="h2"
|
|
72
|
+
>
|
|
73
|
+
<HeaderContent>
|
|
74
|
+
some alias
|
|
75
|
+
<Connect(StructureGrantRequestButton) />
|
|
19
76
|
<HeaderSubheader>
|
|
20
|
-
|
|
77
|
+
s1
|
|
21
78
|
</HeaderSubheader>
|
|
22
79
|
</HeaderContent>
|
|
23
80
|
</Header>
|
|
@@ -84,11 +141,6 @@ exports[`<StructureSummary /> renders custom grant label when grant provided 1`]
|
|
|
84
141
|
<p>
|
|
85
142
|
bar
|
|
86
143
|
</p>
|
|
87
|
-
<div
|
|
88
|
-
class="sub header"
|
|
89
|
-
>
|
|
90
|
-
foo
|
|
91
|
-
</div>
|
|
92
144
|
</div>
|
|
93
145
|
</h2>
|
|
94
146
|
<div
|
|
@@ -198,6 +250,28 @@ exports[`<StructureSummary /> renders custom grant label when grant provided 1`]
|
|
|
198
250
|
</div>
|
|
199
251
|
</div>
|
|
200
252
|
</div>
|
|
253
|
+
<div
|
|
254
|
+
class="three wide column"
|
|
255
|
+
>
|
|
256
|
+
<div
|
|
257
|
+
class="item"
|
|
258
|
+
>
|
|
259
|
+
<div
|
|
260
|
+
class="content"
|
|
261
|
+
>
|
|
262
|
+
<h5
|
|
263
|
+
class="header"
|
|
264
|
+
>
|
|
265
|
+
structure.type
|
|
266
|
+
</h5>
|
|
267
|
+
<div
|
|
268
|
+
class="description"
|
|
269
|
+
>
|
|
270
|
+
foo
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</div>
|
|
201
275
|
</div>
|
|
202
276
|
</div>
|
|
203
277
|
</div>
|
|
@@ -233,11 +307,6 @@ exports[`<StructureSummary /> renders label when grant provided 1`] = `
|
|
|
233
307
|
/>
|
|
234
308
|
structure.grant.has_grant
|
|
235
309
|
</div>
|
|
236
|
-
<div
|
|
237
|
-
class="sub header"
|
|
238
|
-
>
|
|
239
|
-
foo
|
|
240
|
-
</div>
|
|
241
310
|
</div>
|
|
242
311
|
</h2>
|
|
243
312
|
<div
|
|
@@ -347,6 +416,28 @@ exports[`<StructureSummary /> renders label when grant provided 1`] = `
|
|
|
347
416
|
</div>
|
|
348
417
|
</div>
|
|
349
418
|
</div>
|
|
419
|
+
<div
|
|
420
|
+
class="three wide column"
|
|
421
|
+
>
|
|
422
|
+
<div
|
|
423
|
+
class="item"
|
|
424
|
+
>
|
|
425
|
+
<div
|
|
426
|
+
class="content"
|
|
427
|
+
>
|
|
428
|
+
<h5
|
|
429
|
+
class="header"
|
|
430
|
+
>
|
|
431
|
+
structure.type
|
|
432
|
+
</h5>
|
|
433
|
+
<div
|
|
434
|
+
class="description"
|
|
435
|
+
>
|
|
436
|
+
foo
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
350
441
|
</div>
|
|
351
442
|
</div>
|
|
352
443
|
</div>
|
package/src/components/index.js
CHANGED
|
@@ -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,
|
|
@@ -2,24 +2,33 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import { getStructureParent } from "..";
|
|
3
3
|
|
|
4
4
|
const structureParents = [
|
|
5
|
-
{
|
|
5
|
+
{
|
|
6
|
+
id: "1",
|
|
7
|
+
name: "structure",
|
|
8
|
+
type: "structure type",
|
|
9
|
+
published_note: { alias: "alias" },
|
|
10
|
+
},
|
|
6
11
|
];
|
|
7
12
|
const system = { id: "1", name: "system", type: "system" };
|
|
8
13
|
|
|
9
14
|
const structure = {
|
|
10
15
|
id: "1",
|
|
11
16
|
name: "structure",
|
|
12
|
-
system: _.omit(["type"])(system)
|
|
17
|
+
system: _.omit(["type"])(system),
|
|
13
18
|
};
|
|
14
19
|
|
|
15
20
|
describe("selectors: getStructureParent", () => {
|
|
16
21
|
const state = {
|
|
17
22
|
structureParents,
|
|
18
|
-
structure
|
|
23
|
+
structure,
|
|
19
24
|
};
|
|
20
25
|
|
|
21
26
|
it("get structure parent from state when is not empty", () => {
|
|
22
|
-
const reply = _.flow(
|
|
27
|
+
const reply = _.flow(
|
|
28
|
+
_.head,
|
|
29
|
+
_.set("name", ".."),
|
|
30
|
+
_.omit("published_note")
|
|
31
|
+
)(structureParents);
|
|
23
32
|
expect(getStructureParent(state)).toEqual(reply);
|
|
24
33
|
});
|
|
25
34
|
|
|
@@ -10,9 +10,9 @@ describe("selectors: getStructureProperties", () => {
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
describe("selectors: getStructureProperties", () => {
|
|
13
|
-
it("should return
|
|
13
|
+
it("should return default properties when present", () => {
|
|
14
14
|
const res = getStructureProperties({});
|
|
15
|
-
expect(res).toHaveLength(
|
|
15
|
+
expect(res).toHaveLength(3);
|
|
16
16
|
expect(res).toEqual(defaultStructureProperties);
|
|
17
17
|
});
|
|
18
18
|
});
|
|
@@ -7,25 +7,31 @@ import { Link } from "react-router-dom";
|
|
|
7
7
|
import { linkTo } from "@truedat/core/routes";
|
|
8
8
|
import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
|
|
9
9
|
|
|
10
|
-
const translateDecorator = text => <FormattedMessage id={text} />;
|
|
10
|
+
const translateDecorator = (text) => <FormattedMessage id={text} />;
|
|
11
11
|
|
|
12
12
|
const translateDecoratorWithDefault = (text, default_text) => (
|
|
13
13
|
<FormattedMessage id={text} defaultMessage={default_text} />
|
|
14
14
|
);
|
|
15
15
|
|
|
16
|
-
const typeDecorator = field =>
|
|
16
|
+
const typeDecorator = (field) =>
|
|
17
17
|
translateDecoratorWithDefault(`structure.type.${field}`, field);
|
|
18
18
|
|
|
19
|
-
const linkToStructureDecorator = ({
|
|
20
|
-
|
|
19
|
+
const linkToStructureDecorator = ({
|
|
20
|
+
data_structure_id: id,
|
|
21
|
+
name,
|
|
22
|
+
published_note,
|
|
23
|
+
}) => (
|
|
24
|
+
<Link to={linkTo.STRUCTURE({ id })}>
|
|
25
|
+
{_.isEmpty(published_note?.alias) ? name : published_note.alias}
|
|
26
|
+
</Link>
|
|
21
27
|
);
|
|
22
28
|
|
|
23
|
-
const nullableDecorator = field =>
|
|
29
|
+
const nullableDecorator = (field) =>
|
|
24
30
|
field
|
|
25
31
|
? translateDecorator("structure.field.nullable.true")
|
|
26
32
|
: translateDecorator("structure.field.nullable.false");
|
|
27
33
|
|
|
28
|
-
const hasDfContentDecorator = has_df_content =>
|
|
34
|
+
const hasDfContentDecorator = (has_df_content) =>
|
|
29
35
|
has_df_content && translateDecorator("structure.field.nullable.true");
|
|
30
36
|
|
|
31
37
|
const lineageLinkDecorator = ({ degree, data_structure_id: id }) =>
|
|
@@ -42,7 +48,7 @@ const lineageLinkDecorator = ({ degree, data_structure_id: id }) =>
|
|
|
42
48
|
</Link>
|
|
43
49
|
);
|
|
44
50
|
|
|
45
|
-
export const linksDecorator = links => {
|
|
51
|
+
export const linksDecorator = (links) => {
|
|
46
52
|
const sortedLinks = _.sortBy(accentInsensitivePathOrder("name"))(links);
|
|
47
53
|
return (
|
|
48
54
|
!_.isEmpty(sortedLinks) && (
|
|
@@ -52,7 +58,7 @@ export const linksDecorator = links => {
|
|
|
52
58
|
<Link
|
|
53
59
|
to={linkTo.CONCEPT_VERSION({
|
|
54
60
|
business_concept_id: resource.resource_id,
|
|
55
|
-
id: "current"
|
|
61
|
+
id: "current",
|
|
56
62
|
})}
|
|
57
63
|
>
|
|
58
64
|
{resource.name}
|
|
@@ -67,8 +73,8 @@ export const linksDecorator = links => {
|
|
|
67
73
|
export const defaultStructureFieldColumns = [
|
|
68
74
|
{
|
|
69
75
|
name: "name",
|
|
70
|
-
fieldSelector: _.pick(["data_structure_id", "name"]),
|
|
71
|
-
fieldDecorator: linkToStructureDecorator
|
|
76
|
+
fieldSelector: _.pick(["data_structure_id", "name", "published_note"]),
|
|
77
|
+
fieldDecorator: linkToStructureDecorator,
|
|
72
78
|
},
|
|
73
79
|
{ name: "type", fieldDecorator: typeDecorator },
|
|
74
80
|
{ name: "precision" },
|
|
@@ -76,18 +82,18 @@ export const defaultStructureFieldColumns = [
|
|
|
76
82
|
{ name: "description" },
|
|
77
83
|
{
|
|
78
84
|
name: "has_df_content",
|
|
79
|
-
fieldDecorator: hasDfContentDecorator
|
|
85
|
+
fieldDecorator: hasDfContentDecorator,
|
|
80
86
|
},
|
|
81
87
|
{
|
|
82
88
|
name: "degree",
|
|
83
89
|
fieldSelector: _.pick(["degree", "data_structure_id"]),
|
|
84
90
|
fieldDecorator: lineageLinkDecorator,
|
|
85
|
-
textAlign: "center"
|
|
91
|
+
textAlign: "center",
|
|
86
92
|
},
|
|
87
93
|
{
|
|
88
94
|
name: "links",
|
|
89
|
-
fieldDecorator: linksDecorator
|
|
90
|
-
}
|
|
95
|
+
fieldDecorator: linksDecorator,
|
|
96
|
+
},
|
|
91
97
|
];
|
|
92
98
|
|
|
93
99
|
export const getStructureFieldColumns = createSelector(
|
|
@@ -3,16 +3,21 @@ import { createSelector } from "reselect";
|
|
|
3
3
|
|
|
4
4
|
const defaultName = "..";
|
|
5
5
|
|
|
6
|
-
const systemNavItem = structure =>
|
|
6
|
+
const systemNavItem = (structure) =>
|
|
7
7
|
_.flow(
|
|
8
8
|
_.propOr({}, "system"),
|
|
9
9
|
_.pick(["id", "name"]),
|
|
10
10
|
_.set("type", "system"),
|
|
11
|
-
_.set("name", defaultName)
|
|
11
|
+
_.set("name", defaultName),
|
|
12
|
+
_.omit(["published_note"])
|
|
12
13
|
)(structure);
|
|
13
14
|
|
|
14
|
-
const structureNavItem = structures =>
|
|
15
|
-
_.flow(
|
|
15
|
+
const structureNavItem = (structures) =>
|
|
16
|
+
_.flow(
|
|
17
|
+
_.head,
|
|
18
|
+
_.set("name", defaultName),
|
|
19
|
+
_.omit(["published_note"])
|
|
20
|
+
)(structures);
|
|
16
21
|
|
|
17
22
|
export const getStructureParent = createSelector(
|
|
18
23
|
[_.propOr({}, "structure"), _.propOr([], "structureParents")],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { createSelector } from "reselect";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
4
5
|
import EditDomainPopup from "../components/EditDomainPopup";
|
|
5
6
|
|
|
6
7
|
const domainDecorator = (domainNames) => (
|
|
@@ -10,6 +11,12 @@ const domainDecorator = (domainNames) => (
|
|
|
10
11
|
</>
|
|
11
12
|
);
|
|
12
13
|
|
|
14
|
+
const typeDecorator = ({ type, data_structure_type }) => (
|
|
15
|
+
<FormattedMessage
|
|
16
|
+
id={`structure.type.${type}.text`}
|
|
17
|
+
defaultMessage={_.get("translation")(data_structure_type) || type}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
13
20
|
export const defaultStructureProperties = [
|
|
14
21
|
{
|
|
15
22
|
name: "domain",
|
|
@@ -17,6 +24,11 @@ export const defaultStructureProperties = [
|
|
|
17
24
|
fieldDecorator: domainDecorator,
|
|
18
25
|
},
|
|
19
26
|
{ name: "group" },
|
|
27
|
+
{
|
|
28
|
+
name: "type",
|
|
29
|
+
fieldSelector: _.pick(["type", "data_structure_type"]),
|
|
30
|
+
fieldDecorator: typeDecorator,
|
|
31
|
+
},
|
|
20
32
|
];
|
|
21
33
|
|
|
22
34
|
export const getStructureProperties = createSelector(
|
|
@@ -14,9 +14,15 @@ const typeTranslateDecorator = ({ type, data_structure_type }) => (
|
|
|
14
14
|
const dateDecorator = (date) => (
|
|
15
15
|
<Moment locale="es" date={date} format="YYYY-MM-DD HH:mm" />
|
|
16
16
|
);
|
|
17
|
-
|
|
17
|
+
const nameFieldSelector = ({ name, published_note }) =>
|
|
18
|
+
_.isEmpty(published_note?.alias) ? name : published_note.alias;
|
|
18
19
|
export const defaultStructureColumns = [
|
|
19
|
-
{
|
|
20
|
+
{
|
|
21
|
+
name: "name",
|
|
22
|
+
fieldSelector: nameFieldSelector,
|
|
23
|
+
sort: { name: "name.sort" },
|
|
24
|
+
width: 2,
|
|
25
|
+
},
|
|
20
26
|
{
|
|
21
27
|
name: "type",
|
|
22
28
|
fieldSelector: _.pick(["type", "data_structure_type"]),
|
|
@@ -82,5 +88,7 @@ export const structureRowsSelector = createSelector(
|
|
|
82
88
|
getStructures,
|
|
83
89
|
getStructureColumnNames,
|
|
84
90
|
(structures, columnNames) =>
|
|
85
|
-
_.map(_.pick([...columnNames, "id", "domain_id"]))(
|
|
91
|
+
_.map(_.pick([...columnNames, "id", "domain_id", "published_note"]))(
|
|
92
|
+
structures
|
|
93
|
+
)
|
|
86
94
|
);
|
|
@@ -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);
|