@truedat/dq 6.8.8 → 6.8.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dq",
3
- "version": "6.8.8",
3
+ "version": "6.8.9",
4
4
  "description": "Truedat Web Data Quality Module",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -92,8 +92,8 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "@apollo/client": "^3.7.1",
95
- "@truedat/core": "6.8.6",
96
- "@truedat/df": "6.8.6",
95
+ "@truedat/core": "6.8.9",
96
+ "@truedat/df": "6.8.9",
97
97
  "decode-uri-component": "^0.2.2",
98
98
  "graphql": "^15.5.3",
99
99
  "moment": "^2.29.4",
@@ -118,5 +118,5 @@
118
118
  "react-dom": ">= 16.8.6 < 17",
119
119
  "semantic-ui-react": ">= 2.0.3 < 2.2"
120
120
  },
121
- "gitHead": "8b5f95c2dd85e395d3f8e9e38249875702ee7a10"
121
+ "gitHead": "9dd7fa68422d3261185c3a6b9d618217a3e57bec"
122
122
  }
@@ -1,29 +1,163 @@
1
+ import _ from "lodash/fp";
1
2
  import React from "react";
2
3
  import PropTypes from "prop-types";
3
4
  import { connect } from "react-redux";
4
- import { Segment } from "semantic-ui-react";
5
- import { getImplementationStructureLinksColumns } from "../selectors";
6
- import ImplementationStructureLinksActions from "./ImplementationStructureLinksActions";
7
-
8
- const LinksPane = React.lazy(() => import("@truedat/lm/components/LinksPane"));
9
-
10
- export const ImplementationStructures = ({ groups }) => (
11
- <Segment attached="bottom">
12
- <LinksPane
13
- groups={groups}
14
- sourceType="implementations"
15
- targetType="structure"
16
- linksActions={<ImplementationStructureLinksActions />}
17
- />
18
- </Segment>
5
+ import {
6
+ Button,
7
+ Grid,
8
+ Header,
9
+ Icon,
10
+ List,
11
+ Segment,
12
+ Table,
13
+ } from "semantic-ui-react";
14
+ import { FormattedMessage } from "react-intl";
15
+ import { Link } from "react-router-dom";
16
+ import { linkTo } from "@truedat/core/routes";
17
+ import { columnDecorator } from "@truedat/core/services";
18
+ import ImplementationStructureDelete from "./ImplementationStructureDelete";
19
+ import ImplementationStructureLink from "./ImplementationStructureLink";
20
+
21
+ const ImplementationStructureDeleteDecorator = ({ id, implementation_id }) => (
22
+ <ImplementationStructureDelete id={id} implementationId={implementation_id} />
23
+ );
24
+ ImplementationStructureDeleteDecorator.propTypes = {
25
+ id: PropTypes.number,
26
+ implementation_id: PropTypes.number,
27
+ };
28
+
29
+ const DomainDecorator = (domains) => (
30
+ <List>
31
+ {domains.map(({ name, parents }, i) => (
32
+ <List.Item key={i}>
33
+ {_.flow(_.map("name"), _.union([name]), _.join(" > "))(parents)}
34
+ </List.Item>
35
+ ))}
36
+ </List>
37
+ );
38
+
39
+ DomainDecorator.propTypes = {
40
+ domains: PropTypes.array,
41
+ };
42
+
43
+ const PathDecorator = (path) => (
44
+ <span title={_.join(" › ")(path)}>
45
+ {_.flow(_.join(" › "), _.truncate({ length: 90 }))(path)}
46
+ </span>
47
+ );
48
+ PathDecorator.propTypes = {
49
+ path: PropTypes.string,
50
+ };
51
+
52
+ const ImplementationStructureTypeDecorator = (type) => (
53
+ <FormattedMessage id={`implementationsStructures.type.${type}`} />
19
54
  );
55
+ ImplementationStructureTypeDecorator.propTypes = {
56
+ type: PropTypes.string,
57
+ };
58
+
59
+ export const ImplementationStructures = ({ implementation, canCreateLink }) => {
60
+ const deleteColumn = canCreateLink
61
+ ? [
62
+ {
63
+ fieldSelector: _.identity,
64
+ fieldDecorator: ImplementationStructureDeleteDecorator,
65
+ },
66
+ ]
67
+ : [];
68
+
69
+ const columns = [
70
+ {
71
+ header: "structure.name",
72
+ fieldSelector: _.path("data_structure"),
73
+ fieldDecorator: ImplementationStructureLink,
74
+ },
75
+ {
76
+ header: "structure.domain",
77
+ fieldSelector: _.path("data_structure.domains"),
78
+ fieldDecorator: DomainDecorator,
79
+ },
80
+ {
81
+ header: "structure.system",
82
+ fieldSelector: _.path("data_structure.system.name"),
83
+ },
84
+ {
85
+ header: "structure.path",
86
+ fieldSelector: _.path("data_structure.current_version.path"),
87
+ fieldDecorator: PathDecorator,
88
+ },
89
+ {
90
+ header: "implementationsStructures.type",
91
+ fieldSelector: _.path("type"),
92
+ fieldDecorator: ImplementationStructureTypeDecorator,
93
+ },
94
+ ...deleteColumn,
95
+ ];
96
+
97
+ const headerRow = columns.map(({ header }, key) => (
98
+ <Table.HeaderCell
99
+ key={key}
100
+ content={header ? <FormattedMessage id={header} /> : null}
101
+ />
102
+ ));
103
+
104
+ const implementation_id = _.prop("id")(implementation);
105
+
106
+ return (
107
+ <Segment attached="bottom">
108
+ <Grid>
109
+ {implementation_id && canCreateLink && (
110
+ <Grid.Column width={16}>
111
+ <Button
112
+ floated="right"
113
+ primary
114
+ as={Link}
115
+ to={linkTo.IMPLEMENTATION_STRUCTURES_NEW({
116
+ implementation_id,
117
+ })}
118
+ content={<FormattedMessage id="links.actions.create" />}
119
+ />
120
+ </Grid.Column>
121
+ )}
122
+ {!_.isEmpty(implementation?.data_structures) ? (
123
+ <Grid.Column width={16}>
124
+ <Table
125
+ headerRow={headerRow}
126
+ renderBodyRow={(link, i) => (
127
+ <Table.Row key={i}>
128
+ {columns.map((column, ci) => (
129
+ <Table.Cell
130
+ key={ci}
131
+ textAlign={_.prop("textAlign")(column)}
132
+ content={columnDecorator(column)(link)}
133
+ />
134
+ ))}
135
+ </Table.Row>
136
+ )}
137
+ tableData={implementation?.data_structures}
138
+ />
139
+ </Grid.Column>
140
+ ) : (
141
+ <Header as="h4">
142
+ <Icon name="search" />
143
+ <Header.Content>
144
+ <FormattedMessage id="implementationStructures.empty" />
145
+ </Header.Content>
146
+ </Header>
147
+ )}
148
+ </Grid>
149
+ </Segment>
150
+ );
151
+ };
20
152
 
21
153
  ImplementationStructures.propTypes = {
22
- groups: PropTypes.array,
154
+ implementation: PropTypes.object,
155
+ canCreateLink: PropTypes.bool,
23
156
  };
24
157
 
25
158
  const mapStateToProps = (state) => ({
26
- groups: getImplementationStructureLinksColumns(state),
159
+ implementation: state.ruleImplementation,
160
+ canCreateLink: _.propOr(false, "link_structure")(state.implementationActions),
27
161
  });
28
162
 
29
163
  export default connect(mapStateToProps)(ImplementationStructures);
@@ -1,120 +1,91 @@
1
- import React, { Suspense } from "react";
2
- import { waitFor } from "@testing-library/react";
1
+ import React from "react";
3
2
  import { render } from "@truedat/test/render";
4
3
  import { ImplementationStructures } from "../ImplementationStructures";
5
- import { defaultImplementationStructureLinksColumns } from "../../selectors";
6
-
7
- const columns = defaultImplementationStructureLinksColumns;
8
-
9
- const groups = [
10
- [
11
- columns,
12
- [
13
- "undefined",
14
- [
15
- {
16
- data_structure: {
17
- current_version: {
18
- deleted_at: null,
19
- name: "AGENCIA RECIBO",
20
- },
21
- id: 10397859,
22
- },
23
- data_structure_id: 10397859,
24
- id: 21844,
25
- implementation_id: 11932,
26
- type: "population",
27
- },
28
- ],
29
- ],
30
- ],
31
- [
32
- columns,
33
- [
34
- "deleted",
35
- [
36
- {
37
- data_structure: {
38
- current_version: {
39
- deleted_at: "2023-07-12T08:11:23.000000Z",
40
- name: "/BEV1/RBKP",
41
- },
42
- id: 12579384,
43
- },
44
- data_structure_id: 12579384,
45
- id: 21800,
46
- implementation_id: 11932,
47
- type: "dataset",
48
- },
49
- ],
50
- ],
51
- ],
52
- ];
53
4
 
54
5
  describe("<ImplementationStructures />", () => {
55
6
  const renderOpts = {
56
- fallback: "lazy",
57
7
  messages: {
58
8
  en: {
59
- "implementationsRelation.master.table.title": "Links to Structures",
60
- "implementationsDeletedRelation.table.title": "Deleted Structures",
61
- "links.actions.create": "Create",
9
+ "structure.domain": "domain",
10
+ "structure.name": "name",
11
+ "structure.system": "system",
12
+ "structure.path": "path",
13
+ "implementationsStructures.type": "type",
14
+ "links.actions.create": "create",
15
+ "implementationStructures.empty": "empty",
62
16
  "implementationsStructures.type.dataset": "dataset",
63
- "implementationsStructures.type.population": "population",
64
17
  },
65
18
  },
66
19
  };
67
20
 
68
- it("matches the latest snapshot", async () => {
69
- const props = { groups };
70
- const { container, queryByText } = render(
71
- <Suspense fallback={null}>
72
- <ImplementationStructures {...props} />
73
- </Suspense>,
21
+ it("matches the latest snapshot", () => {
22
+ const props = {
23
+ implementation: {
24
+ data_structures: [
25
+ {
26
+ data_structure: {
27
+ id: 1,
28
+ name: "foo",
29
+ system: { name: "bar" },
30
+ domains: [{ name: "foo_domain", parents: [{ name: "bar" }] }],
31
+ current_version: {
32
+ name: "qux",
33
+ path: ["baz"],
34
+ },
35
+ },
36
+ type: "dataset",
37
+ },
38
+ ],
39
+ },
40
+ canCreateLink: true,
41
+ };
42
+ const { container } = render(
43
+ <ImplementationStructures {...props} />,
74
44
  renderOpts
75
45
  );
76
-
77
- await waitFor(() =>
78
- expect(queryByText(/AGENCIA RECIBO/i)).toBeInTheDocument()
79
- );
80
-
81
46
  expect(container).toMatchSnapshot();
82
47
  });
83
48
 
84
- it("matches the latest snapshot without create permission", async () => {
85
- const props = { groups };
86
- const state = {
87
- ruleImplementation: { id: 1 },
88
- implementationActions: { link_structure: {} },
49
+ it("matches the latest snapshot without create permission", () => {
50
+ const props = {
51
+ implementation: {
52
+ data_structures: [
53
+ {
54
+ data_structure: {
55
+ id: 1,
56
+ name: "foo",
57
+ domains: [{ name: "foo_domain", parents: [{ name: "bar" }] }],
58
+ system: { name: "bar" },
59
+ path: ["baz"],
60
+ current_version: {
61
+ name: "qux",
62
+ path: ["baz"],
63
+ },
64
+ },
65
+ type: "dataset",
66
+ },
67
+ ],
68
+ },
69
+ canCreateLink: false,
89
70
  };
90
- const { getByRole } = render(
91
- <Suspense fallback={null}>
92
- <ImplementationStructures {...props} />
93
- </Suspense>,
94
- { ...renderOpts, state }
95
- );
96
- await waitFor(() =>
97
- expect(getByRole("button", { name: /create/i })).toBeEnabled()
71
+ const { container } = render(
72
+ <ImplementationStructures {...props} />,
73
+ renderOpts
98
74
  );
75
+ expect(container).toMatchSnapshot();
99
76
  });
100
77
 
101
- it("matches the latest snapshot without data_structures", async () => {
102
- const state = {
103
- ruleImplementation: { id: 1 },
104
- implementationActions: { link_structure: {} },
78
+ it("matches the latest snapshot without data_structures", () => {
79
+ const props = {
80
+ implementation: {
81
+ data_structures: [],
82
+ },
83
+ canCreateLink: true,
105
84
  };
106
- const props = [];
107
- const { container, getByRole } = render(
108
- <Suspense fallback={null}>
109
- <ImplementationStructures {...props} />
110
- </Suspense>,
111
- { ...renderOpts, state }
112
- );
113
-
114
- await waitFor(() =>
115
- expect(getByRole("button", { name: /create/i })).toBeEnabled()
85
+ const { container } = render(
86
+ <ImplementationStructures {...props} />,
87
+ renderOpts
116
88
  );
117
-
118
89
  expect(container).toMatchSnapshot();
119
90
  });
120
91
  });
@@ -4,131 +4,217 @@ exports[`<ImplementationStructures /> matches the latest snapshot 1`] = `
4
4
  <div>
5
5
  <div
6
6
  class="ui bottom attached segment"
7
- style=""
8
7
  >
9
8
  <div
10
9
  class="ui grid"
11
10
  >
12
11
  <div
13
- class="row"
12
+ class="sixteen wide column"
14
13
  >
15
- <div
16
- class="column"
17
- />
18
- </div>
19
- <div
20
- class="row"
21
- >
22
- <div
23
- class="column"
14
+ <table
15
+ class="ui table"
24
16
  >
25
- <h3
26
- class="ui header"
27
- >
28
- Links to Structures
29
- </h3>
30
- <table
31
- class="ui table"
17
+ <thead
18
+ class=""
32
19
  >
33
- <thead
20
+ <tr
34
21
  class=""
35
22
  >
36
- <tr
23
+ <th
37
24
  class=""
38
25
  >
39
- <th
40
- class=""
41
- >
42
- name
43
- </th>
44
- <th
45
- class=""
46
- >
47
- type
48
- </th>
49
- </tr>
50
- </thead>
51
- <tbody
26
+ name
27
+ </th>
28
+ <th
29
+ class=""
30
+ >
31
+ domain
32
+ </th>
33
+ <th
34
+ class=""
35
+ >
36
+ system
37
+ </th>
38
+ <th
39
+ class=""
40
+ >
41
+ path
42
+ </th>
43
+ <th
44
+ class=""
45
+ >
46
+ type
47
+ </th>
48
+ <th
49
+ class=""
50
+ />
51
+ </tr>
52
+ </thead>
53
+ <tbody
54
+ class=""
55
+ >
56
+ <tr
52
57
  class=""
53
58
  >
54
- <tr
59
+ <td
55
60
  class=""
56
61
  >
57
- <td
58
- class=""
62
+ <a
63
+ href="/structures/1"
59
64
  >
60
- <a
61
- href="/structures/10397859"
65
+ qux
66
+ </a>
67
+ </td>
68
+ <td
69
+ class=""
70
+ >
71
+ <div
72
+ class="ui list"
73
+ role="list"
74
+ >
75
+ <div
76
+ class="item"
77
+ role="listitem"
62
78
  >
63
- AGENCIA RECIBO
64
- </a>
65
- </td>
66
- <td
67
- class=""
79
+ bar &gt; foo_domain
80
+ </div>
81
+ </div>
82
+ </td>
83
+ <td
84
+ class=""
85
+ >
86
+ bar
87
+ </td>
88
+ <td
89
+ class=""
90
+ >
91
+ <span
92
+ title="baz"
68
93
  >
69
- population
70
- </td>
71
- </tr>
72
- </tbody>
73
- </table>
74
- </div>
94
+ baz
95
+ </span>
96
+ </td>
97
+ <td
98
+ class=""
99
+ >
100
+ dataset
101
+ </td>
102
+ <td
103
+ class=""
104
+ >
105
+ <i
106
+ aria-hidden="true"
107
+ class="red trash alternate outline icon"
108
+ />
109
+ </td>
110
+ </tr>
111
+ </tbody>
112
+ </table>
75
113
  </div>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ `;
118
+
119
+ exports[`<ImplementationStructures /> matches the latest snapshot without create permission 1`] = `
120
+ <div>
121
+ <div
122
+ class="ui bottom attached segment"
123
+ >
124
+ <div
125
+ class="ui grid"
126
+ >
76
127
  <div
77
- class="row"
128
+ class="sixteen wide column"
78
129
  >
79
- <div
80
- class="column"
130
+ <table
131
+ class="ui table"
81
132
  >
82
- <h3
83
- class="ui header"
133
+ <thead
134
+ class=""
84
135
  >
85
- Deleted Structures
86
- </h3>
87
- <table
88
- class="ui table"
89
- >
90
- <thead
136
+ <tr
91
137
  class=""
92
138
  >
93
- <tr
139
+ <th
94
140
  class=""
95
141
  >
96
- <th
97
- class=""
98
- >
99
- name
100
- </th>
101
- <th
102
- class=""
103
- >
104
- type
105
- </th>
106
- </tr>
107
- </thead>
108
- <tbody
142
+ name
143
+ </th>
144
+ <th
145
+ class=""
146
+ >
147
+ domain
148
+ </th>
149
+ <th
150
+ class=""
151
+ >
152
+ system
153
+ </th>
154
+ <th
155
+ class=""
156
+ >
157
+ path
158
+ </th>
159
+ <th
160
+ class=""
161
+ >
162
+ type
163
+ </th>
164
+ </tr>
165
+ </thead>
166
+ <tbody
167
+ class=""
168
+ >
169
+ <tr
109
170
  class=""
110
171
  >
111
- <tr
172
+ <td
112
173
  class=""
113
174
  >
114
- <td
115
- class=""
175
+ <a
176
+ href="/structures/1"
116
177
  >
117
- <a
118
- href="/structures/12579384"
178
+ qux
179
+ </a>
180
+ </td>
181
+ <td
182
+ class=""
183
+ >
184
+ <div
185
+ class="ui list"
186
+ role="list"
187
+ >
188
+ <div
189
+ class="item"
190
+ role="listitem"
119
191
  >
120
- /BEV1/RBKP
121
- </a>
122
- </td>
123
- <td
124
- class=""
192
+ bar &gt; foo_domain
193
+ </div>
194
+ </div>
195
+ </td>
196
+ <td
197
+ class=""
198
+ >
199
+ bar
200
+ </td>
201
+ <td
202
+ class=""
203
+ >
204
+ <span
205
+ title="baz"
125
206
  >
126
- dataset
127
- </td>
128
- </tr>
129
- </tbody>
130
- </table>
131
- </div>
207
+ baz
208
+ </span>
209
+ </td>
210
+ <td
211
+ class=""
212
+ >
213
+ dataset
214
+ </td>
215
+ </tr>
216
+ </tbody>
217
+ </table>
132
218
  </div>
133
219
  </div>
134
220
  </div>
@@ -143,21 +229,19 @@ exports[`<ImplementationStructures /> matches the latest snapshot without data_s
143
229
  <div
144
230
  class="ui grid"
145
231
  >
146
- <div
147
- class="row"
232
+ <h4
233
+ class="ui header"
148
234
  >
235
+ <i
236
+ aria-hidden="true"
237
+ class="search icon"
238
+ />
149
239
  <div
150
- class="column"
240
+ class="content"
151
241
  >
152
- <a
153
- class="ui primary right floated button"
154
- href="/implementations/1/structures/new"
155
- role="button"
156
- >
157
- Create
158
- </a>
242
+ empty
159
243
  </div>
160
- </div>
244
+ </h4>
161
245
  </div>
162
246
  </div>
163
247
  </div>
@@ -1,9 +1,5 @@
1
1
  export { datasetDefaultFiltersSelector } from "./datasetDefaultFiltersSelector";
2
2
  export { getImplementationsExecution } from "./getImplementationsExecution";
3
- export {
4
- getImplementationStructureLinksColumns,
5
- defaultImplementationStructureLinksColumns,
6
- } from "./getImplementationStructureLinksColumns";
7
3
  export { getRuleAvailableFilters } from "./getRuleAvailableFilters";
8
4
  export { getRuleFilterTypes } from "./getRuleFilterTypes";
9
5
  export { getRuleSelectedFilters } from "./getRuleSelectedFilters";
@@ -1,36 +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 { Button } from "semantic-ui-react";
6
- import { Link } from "react-router-dom";
7
- import { FormattedMessage } from "react-intl";
8
- import { linkTo } from "@truedat/core/routes";
9
-
10
- export const ImplementationStructureLinksActions = ({
11
- implementation_id,
12
- canCreateLink,
13
- }) =>
14
- implementation_id && canCreateLink ? (
15
- <Button
16
- floated="right"
17
- primary
18
- as={Link}
19
- to={linkTo.IMPLEMENTATION_STRUCTURES_NEW({
20
- implementation_id,
21
- })}
22
- content={<FormattedMessage id="links.actions.create" />}
23
- />
24
- ) : null;
25
-
26
- ImplementationStructureLinksActions.propTypes = {
27
- implementation_id: PropTypes.number,
28
- canCreateLink: PropTypes.bool,
29
- };
30
-
31
- const mapStateToProps = (state) => ({
32
- implementation_id: _.prop("id")(state.ruleImplementation),
33
- canCreateLink: _.propOr(false, "link_structure")(state.implementationActions),
34
- });
35
-
36
- export default connect(mapStateToProps)(ImplementationStructureLinksActions);
@@ -1,56 +0,0 @@
1
- import _ from "lodash/fp";
2
- import { getImplementationStructureLinksColumns } from "..";
3
- // import { defaultImplementationStructureLinksColumns } from "../../selectors";
4
-
5
- const foo = {
6
- data_structure: {
7
- current_version: {
8
- deleted_at: "2023-07-12T08:11:23.000000Z",
9
- name: "/BEV1/RBKP",
10
- },
11
- id: 12579384,
12
- },
13
- data_structure_id: 12579384,
14
- id: 21800,
15
- implementation_id: 11932,
16
- type: "dataset",
17
- };
18
-
19
- const bar = {
20
- data_structure: {
21
- current_version: {
22
- deleted_at: null,
23
- name: "AGENCIA RECIBO",
24
- },
25
- id: 10397859,
26
- },
27
- data_structure_id: 10397859,
28
- id: 21844,
29
- implementation_id: 11932,
30
- type: "population",
31
- };
32
-
33
- const data_structures = [foo, bar];
34
-
35
- // const columns = defaultImplementationStructureLinksColumns
36
-
37
- describe("selectors: getImplementationStructureLinksColumns", () => {
38
- const state = {
39
- ruleImplementation: {
40
- id: 1,
41
- data_structures,
42
- },
43
- implementationActions: { link_structure: {} },
44
- };
45
-
46
- it("should return all links", () => {
47
- const links = _.flow(
48
- getImplementationStructureLinksColumns,
49
- _.map(_.last)
50
- )(state);
51
- expect(links).toEqual([
52
- ["undefined", [bar]],
53
- ["deleted", [foo]],
54
- ]);
55
- });
56
- });
@@ -1,184 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React from "react";
3
- import PropTypes from "prop-types";
4
- import { Icon, Label, List } from "semantic-ui-react";
5
- import { createSelector } from "reselect";
6
- import { FormattedMessage } from "react-intl";
7
- import Moment from "react-moment";
8
- import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
9
- import ImplementationStructureDelete from "../components/ImplementationStructureDelete";
10
- import ImplementationStructureLink from "../components/ImplementationStructureLink";
11
-
12
- const ImplementationStructureDeleteDecorator = ({ id, implementation_id }) => (
13
- <ImplementationStructureDelete id={id} implementationId={implementation_id} />
14
- );
15
- ImplementationStructureDeleteDecorator.propTypes = {
16
- id: PropTypes.number,
17
- implementation_id: PropTypes.number,
18
- };
19
-
20
- const deletedDateDecorator = (date) => (
21
- <Label className="alert warning">
22
- <Icon name="warning circle" color="red" />
23
- <Moment locale="es" date={date} format="YYYY-MM-DD HH:mm" />
24
- </Label>
25
- );
26
-
27
- const dateDecorator = (date) => (
28
- <Moment locale="es" date={date} format="YYYY-MM-DD HH:mm" />
29
- );
30
-
31
- const DomainDecorator = (domains) => (
32
- <List>
33
- {domains.map(({ name, parents }, i) => (
34
- <List.Item key={i}>
35
- {_.flow(_.map("name"), _.union([name]), _.join(" > "))(parents)}
36
- </List.Item>
37
- ))}
38
- </List>
39
- );
40
-
41
- DomainDecorator.propTypes = {
42
- domains: PropTypes.array,
43
- };
44
-
45
- const PathDecorator = (path) => (
46
- <span title={_.join(" › ")(path)}>
47
- {_.flow(_.join(" › "), _.truncate({ length: 90 }))(path)}
48
- </span>
49
- );
50
- PathDecorator.propTypes = {
51
- path: PropTypes.string,
52
- };
53
-
54
- const ImplementationStructureTypeDecorator = (type) => (
55
- <FormattedMessage id={`implementationsStructures.type.${type}`} />
56
- );
57
- ImplementationStructureTypeDecorator.propTypes = {
58
- type: PropTypes.string,
59
- };
60
-
61
- export const defaultImplementationStructureLinksColumns = [
62
- {
63
- name: "name",
64
- fieldSelector: _.path("data_structure"),
65
- fieldDecorator: ImplementationStructureLink,
66
- },
67
- {
68
- name: "domain",
69
- fieldSelector: _.path("data_structure.domains"),
70
- fieldDecorator: DomainDecorator,
71
- },
72
- {
73
- name: "system",
74
- fieldSelector: _.path("data_structure.system.name"),
75
- },
76
- {
77
- name: "path",
78
- fieldSelector: _.path("data_structure.current_version.path"),
79
- fieldDecorator: PathDecorator,
80
- },
81
- {
82
- name: "updated_at",
83
- fieldSelector: _.path("data_structure.updated_at"),
84
- fieldDecorator: dateDecorator,
85
- },
86
- {
87
- name: "type",
88
- fieldSelector: _.path("type"),
89
- fieldDecorator: ImplementationStructureTypeDecorator,
90
- },
91
- ];
92
-
93
- const getStructureLinks = ({ ruleImplementation }) =>
94
- ruleImplementation?.data_structures;
95
-
96
- const getAction = (state) =>
97
- !!_.prop("link_structure")(state.implementationActions);
98
-
99
- const getColumns = (state) =>
100
- _.defaultTo(defaultImplementationStructureLinksColumns)(
101
- state.implementationStructureLinksColumns
102
- );
103
- const orderedLinks = (links) =>
104
- _.sortBy(accentInsensitivePathOrder("current_version.name"))(links);
105
-
106
- const withActions = (columns, canCreateLink) => {
107
- const deleteColumn = canCreateLink
108
- ? [
109
- {
110
- name: "_actions",
111
- fieldSelector: _.identity,
112
- fieldDecorator: ImplementationStructureDeleteDecorator,
113
- },
114
- ]
115
- : [];
116
- const result = [...columns, ...deleteColumn];
117
-
118
- return result;
119
- };
120
-
121
- const withDeletedAttribute = (columns, tag) =>
122
- tag == "deleted"
123
- ? _.map((c) =>
124
- _.propEq("name", "updated_at")(c)
125
- ? {
126
- name: "deleted_at",
127
- fieldSelector: _.path(
128
- "data_structure.current_version.deleted_at"
129
- ),
130
- fieldDecorator: deletedDateDecorator,
131
- }
132
- : c
133
- )(columns)
134
- : columns;
135
-
136
- const mapColumns = (tag, columns, canCreateLink) =>
137
- _.flow(
138
- (cols) => withActions(cols, canCreateLink),
139
- (cols) => withDeletedAttribute(cols, tag)
140
- )(columns);
141
-
142
- const withHeaders = (pair, columns, canCreateLink) => [
143
- mapColumns(_.first(pair), columns, canCreateLink),
144
- pair,
145
- ];
146
-
147
- const implementationStructureDeletedLinks = (links, columns, canCreateLink) => {
148
- const deleted = _.flow(
149
- orderedLinks,
150
- _.filter(
151
- ({ data_structure }) =>
152
- !_.isEmpty(_.get("current_version.deleted_at", data_structure))
153
- )
154
- )(links);
155
- return _.isEmpty(deleted)
156
- ? []
157
- : [withHeaders(["deleted", deleted], columns, canCreateLink)];
158
- };
159
-
160
- const implementationStructureLinks = (links, columns, canCreateLink) =>
161
- _.flow(
162
- orderedLinks,
163
- _.filter(({ data_structure }) =>
164
- _.isEmpty(_.get("current_version.deleted_at", data_structure))
165
- ),
166
- _.groupBy("\uffee"),
167
- _.toPairs,
168
- _.sortBy(([k]) => k),
169
- _.map((pair) => withHeaders(pair, columns, canCreateLink))
170
- )(links);
171
-
172
- export const getImplementationStructureLinksColumns = createSelector(
173
- [getStructureLinks, getColumns, getAction],
174
- (structureLinks, columns, canCreateLink) => {
175
- return [
176
- ...implementationStructureLinks(structureLinks, columns, canCreateLink),
177
- ...implementationStructureDeletedLinks(
178
- structureLinks,
179
- columns,
180
- canCreateLink
181
- ),
182
- ];
183
- }
184
- );