@truedat/dd 7.11.0 → 7.11.2
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 +3 -3
- package/src/api/queries.js +126 -113
- package/src/components/StructureGrants.js +50 -7
- package/src/components/StructureTabPane.js +20 -8
- package/src/components/StructureVersions.js +15 -2
- package/src/components/StructuresEditableDownloadOption.js +2 -0
- package/src/components/__tests__/StructureGrants.spec.js +26 -0
- package/src/components/__tests__/StructureTabPane.spec.js +106 -45
- package/src/components/__tests__/StructureVersions.spec.js +26 -0
- package/src/reducers/__tests__/structureRelations.spec.js +3 -3
- package/src/reducers/__tests__/structureVersions.spec.js +3 -3
- package/src/reducers/structure.js +3 -1
- package/src/reducers/structureRelations.js +4 -4
- package/src/reducers/structureVersions.js +6 -5
- package/src/routines.js +3 -0
- package/src/sagas/fetchStructureChildrens.js +48 -0
- package/src/sagas/fetchStructureParents.js +48 -0
- package/src/sagas/fetchStructureVersions.js +46 -0
- package/src/sagas/index.js +2 -0
- package/src/selectors/__tests__/getTabVisibility.spec.js +6 -6
- package/src/selectors/getTabVisibility.js +5 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "7.11.
|
|
3
|
+
"version": "7.11.2",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@testing-library/jest-dom": "^6.6.3",
|
|
49
49
|
"@testing-library/react": "^16.3.0",
|
|
50
50
|
"@testing-library/user-event": "^14.6.1",
|
|
51
|
-
"@truedat/test": "7.11.
|
|
51
|
+
"@truedat/test": "7.11.2",
|
|
52
52
|
"identity-obj-proxy": "^3.0.0",
|
|
53
53
|
"jest": "^29.7.0",
|
|
54
54
|
"redux-saga-test-plan": "^4.0.6"
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"svg-pan-zoom": "^3.6.2",
|
|
84
84
|
"swr": "^2.3.3"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "c7c9de44c34d3105c78711fa63f6ee8cf7730eaf"
|
|
87
87
|
}
|
package/src/api/queries.js
CHANGED
|
@@ -242,7 +242,6 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
242
242
|
query DataStructureVersion(
|
|
243
243
|
$dataStructureId: ID!
|
|
244
244
|
$version: String!
|
|
245
|
-
$note_fields: [String]
|
|
246
245
|
) {
|
|
247
246
|
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
248
247
|
id
|
|
@@ -285,106 +284,33 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
285
284
|
alias
|
|
286
285
|
classes
|
|
287
286
|
data_structure_id
|
|
288
|
-
deleted_at
|
|
289
287
|
id
|
|
290
|
-
metadata
|
|
291
288
|
name
|
|
292
289
|
type
|
|
293
|
-
has_note
|
|
294
290
|
note
|
|
295
291
|
}
|
|
296
292
|
children {
|
|
297
293
|
alias
|
|
298
294
|
classes
|
|
299
295
|
data_structure_id
|
|
300
|
-
deleted_at
|
|
301
296
|
id
|
|
302
|
-
metadata
|
|
303
297
|
name
|
|
304
298
|
type
|
|
305
|
-
has_note
|
|
306
299
|
note
|
|
307
300
|
}
|
|
308
301
|
siblings {
|
|
309
302
|
alias
|
|
310
303
|
classes
|
|
311
304
|
data_structure_id
|
|
312
|
-
deleted_at
|
|
313
305
|
id
|
|
314
|
-
metadata
|
|
315
306
|
name
|
|
316
307
|
type
|
|
317
308
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
inserted_at
|
|
321
|
-
updated_at
|
|
322
|
-
version
|
|
323
|
-
}
|
|
309
|
+
version_count
|
|
310
|
+
|
|
324
311
|
ancestry
|
|
325
312
|
|
|
326
|
-
|
|
327
|
-
data_structure {
|
|
328
|
-
external_id
|
|
329
|
-
id
|
|
330
|
-
system_id
|
|
331
|
-
}
|
|
332
|
-
data_structure_version {
|
|
333
|
-
ancestry
|
|
334
|
-
name
|
|
335
|
-
}
|
|
336
|
-
detail
|
|
337
|
-
end_date
|
|
338
|
-
external_ref
|
|
339
|
-
id
|
|
340
|
-
inserted_at
|
|
341
|
-
pending_removal
|
|
342
|
-
source_user_name
|
|
343
|
-
start_date
|
|
344
|
-
system {
|
|
345
|
-
external_id
|
|
346
|
-
id
|
|
347
|
-
name
|
|
348
|
-
}
|
|
349
|
-
updated_at
|
|
350
|
-
user {
|
|
351
|
-
email
|
|
352
|
-
full_name
|
|
353
|
-
user_name
|
|
354
|
-
}
|
|
355
|
-
user_id
|
|
356
|
-
}
|
|
357
|
-
grant {
|
|
358
|
-
data_structure {
|
|
359
|
-
external_id
|
|
360
|
-
id
|
|
361
|
-
system_id
|
|
362
|
-
}
|
|
363
|
-
data_structure_version {
|
|
364
|
-
ancestry
|
|
365
|
-
name
|
|
366
|
-
}
|
|
367
|
-
detail
|
|
368
|
-
end_date
|
|
369
|
-
external_ref
|
|
370
|
-
id
|
|
371
|
-
inserted_at
|
|
372
|
-
pending_removal
|
|
373
|
-
source_user_name
|
|
374
|
-
start_date
|
|
375
|
-
system {
|
|
376
|
-
external_id
|
|
377
|
-
id
|
|
378
|
-
name
|
|
379
|
-
}
|
|
380
|
-
updated_at
|
|
381
|
-
user {
|
|
382
|
-
email
|
|
383
|
-
full_name
|
|
384
|
-
user_name
|
|
385
|
-
}
|
|
386
|
-
user_id
|
|
387
|
-
}
|
|
313
|
+
grants_count
|
|
388
314
|
|
|
389
315
|
classes
|
|
390
316
|
implementation_count
|
|
@@ -419,33 +345,7 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
419
345
|
in
|
|
420
346
|
out
|
|
421
347
|
}
|
|
422
|
-
|
|
423
|
-
alias
|
|
424
|
-
classes
|
|
425
|
-
data_structure_id
|
|
426
|
-
deleted_at
|
|
427
|
-
description
|
|
428
|
-
degree {
|
|
429
|
-
in
|
|
430
|
-
out
|
|
431
|
-
}
|
|
432
|
-
links
|
|
433
|
-
id
|
|
434
|
-
metadata
|
|
435
|
-
name
|
|
436
|
-
type
|
|
437
|
-
profile {
|
|
438
|
-
max
|
|
439
|
-
min
|
|
440
|
-
most_frequent
|
|
441
|
-
null_count
|
|
442
|
-
patterns
|
|
443
|
-
total_count
|
|
444
|
-
unique_count
|
|
445
|
-
}
|
|
446
|
-
has_note
|
|
447
|
-
note(select_fields: $note_fields)
|
|
448
|
-
}
|
|
348
|
+
data_fields_count
|
|
449
349
|
relations {
|
|
450
350
|
parents {
|
|
451
351
|
id
|
|
@@ -476,23 +376,136 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
476
376
|
}
|
|
477
377
|
}
|
|
478
378
|
|
|
479
|
-
links
|
|
480
379
|
_actions
|
|
481
380
|
user_permissions
|
|
482
381
|
}
|
|
483
382
|
}
|
|
484
383
|
`;
|
|
485
|
-
|
|
384
|
+
|
|
486
385
|
export const DATA_STRUCTURE_VERSION_METADATA_QUERY = gql`
|
|
487
|
-
query DataStructureVersion(
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
) {
|
|
491
|
-
|
|
492
|
-
|
|
386
|
+
query DataStructureVersion(
|
|
387
|
+
$dataStructureId: ID!
|
|
388
|
+
$version: String!
|
|
389
|
+
) {
|
|
390
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
391
|
+
metadata
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
`;
|
|
395
|
+
|
|
396
|
+
export const DATA_STRUCTURE_VERSION_LINKS_QUERY = gql`
|
|
397
|
+
query DataStructureVersion(
|
|
398
|
+
$dataStructureId: ID!
|
|
399
|
+
$version: String!
|
|
400
|
+
) {
|
|
401
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
402
|
+
links
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
`;
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
export const DATA_STRUCTURE_VERSION_VERSIONS_QUERY = gql`
|
|
409
|
+
query DataStructureVersion(
|
|
410
|
+
$dataStructureId: ID!
|
|
411
|
+
$version: String!
|
|
412
|
+
) {
|
|
413
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
414
|
+
versions {
|
|
415
|
+
deleted_at
|
|
416
|
+
inserted_at
|
|
417
|
+
updated_at
|
|
418
|
+
version
|
|
419
|
+
}
|
|
420
|
+
}
|
|
493
421
|
}
|
|
494
|
-
}
|
|
495
422
|
`;
|
|
423
|
+
|
|
424
|
+
export const DATA_STRUCTURE_VERSION_GRANTS_QUERY = gql`
|
|
425
|
+
query DataStructureVersion(
|
|
426
|
+
$dataStructureId: ID!
|
|
427
|
+
$version: String!
|
|
428
|
+
) {
|
|
429
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
430
|
+
grants {
|
|
431
|
+
data_structure {
|
|
432
|
+
external_id
|
|
433
|
+
id
|
|
434
|
+
system_id
|
|
435
|
+
}
|
|
436
|
+
data_structure_version {
|
|
437
|
+
ancestry
|
|
438
|
+
name
|
|
439
|
+
}
|
|
440
|
+
detail
|
|
441
|
+
end_date
|
|
442
|
+
external_ref
|
|
443
|
+
id
|
|
444
|
+
inserted_at
|
|
445
|
+
pending_removal
|
|
446
|
+
source_user_name
|
|
447
|
+
start_date
|
|
448
|
+
system {
|
|
449
|
+
external_id
|
|
450
|
+
id
|
|
451
|
+
name
|
|
452
|
+
}
|
|
453
|
+
updated_at
|
|
454
|
+
user {
|
|
455
|
+
email
|
|
456
|
+
full_name
|
|
457
|
+
user_name
|
|
458
|
+
}
|
|
459
|
+
user_id
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
`;
|
|
464
|
+
|
|
465
|
+
export const DATA_STRUCTURE_PARENTS_QUERY = gql`
|
|
466
|
+
query DataStructureVersion(
|
|
467
|
+
$dataStructureId: ID!
|
|
468
|
+
$version: String!
|
|
469
|
+
) {
|
|
470
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
471
|
+
parents {
|
|
472
|
+
alias
|
|
473
|
+
classes
|
|
474
|
+
data_structure_id
|
|
475
|
+
deleted_at
|
|
476
|
+
id
|
|
477
|
+
metadata
|
|
478
|
+
name
|
|
479
|
+
type
|
|
480
|
+
has_note
|
|
481
|
+
note
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
`;
|
|
486
|
+
|
|
487
|
+
export const DATA_STRUCTURE_CHILDREN_QUERY = gql`
|
|
488
|
+
query DataStructureVersion(
|
|
489
|
+
$dataStructureId: ID!
|
|
490
|
+
$version: String!
|
|
491
|
+
) {
|
|
492
|
+
dataStructureVersion(dataStructureId: $dataStructureId, version: $version) {
|
|
493
|
+
children {
|
|
494
|
+
alias
|
|
495
|
+
classes
|
|
496
|
+
data_structure_id
|
|
497
|
+
deleted_at
|
|
498
|
+
id
|
|
499
|
+
metadata
|
|
500
|
+
name
|
|
501
|
+
type
|
|
502
|
+
has_note
|
|
503
|
+
note
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
`;
|
|
508
|
+
|
|
496
509
|
export const TASKS_QUERY = gql`
|
|
497
510
|
query Tasks {
|
|
498
511
|
tasks {
|
|
@@ -8,23 +8,23 @@ import { columnDecorator } from "@truedat/core/services";
|
|
|
8
8
|
import { linkTo } from "@truedat/core/routes";
|
|
9
9
|
import { getGrantsColumns } from "../selectors";
|
|
10
10
|
import GrantRemoval from "./GrantRemoval";
|
|
11
|
+
import { useQuery } from "@apollo/client";
|
|
12
|
+
import { DATA_STRUCTURE_VERSION_GRANTS_QUERY } from "../api/queries";
|
|
11
13
|
|
|
12
14
|
const matchesStructure = ({ id }) => _.pathEq("data_structure.id", id);
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
const StructureGrantsContent = ({
|
|
15
17
|
columns,
|
|
16
|
-
grants,
|
|
17
18
|
grantsActions,
|
|
18
19
|
structure,
|
|
19
20
|
userPermissions,
|
|
21
|
+
grants,
|
|
22
|
+
canUpdateRemoval,
|
|
20
23
|
}) => {
|
|
21
24
|
const { formatMessage } = useIntl();
|
|
22
25
|
const navigate = useNavigate();
|
|
23
|
-
const canUpdateRemoval =
|
|
24
|
-
userPermissions?.update_grant_removal &&
|
|
25
|
-
_.any(matchesStructure(structure))(grants);
|
|
26
26
|
|
|
27
|
-
return
|
|
27
|
+
return (
|
|
28
28
|
<Table basic="very">
|
|
29
29
|
<Table.Header>
|
|
30
30
|
<Table.Row>
|
|
@@ -76,7 +76,50 @@ export const StructureGrants = ({
|
|
|
76
76
|
))}
|
|
77
77
|
</Table.Body>
|
|
78
78
|
</Table>
|
|
79
|
-
)
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
StructureGrantsContent.propTypes = {
|
|
83
|
+
columns: PropTypes.array,
|
|
84
|
+
grantsActions: PropTypes.object,
|
|
85
|
+
structure: PropTypes.object,
|
|
86
|
+
userPermissions: PropTypes.object,
|
|
87
|
+
grants: PropTypes.array,
|
|
88
|
+
canUpdateRemoval: PropTypes.bool,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const StructureGrants = ({
|
|
92
|
+
columns,
|
|
93
|
+
grantsActions,
|
|
94
|
+
structure,
|
|
95
|
+
userPermissions,
|
|
96
|
+
}) => {
|
|
97
|
+
const { data } = useQuery(DATA_STRUCTURE_VERSION_GRANTS_QUERY, {
|
|
98
|
+
fetchPolicy: "network-only",
|
|
99
|
+
variables: { dataStructureId: structure.id, version: "latest" },
|
|
100
|
+
skip: !structure?.id,
|
|
101
|
+
});
|
|
102
|
+
const grants = data?.dataStructureVersion.grants;
|
|
103
|
+
|
|
104
|
+
const canUpdateRemoval =
|
|
105
|
+
userPermissions?.update_grant_removal &&
|
|
106
|
+
grants &&
|
|
107
|
+
_.any(matchesStructure(structure))(grants);
|
|
108
|
+
|
|
109
|
+
if (!grants) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<StructureGrantsContent
|
|
115
|
+
columns={columns}
|
|
116
|
+
grantsActions={grantsActions}
|
|
117
|
+
structure={structure}
|
|
118
|
+
userPermissions={userPermissions}
|
|
119
|
+
grants={grants}
|
|
120
|
+
canUpdateRemoval={canUpdateRemoval}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
80
123
|
};
|
|
81
124
|
|
|
82
125
|
StructureGrants.propTypes = {
|
|
@@ -41,21 +41,30 @@ const StructureSuggestionLinkForm = lazy(
|
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
const RuleImplementationsTable = lazy(
|
|
44
|
-
() => import("@truedat/dq/components/
|
|
44
|
+
() => import("@truedat/dq/components/SimpleRuleImplementationsTable")
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
const CustomTab = ({ tabs, activeTab }) => {
|
|
48
48
|
if (_.isEmpty(tabs)) return null;
|
|
49
|
-
const tab = _.find((tab) =>
|
|
49
|
+
const tab = _.find((tab) => tab.name === activeTab)(tabs);
|
|
50
50
|
return tab?.content;
|
|
51
|
-
}
|
|
51
|
+
};
|
|
52
52
|
|
|
53
53
|
export const StructureTabPane = ({ path }) => {
|
|
54
54
|
const customTabs = useStructureCustomTabs();
|
|
55
55
|
const tabVisibility = useSelector(getTabVisibility);
|
|
56
|
-
const structureTabsOrder = useSelector(state => state.structureTabsOrder);
|
|
57
|
-
const columns = useSelector(state =>
|
|
58
|
-
|
|
56
|
+
const structureTabsOrder = useSelector((state) => state.structureTabsOrder);
|
|
57
|
+
const columns = useSelector((state) =>
|
|
58
|
+
getLinkedImplementationsToStructuresColumns(state)
|
|
59
|
+
);
|
|
60
|
+
const ruleImplementations = useSelector((state) => state.ruleImplementations);
|
|
61
|
+
|
|
62
|
+
const activeTab = getActiveTab({
|
|
63
|
+
tabVisibility,
|
|
64
|
+
path,
|
|
65
|
+
structureTabsOrder,
|
|
66
|
+
customTabs,
|
|
67
|
+
});
|
|
59
68
|
|
|
60
69
|
return (
|
|
61
70
|
<ErrorBoundary>
|
|
@@ -90,7 +99,10 @@ export const StructureTabPane = ({ path }) => {
|
|
|
90
99
|
{activeTab === "events" && <StructureEvents />}
|
|
91
100
|
{activeTab === "roles" && <StructureRoles />}
|
|
92
101
|
{activeTab === "rules" && tabVisibility.rules && (
|
|
93
|
-
<RuleImplementationsTable
|
|
102
|
+
<RuleImplementationsTable
|
|
103
|
+
columns={columns}
|
|
104
|
+
ruleImplementations={ruleImplementations}
|
|
105
|
+
/>
|
|
94
106
|
)}
|
|
95
107
|
{activeTab === "metadata" && tabVisibility.metadata && (
|
|
96
108
|
<StructureMetadata />
|
|
@@ -102,6 +114,6 @@ export const StructureTabPane = ({ path }) => {
|
|
|
102
114
|
);
|
|
103
115
|
};
|
|
104
116
|
|
|
105
|
-
StructureTabPane.propTypes = { path: PropTypes.string
|
|
117
|
+
StructureTabPane.propTypes = { path: PropTypes.string };
|
|
106
118
|
|
|
107
119
|
export default StructureTabPane;
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
|
+
import { useParams } from "react-router";
|
|
4
5
|
import { List } from "semantic-ui-react";
|
|
5
6
|
import StructureVersionListItem from "./StructureVersionListItem";
|
|
7
|
+
import { useQuery } from "@apollo/client";
|
|
8
|
+
import { DATA_STRUCTURE_VERSION_VERSIONS_QUERY } from "../api/queries";
|
|
6
9
|
|
|
7
|
-
export const StructureVersions = (
|
|
10
|
+
export const StructureVersions = () =>{
|
|
11
|
+
const { id } = useParams();
|
|
12
|
+
|
|
13
|
+
const { data } = useQuery(DATA_STRUCTURE_VERSION_VERSIONS_QUERY, {
|
|
14
|
+
fetchPolicy: "network-only",
|
|
15
|
+
variables: { dataStructureId: id, version: "latest" },
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const versions = data?.dataStructureVersion.versions;
|
|
19
|
+
return (
|
|
8
20
|
!_.isEmpty(versions) && (
|
|
9
21
|
<List selection>
|
|
10
22
|
{versions.map((v, i) => (
|
|
11
23
|
<StructureVersionListItem key={i} id={id} {...v} />
|
|
12
24
|
))}
|
|
13
25
|
</List>
|
|
14
|
-
);
|
|
26
|
+
));
|
|
27
|
+
}
|
|
15
28
|
|
|
16
29
|
StructureVersions.propTypes = {
|
|
17
30
|
id: PropTypes.number,
|
|
@@ -12,11 +12,13 @@ export const StructuresEditableDownloadOption = ({
|
|
|
12
12
|
pendingStructureNotes,
|
|
13
13
|
}) => {
|
|
14
14
|
const { formatMessage, locale } = useIntl();
|
|
15
|
+
|
|
15
16
|
const {
|
|
16
17
|
searchData,
|
|
17
18
|
loading: structuresLoading,
|
|
18
19
|
filterParams: searchParams,
|
|
19
20
|
} = useSearchContext();
|
|
21
|
+
|
|
20
22
|
const { trigger: triggerDownload, isMutating: structuresDownloading } =
|
|
21
23
|
useDataStructureDownload();
|
|
22
24
|
|
|
@@ -2,6 +2,32 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import { render } from "@truedat/test/render";
|
|
3
3
|
import { StructureGrants } from "../StructureGrants";
|
|
4
4
|
|
|
5
|
+
jest.mock("@apollo/client", () => ({
|
|
6
|
+
gql: jest.fn((query) => query),
|
|
7
|
+
useQuery: jest.fn(() => ({
|
|
8
|
+
data: {
|
|
9
|
+
dataStructureVersion: {
|
|
10
|
+
grants: [
|
|
11
|
+
{
|
|
12
|
+
id: 1,
|
|
13
|
+
user: { id: 1, full_name: "foo user" },
|
|
14
|
+
data_structure: { id: 99, external_id: "foo_strucutre" },
|
|
15
|
+
end_date: "2021/08/02",
|
|
16
|
+
pending_removal: false,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 2,
|
|
20
|
+
user: { id: 2, full_name: "bar user" },
|
|
21
|
+
data_structure: { name: "bar structure" },
|
|
22
|
+
end_date: "2021/09/02",
|
|
23
|
+
pending_removal: false,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
})),
|
|
29
|
+
}));
|
|
30
|
+
|
|
5
31
|
describe("<StructureGrants />", () => {
|
|
6
32
|
const idDecorator = ({ id }) => <p>{id}</p>;
|
|
7
33
|
const userDecorator = ({ user }) => <p>{user.full_name}</p>;
|
|
@@ -56,7 +56,7 @@ jest.mock("@truedat/lm/components/StructureRelationForm", () => () => (
|
|
|
56
56
|
<div>StructureRelationForm</div>
|
|
57
57
|
));
|
|
58
58
|
jest.mock("@truedat/profile", () => () => <div>StructureProfile</div>);
|
|
59
|
-
jest.mock("@truedat/dq/components/
|
|
59
|
+
jest.mock("@truedat/dq/components/SimpleRuleImplementationsTable", () => () => (
|
|
60
60
|
<div>RuleImplementationsTable</div>
|
|
61
61
|
));
|
|
62
62
|
|
|
@@ -73,132 +73,193 @@ describe("<StructureTabPane />", () => {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
it("renders correctly with fields tab", async () => {
|
|
76
|
-
jest
|
|
77
|
-
|
|
76
|
+
jest
|
|
77
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
78
|
+
.mockReturnValue(tabVisibility);
|
|
79
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_FIELDS} />, {
|
|
80
|
+
state,
|
|
81
|
+
});
|
|
78
82
|
await waitForLoad(rendered);
|
|
79
83
|
expect(rendered.container).toMatchSnapshot();
|
|
80
84
|
});
|
|
81
85
|
|
|
82
86
|
it("renders correctly with notes edit route", async () => {
|
|
83
|
-
const rendered = render(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
87
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_NOTES_EDIT} />, {
|
|
88
|
+
routes: [STRUCTURE_NOTES_EDIT],
|
|
89
|
+
state,
|
|
90
|
+
});
|
|
87
91
|
await waitForLoad(rendered);
|
|
88
92
|
expect(rendered.container).toMatchSnapshot();
|
|
89
93
|
});
|
|
90
94
|
|
|
91
95
|
it("renders correctly with notes default route", async () => {
|
|
92
|
-
const rendered = render(
|
|
93
|
-
|
|
94
|
-
);
|
|
96
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_NOTES} />, {
|
|
97
|
+
state,
|
|
98
|
+
});
|
|
95
99
|
await waitForLoad(rendered);
|
|
96
100
|
expect(rendered.container).toMatchSnapshot();
|
|
97
101
|
});
|
|
98
102
|
|
|
99
103
|
it("renders correctly with grants tab", async () => {
|
|
100
|
-
jest
|
|
101
|
-
|
|
104
|
+
jest
|
|
105
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
106
|
+
.mockReturnValue(tabVisibility);
|
|
107
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_GRANTS} />, {
|
|
108
|
+
state,
|
|
109
|
+
});
|
|
102
110
|
await waitForLoad(rendered);
|
|
103
111
|
expect(rendered.container).toMatchSnapshot();
|
|
104
112
|
});
|
|
105
113
|
|
|
106
114
|
it("renders correctly with profile tab", async () => {
|
|
107
|
-
jest
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
jest
|
|
116
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
117
|
+
.mockReturnValue(tabVisibility);
|
|
118
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_PROFILE} />, {
|
|
119
|
+
state,
|
|
120
|
+
});
|
|
111
121
|
await waitForLoad(rendered);
|
|
112
122
|
expect(rendered.container).toMatchSnapshot();
|
|
113
123
|
});
|
|
114
124
|
|
|
115
125
|
it("renders correctly with metadata tab", async () => {
|
|
116
|
-
jest
|
|
117
|
-
|
|
126
|
+
jest
|
|
127
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
128
|
+
.mockReturnValue(tabVisibility);
|
|
129
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_METADATA} />, {
|
|
130
|
+
state,
|
|
131
|
+
});
|
|
118
132
|
await waitForLoad(rendered);
|
|
119
133
|
expect(rendered.container).toMatchSnapshot();
|
|
120
134
|
});
|
|
121
135
|
|
|
122
136
|
it("renders correctly with rules tab", async () => {
|
|
123
|
-
jest
|
|
124
|
-
|
|
137
|
+
jest
|
|
138
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
139
|
+
.mockReturnValue(tabVisibility);
|
|
140
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_RULES} />, {
|
|
141
|
+
state,
|
|
142
|
+
});
|
|
125
143
|
await waitForLoad(rendered);
|
|
126
144
|
expect(rendered.container).toMatchSnapshot();
|
|
127
145
|
});
|
|
128
146
|
|
|
129
147
|
it("renders correctly with links tab", async () => {
|
|
130
|
-
jest
|
|
131
|
-
|
|
148
|
+
jest
|
|
149
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
150
|
+
.mockReturnValue(tabVisibility);
|
|
151
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_LINKS} />, {
|
|
152
|
+
state,
|
|
153
|
+
});
|
|
132
154
|
await waitForLoad(rendered);
|
|
133
155
|
expect(rendered.container).toMatchSnapshot();
|
|
134
156
|
});
|
|
135
157
|
|
|
136
158
|
it("renders correctly with structure links tab", async () => {
|
|
137
|
-
jest
|
|
138
|
-
|
|
159
|
+
jest
|
|
160
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
161
|
+
.mockReturnValue(tabVisibility);
|
|
162
|
+
const rendered = render(
|
|
163
|
+
<StructureTabPane path={STRUCTURE_STRUCTURE_LINKS} />,
|
|
164
|
+
{ state }
|
|
139
165
|
);
|
|
140
166
|
await waitForLoad(rendered);
|
|
141
167
|
expect(rendered.container).toMatchSnapshot();
|
|
142
168
|
});
|
|
143
169
|
|
|
144
170
|
it("renders correctly with parents tab", async () => {
|
|
145
|
-
jest
|
|
146
|
-
|
|
171
|
+
jest
|
|
172
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
173
|
+
.mockReturnValue(tabVisibility);
|
|
174
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_PARENTS} />, {
|
|
175
|
+
state,
|
|
176
|
+
});
|
|
147
177
|
await waitForLoad(rendered);
|
|
148
178
|
expect(rendered.container).toMatchSnapshot();
|
|
149
179
|
});
|
|
150
180
|
|
|
151
181
|
it("renders correctly with children tab", async () => {
|
|
152
|
-
jest
|
|
153
|
-
|
|
182
|
+
jest
|
|
183
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
184
|
+
.mockReturnValue(tabVisibility);
|
|
185
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_CHILDREN} />, {
|
|
186
|
+
state,
|
|
187
|
+
});
|
|
154
188
|
await waitForLoad(rendered);
|
|
155
189
|
expect(rendered.container).toMatchSnapshot();
|
|
156
190
|
});
|
|
157
191
|
|
|
158
192
|
it("renders correctly with versions tab", async () => {
|
|
159
|
-
jest
|
|
160
|
-
|
|
193
|
+
jest
|
|
194
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
195
|
+
.mockReturnValue(tabVisibility);
|
|
196
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_VERSIONS} />, {
|
|
197
|
+
state,
|
|
198
|
+
});
|
|
161
199
|
await waitForLoad(rendered);
|
|
162
200
|
expect(rendered.container).toMatchSnapshot();
|
|
163
201
|
});
|
|
164
202
|
|
|
165
203
|
it("renders correctly with events tab", async () => {
|
|
166
|
-
jest
|
|
167
|
-
|
|
204
|
+
jest
|
|
205
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
206
|
+
.mockReturnValue(tabVisibility);
|
|
207
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_EVENTS} />, {
|
|
208
|
+
state,
|
|
209
|
+
});
|
|
168
210
|
await waitForLoad(rendered);
|
|
169
211
|
expect(rendered.container).toMatchSnapshot();
|
|
170
212
|
});
|
|
171
213
|
|
|
172
214
|
it("renders correctly with roles tab", async () => {
|
|
173
|
-
jest
|
|
174
|
-
|
|
215
|
+
jest
|
|
216
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
217
|
+
.mockReturnValue(tabVisibility);
|
|
218
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_MEMBERS} />, {
|
|
219
|
+
state,
|
|
220
|
+
});
|
|
175
221
|
await waitForLoad(rendered);
|
|
176
222
|
expect(rendered.container).toMatchSnapshot();
|
|
177
223
|
});
|
|
178
224
|
|
|
179
225
|
it("renders correctly with lineage tab", async () => {
|
|
180
|
-
jest
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
226
|
+
jest
|
|
227
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
228
|
+
.mockReturnValue(tabVisibility);
|
|
229
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_LINEAGE} />, {
|
|
230
|
+
state,
|
|
231
|
+
});
|
|
184
232
|
await waitForLoad(rendered);
|
|
185
233
|
expect(rendered.container).toMatchSnapshot();
|
|
186
234
|
});
|
|
187
235
|
|
|
188
236
|
it("renders correctly with impact tab", async () => {
|
|
189
|
-
jest
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
237
|
+
jest
|
|
238
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
239
|
+
.mockReturnValue(tabVisibility);
|
|
240
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_IMPACT} />, {
|
|
241
|
+
state,
|
|
242
|
+
});
|
|
193
243
|
await waitForLoad(rendered);
|
|
194
244
|
expect(rendered.container).toMatchSnapshot();
|
|
195
245
|
});
|
|
196
246
|
|
|
197
247
|
it("renders correctly with custom tab", async () => {
|
|
198
|
-
jest
|
|
199
|
-
|
|
248
|
+
jest
|
|
249
|
+
.spyOn(getTabVisibilityModule, "getTabVisibility")
|
|
250
|
+
.mockReturnValue(tabVisibility);
|
|
251
|
+
jest
|
|
252
|
+
.spyOn(useCustomTabsModule, "useStructureCustomTabs")
|
|
253
|
+
.mockReturnValue([
|
|
254
|
+
{
|
|
255
|
+
name: "custom",
|
|
256
|
+
route: "/structures/:id/custom",
|
|
257
|
+
content: <p>Custom</p>,
|
|
258
|
+
},
|
|
259
|
+
]);
|
|
200
260
|
const rendered = render(
|
|
201
|
-
<StructureTabPane path={"/structures/:id/custom"} />,
|
|
261
|
+
<StructureTabPane path={"/structures/:id/custom"} />,
|
|
262
|
+
{ state }
|
|
202
263
|
);
|
|
203
264
|
await waitForLoad(rendered);
|
|
204
265
|
await waitFor(() => {
|
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import { render, waitForLoad } from "@truedat/test/render";
|
|
2
2
|
import { StructureVersions } from "../StructureVersions";
|
|
3
3
|
|
|
4
|
+
jest.mock("react-router", () => ({
|
|
5
|
+
...jest.requireActual("react-router"),
|
|
6
|
+
useParams: jest.fn(() => ({ id: "1" })),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
jest.mock("@apollo/client", () => ({
|
|
10
|
+
gql: jest.fn((query) => query),
|
|
11
|
+
useQuery: jest.fn(() => ({
|
|
12
|
+
data: {
|
|
13
|
+
dataStructureVersion: {
|
|
14
|
+
versions: [
|
|
15
|
+
{
|
|
16
|
+
version: "0",
|
|
17
|
+
inserted_at: "2018-01-01T01:01:01.123456Z",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
version: "1",
|
|
21
|
+
inserted_at: "2018-02-01T01:01:01.123456Z",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
})),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
|
|
4
30
|
describe("<StructureVersions />", () => {
|
|
5
31
|
it("matches the latest snapshot", async () => {
|
|
6
32
|
const versions = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { clearStructure, fetchStructure } from "../../routines";
|
|
1
|
+
import { clearStructure, fetchStructure, fetchStructureChildrens, fetchStructureParents } from "../../routines";
|
|
2
2
|
import { childrenRelations, parentRelations } from "..";
|
|
3
3
|
|
|
4
4
|
const fooState = { foo: "bar" };
|
|
@@ -48,7 +48,7 @@ describe("reducers: childrenRelations", () => {
|
|
|
48
48
|
it("should handle the fetchStructures.SUCCESS action", () => {
|
|
49
49
|
expect(
|
|
50
50
|
childrenRelations(fooState, {
|
|
51
|
-
type:
|
|
51
|
+
type: fetchStructureChildrens.SUCCESS,
|
|
52
52
|
payload: { data }
|
|
53
53
|
})
|
|
54
54
|
).toMatchObject(children);
|
|
@@ -77,7 +77,7 @@ describe("reducers: parentRelations", () => {
|
|
|
77
77
|
it("should handle the fetchStructures.SUCCESS action", () => {
|
|
78
78
|
expect(
|
|
79
79
|
parentRelations(fooState, {
|
|
80
|
-
type:
|
|
80
|
+
type: fetchStructureParents.SUCCESS,
|
|
81
81
|
payload: { data }
|
|
82
82
|
})
|
|
83
83
|
).toMatchObject(parents);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { clearStructure, fetchStructure } from "../../routines";
|
|
1
|
+
import { clearStructure, fetchStructure, fetchStructureVersions } from "../../routines";
|
|
2
2
|
import { structureVersions } from "..";
|
|
3
3
|
|
|
4
4
|
const fooState = { foo: "bar" };
|
|
@@ -19,7 +19,7 @@ describe("reducers: structureVersions", () => {
|
|
|
19
19
|
it("should handle the fetchStructure.TRIGGER action", () => {
|
|
20
20
|
expect(
|
|
21
21
|
structureVersions(fooState, { type: fetchStructure.TRIGGER })
|
|
22
|
-
).toEqual(
|
|
22
|
+
).toEqual(fooState);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it("should handle the fetchStructure.SUCCESS action", () => {
|
|
@@ -28,7 +28,7 @@ describe("reducers: structureVersions", () => {
|
|
|
28
28
|
|
|
29
29
|
expect(
|
|
30
30
|
structureVersions(fooState, {
|
|
31
|
-
type:
|
|
31
|
+
type: fetchStructureVersions.SUCCESS,
|
|
32
32
|
payload: { data }
|
|
33
33
|
})
|
|
34
34
|
).toMatchObject(versions);
|
|
@@ -29,9 +29,10 @@ const structureVersionFields = _.pick([
|
|
|
29
29
|
"deleted_at",
|
|
30
30
|
"description",
|
|
31
31
|
"grant",
|
|
32
|
-
"
|
|
32
|
+
"grants_count",
|
|
33
33
|
"group",
|
|
34
34
|
"implementation_count",
|
|
35
|
+
"data_fields_count",
|
|
35
36
|
"metadata",
|
|
36
37
|
"name",
|
|
37
38
|
"note",
|
|
@@ -42,6 +43,7 @@ const structureVersionFields = _.pick([
|
|
|
42
43
|
"system",
|
|
43
44
|
"type",
|
|
44
45
|
"_actions",
|
|
46
|
+
"version_count",
|
|
45
47
|
]);
|
|
46
48
|
|
|
47
49
|
const structure = (state = initialState, { type, payload }) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import { clearStructure,
|
|
2
|
+
import { clearStructure, fetchStructureChildrens, fetchStructureParents } from "../routines";
|
|
3
3
|
|
|
4
4
|
export const initialState = [];
|
|
5
5
|
|
|
@@ -7,9 +7,9 @@ export const childrenRelations = (state = initialState, { type, payload }) => {
|
|
|
7
7
|
switch (type) {
|
|
8
8
|
case clearStructure.TRIGGER:
|
|
9
9
|
return initialState;
|
|
10
|
-
case
|
|
10
|
+
case fetchStructureChildrens.TRIGGER:
|
|
11
11
|
return initialState;
|
|
12
|
-
case
|
|
12
|
+
case fetchStructureChildrens.SUCCESS:
|
|
13
13
|
return _.pathOr([], "data.relations.children")(payload);
|
|
14
14
|
default:
|
|
15
15
|
return state;
|
|
@@ -20,7 +20,7 @@ export const parentRelations = (state = initialState, { type, payload }) => {
|
|
|
20
20
|
switch (type) {
|
|
21
21
|
case clearStructure.TRIGGER:
|
|
22
22
|
return initialState;
|
|
23
|
-
case
|
|
23
|
+
case fetchStructureParents.SUCCESS:
|
|
24
24
|
return _.pathOr([], "data.relations.parents")(payload);
|
|
25
25
|
default:
|
|
26
26
|
return state;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import { clearStructure,
|
|
2
|
+
import { clearStructure, fetchStructureVersions } from "../routines";
|
|
3
3
|
|
|
4
4
|
const initialState = [];
|
|
5
5
|
|
|
6
|
-
const structureVersions
|
|
6
|
+
const structureVersions = (state = initialState, { type, payload }) => {
|
|
7
7
|
switch (type) {
|
|
8
8
|
case clearStructure.TRIGGER:
|
|
9
9
|
return initialState;
|
|
10
|
-
case
|
|
10
|
+
case fetchStructureVersions.TRIGGER:
|
|
11
11
|
return initialState;
|
|
12
|
-
case
|
|
12
|
+
case fetchStructureVersions.SUCCESS:
|
|
13
|
+
console.log("payload", payload);
|
|
13
14
|
return _.pathOr([], "data.versions")(payload);
|
|
14
15
|
default:
|
|
15
16
|
return state;
|
|
16
17
|
}
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
export { structureVersions
|
|
20
|
+
export { structureVersions };
|
package/src/routines.js
CHANGED
|
@@ -89,6 +89,9 @@ export const fetchNodes = createRoutine("FETCH_NODES");
|
|
|
89
89
|
export const fetchProfileExecution = createRoutine("FETCH_EXECUTION_PROFILE");
|
|
90
90
|
export const fetchProfileGroup = createRoutine("FETCH_PROFILE_GROUP");
|
|
91
91
|
export const fetchStructure = createRoutine("FETCH_STRUCTURE");
|
|
92
|
+
export const fetchStructureParents = createRoutine("FETCH_STRUCTURE_PARENTS");
|
|
93
|
+
export const fetchStructureChildrens = createRoutine("FETCH_STRUCTURE_CHILDREN");
|
|
94
|
+
export const fetchStructureVersions = createRoutine("FETCH_STRUCTURE_VERSIONS");
|
|
92
95
|
export const fetchStructureGraph = createRoutine("FETCH_STRUCTURE_GRAPH");
|
|
93
96
|
export const fetchStructureNotes = createRoutine("FETCH_STRUCTURE_NOTES");
|
|
94
97
|
export const fetchStructures = createRoutine("FETCH_STRUCTURES");
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { call, put, takeLatest, select, getContext } from "redux-saga/effects";
|
|
3
|
+
import { fetchStructureChildrens } from "../routines";
|
|
4
|
+
import { DATA_STRUCTURE_CHILDREN_QUERY } from "../api/queries";
|
|
5
|
+
import { getStructureFieldColumns } from "../selectors";
|
|
6
|
+
|
|
7
|
+
export function* fetchStructureChildrenSaga({ payload }) {
|
|
8
|
+
try {
|
|
9
|
+
const client = yield getContext("client");
|
|
10
|
+
|
|
11
|
+
yield put(fetchStructureChildrens.request());
|
|
12
|
+
|
|
13
|
+
const { id, version = "latest" } = payload;
|
|
14
|
+
const {
|
|
15
|
+
data: { dataStructureVersion },
|
|
16
|
+
} = yield call(client.query, {
|
|
17
|
+
fetchPolicy: "network-only",
|
|
18
|
+
query: DATA_STRUCTURE_CHILDREN_QUERY,
|
|
19
|
+
variables: {
|
|
20
|
+
dataStructureId: id,
|
|
21
|
+
version,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const data = {
|
|
26
|
+
data: dataStructureVersion,
|
|
27
|
+
_actions: dataStructureVersion._actions,
|
|
28
|
+
user_permissions: dataStructureVersion.user_permissions,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const meta = { version };
|
|
32
|
+
|
|
33
|
+
yield put({ meta, ...fetchStructureChildrens.success(data) });
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.response) {
|
|
36
|
+
const { status, data } = error.response;
|
|
37
|
+
yield put(fetchStructureChildrens.failure({ status, data }));
|
|
38
|
+
} else {
|
|
39
|
+
yield put(fetchStructureChildrens.failure(error.message));
|
|
40
|
+
}
|
|
41
|
+
} finally {
|
|
42
|
+
yield put(fetchStructureChildrens.fulfill());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function* fetchStructureChildrensRequestSaga() {
|
|
47
|
+
yield takeLatest(fetchStructureChildrens.TRIGGER, fetchStructureChildrensSaga);
|
|
48
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { call, put, takeLatest, select, getContext } from "redux-saga/effects";
|
|
3
|
+
import { fetchStructureParents } from "../routines";
|
|
4
|
+
import { DATA_STRUCTURE_PARENTS_QUERY } from "../api/queries";
|
|
5
|
+
import { getStructureFieldColumns } from "../selectors";
|
|
6
|
+
|
|
7
|
+
export function* fetchStructureParentsSaga({ payload }) {
|
|
8
|
+
try {
|
|
9
|
+
const client = yield getContext("client");
|
|
10
|
+
|
|
11
|
+
yield put(fetchStructureParents.request());
|
|
12
|
+
|
|
13
|
+
const { id, version = "latest" } = payload;
|
|
14
|
+
const {
|
|
15
|
+
data: { dataStructureVersion },
|
|
16
|
+
} = yield call(client.query, {
|
|
17
|
+
fetchPolicy: "network-only",
|
|
18
|
+
query: DATA_STRUCTURE_PARENTS_QUERY,
|
|
19
|
+
variables: {
|
|
20
|
+
dataStructureId: id,
|
|
21
|
+
version,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const data = {
|
|
26
|
+
data: dataStructureVersion,
|
|
27
|
+
_actions: dataStructureVersion._actions,
|
|
28
|
+
user_permissions: dataStructureVersion.user_permissions,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const meta = { version };
|
|
32
|
+
|
|
33
|
+
yield put({ meta, ...fetchStructureParents.success(data) });
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.response) {
|
|
36
|
+
const { status, data } = error.response;
|
|
37
|
+
yield put(fetchStructureParents.failure({ status, data }));
|
|
38
|
+
} else {
|
|
39
|
+
yield put(fetchStructureParents.failure(error.message));
|
|
40
|
+
}
|
|
41
|
+
} finally {
|
|
42
|
+
yield put(fetchStructureParents.fulfill());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function* fetchStructureParentsRequestSaga() {
|
|
47
|
+
yield takeLatest(fetchStructureParents.TRIGGER, fetchStructureParentsSaga);
|
|
48
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { call, put, takeLatest, getContext } from "redux-saga/effects";
|
|
2
|
+
import { fetchStructureVersions } from "../routines";
|
|
3
|
+
import { DATA_STRUCTURE_VERSION_VERSIONS_QUERY } from "../api/queries";
|
|
4
|
+
|
|
5
|
+
export function* fetchStructureVersionsSaga({ payload }) {
|
|
6
|
+
try {
|
|
7
|
+
const client = yield getContext("client");
|
|
8
|
+
|
|
9
|
+
yield put(fetchStructureVersions.request());
|
|
10
|
+
|
|
11
|
+
const { id, version = "latest" } = payload;
|
|
12
|
+
const {
|
|
13
|
+
data: { dataStructureVersion },
|
|
14
|
+
} = yield call(client.query, {
|
|
15
|
+
fetchPolicy: "network-only",
|
|
16
|
+
query: DATA_STRUCTURE_VERSION_VERSIONS_QUERY,
|
|
17
|
+
variables: {
|
|
18
|
+
dataStructureId: id,
|
|
19
|
+
version,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const data = {
|
|
24
|
+
data: dataStructureVersion,
|
|
25
|
+
_actions: dataStructureVersion._actions,
|
|
26
|
+
user_permissions: dataStructureVersion.user_permissions,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const meta = { version };
|
|
30
|
+
|
|
31
|
+
yield put({ meta, ...fetchStructureVersions.success(data) });
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error.response) {
|
|
34
|
+
const { status, data } = error.response;
|
|
35
|
+
yield put(fetchStructureVersions.failure({ status, data }));
|
|
36
|
+
} else {
|
|
37
|
+
yield put(fetchStructureVersions.failure(error.message));
|
|
38
|
+
}
|
|
39
|
+
} finally {
|
|
40
|
+
yield put(fetchStructureVersions.fulfill());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function* fetchStructureVersionsRequestSaga() {
|
|
45
|
+
yield takeLatest(fetchStructureVersions.TRIGGER, fetchStructureVersionsSaga);
|
|
46
|
+
}
|
package/src/sagas/index.js
CHANGED
|
@@ -32,6 +32,8 @@ import { fetchProfileGroupRequestSaga } from "./fetchProfileGroup";
|
|
|
32
32
|
import { fetchStructureGraphRequestSaga } from "./fetchStructureGraph";
|
|
33
33
|
import { fetchStructureNotesRequestSaga } from "./fetchStructureNotes";
|
|
34
34
|
import { fetchStructureRequestSaga } from "./fetchStructure";
|
|
35
|
+
import { fetchStructureParentsRequestSaga } from "./fetchStructureParents";
|
|
36
|
+
import { fetchStructureChildrensRequestSaga } from "./fetchStructureChildrens";
|
|
35
37
|
import { fetchStructureTypeRequestSaga } from "./fetchStructureType";
|
|
36
38
|
import { fetchStructureTypesRequestSaga } from "./fetchStructureTypes";
|
|
37
39
|
import { fetchStructuresRequestSaga } from "./fetchStructures";
|
|
@@ -2,10 +2,10 @@ import { getTabVisibility } from "../getTabVisibility";
|
|
|
2
2
|
|
|
3
3
|
describe("selectors: getTabVisibility", () => {
|
|
4
4
|
it("should include fields iff structureFields is not empty", () => {
|
|
5
|
-
expect(getTabVisibility({
|
|
5
|
+
expect(getTabVisibility({ structure: { data_fields_count: 1 } })).toMatchObject({
|
|
6
6
|
fields: true,
|
|
7
7
|
});
|
|
8
|
-
expect(getTabVisibility({
|
|
8
|
+
expect(getTabVisibility({ structure: { data_fields_count: 0 } })).toMatchObject({
|
|
9
9
|
fields: false,
|
|
10
10
|
});
|
|
11
11
|
});
|
|
@@ -122,10 +122,10 @@ describe("selectors: getTabVisibility", () => {
|
|
|
122
122
|
|
|
123
123
|
it("should include versions iff structureVersions is not empty", () => {
|
|
124
124
|
expect(getTabVisibility({})).toMatchObject({ versions: false });
|
|
125
|
-
expect(getTabVisibility({
|
|
125
|
+
expect(getTabVisibility({ structure: { version_count: 0 } })).toMatchObject({
|
|
126
126
|
versions: false,
|
|
127
127
|
});
|
|
128
|
-
expect(getTabVisibility({
|
|
128
|
+
expect(getTabVisibility({ structure: { version_count: 1 } })).toMatchObject({
|
|
129
129
|
versions: true,
|
|
130
130
|
});
|
|
131
131
|
});
|
|
@@ -224,10 +224,10 @@ describe("selectors: getTabVisibility", () => {
|
|
|
224
224
|
expect(getTabVisibility({ structure: {} })).toMatchObject({
|
|
225
225
|
grants: false,
|
|
226
226
|
});
|
|
227
|
-
expect(getTabVisibility({ structure: {
|
|
227
|
+
expect(getTabVisibility({ structure: { grants_count: 0 } })).toMatchObject({
|
|
228
228
|
grants: false,
|
|
229
229
|
});
|
|
230
|
-
expect(getTabVisibility({ structure: {
|
|
230
|
+
expect(getTabVisibility({ structure: { grants_count: 1 } })).toMatchObject({
|
|
231
231
|
grants: true,
|
|
232
232
|
});
|
|
233
233
|
});
|
|
@@ -6,7 +6,7 @@ const notEmpty = _.negate(_.isEmpty);
|
|
|
6
6
|
const notEmptyPath = (path) => _.flow(_.path(path), notEmpty);
|
|
7
7
|
const hasProfile = notEmptyPath("profile");
|
|
8
8
|
|
|
9
|
-
const fieldsTabVisible =
|
|
9
|
+
const fieldsTabVisible = (state) => state?.structure?.data_fields_count > 0;
|
|
10
10
|
|
|
11
11
|
const profileTabVisible = ({
|
|
12
12
|
userPermissions,
|
|
@@ -36,7 +36,8 @@ const notesTabVisible = ({ templatesLoading, templates, structure }) =>
|
|
|
36
36
|
_.negate(_.isNil)
|
|
37
37
|
)(templates);
|
|
38
38
|
|
|
39
|
-
const versionsTabVisible = notEmptyPath("structureVersions");
|
|
39
|
+
// const versionsTabVisible = notEmptyPath("structureVersions");
|
|
40
|
+
const versionsTabVisible = (state) => state?.structure?.version_count > 0;
|
|
40
41
|
|
|
41
42
|
const structureLinksTabVisible = (state) =>
|
|
42
43
|
_.has("create_struct_to_struct_link", state?.structureActions) ||
|
|
@@ -56,7 +57,8 @@ const eventsTabVisible = _.flow(
|
|
|
56
57
|
_.prop("structureVersion"),
|
|
57
58
|
_.isEqual("latest")
|
|
58
59
|
);
|
|
59
|
-
const grantsTabVisible =
|
|
60
|
+
const grantsTabVisible = (state) => state?.structure?.grants_count > 0;
|
|
61
|
+
|
|
60
62
|
const metatadaVisible = (state) => !_.isEmpty(_.path(["structure", "structure_type", "metadata_views"])(state))
|
|
61
63
|
|
|
62
64
|
export const getTabVisibility = createSelector([state => state], (state) => ({
|