@truedat/dd 6.3.1 → 6.3.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 +6 -6
- package/src/api/queries.js +1 -11
- package/src/components/AddStructureMember.js +24 -0
- package/src/components/StructureRoles.js +6 -0
- package/src/components/StructureTabPane.js +2 -0
- package/src/components/StructureTabPaneRoutes.js +2 -0
- package/src/components/StructureTabRoutes.js +2 -0
- package/src/components/StructureTabs.js +8 -0
- package/src/components/StructuresRoutes.js +19 -1
- package/src/components/__tests__/AddStructureMember.spec.js +12 -0
- package/src/components/__tests__/StructureRoles.spec.js +23 -0
- package/src/components/__tests__/StructureTabPane.spec.js +1 -0
- package/src/components/__tests__/StructureTabs.spec.js +2 -0
- package/src/components/__tests__/__snapshots__/AddStructureMember.spec.js.snap +160 -0
- package/src/components/__tests__/__snapshots__/StructureRoles.spec.js.snap +44 -0
- package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +6 -0
- package/src/components/__tests__/__snapshots__/StructureTabRoutes.spec.js.snap +4 -0
- package/src/components/__tests__/__snapshots__/StructureTabs.spec.js.snap +6 -0
- package/src/reducers/structure.js +1 -0
- package/src/selectors/__tests__/getActiveTab.spec.js +4 -0
- package/src/selectors/__tests__/getTabVisibility.spec.js +7 -0
- package/src/selectors/getActiveTab.js +3 -0
- package/src/selectors/getTabVisibility.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.2",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "6.2
|
|
37
|
+
"@truedat/test": "6.3.2",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@apollo/client": "^3.7.1",
|
|
91
|
-
"@truedat/auth": "6.3.
|
|
92
|
-
"@truedat/core": "6.3.
|
|
93
|
-
"@truedat/df": "6.3.
|
|
91
|
+
"@truedat/auth": "6.3.2",
|
|
92
|
+
"@truedat/core": "6.3.2",
|
|
93
|
+
"@truedat/df": "6.3.2",
|
|
94
94
|
"lodash": "^4.17.21",
|
|
95
95
|
"moment": "^2.29.4",
|
|
96
96
|
"path-to-regexp": "^1.7.0",
|
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
"react-dom": ">= 16.8.6 < 17",
|
|
116
116
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
117
117
|
},
|
|
118
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "b9ccce69ebb729f62d28972e31b2865d74e9a0d6"
|
|
119
119
|
}
|
package/src/api/queries.js
CHANGED
|
@@ -270,6 +270,7 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
270
270
|
id
|
|
271
271
|
inserted_at
|
|
272
272
|
latest_note
|
|
273
|
+
roles
|
|
273
274
|
source {
|
|
274
275
|
external_id
|
|
275
276
|
id
|
|
@@ -277,17 +278,6 @@ export const DATA_STRUCTURE_VERSION_QUERY = gql`
|
|
|
277
278
|
source_id
|
|
278
279
|
system_id
|
|
279
280
|
updated_at
|
|
280
|
-
id
|
|
281
|
-
alias
|
|
282
|
-
confidential
|
|
283
|
-
domain_ids
|
|
284
|
-
domains {
|
|
285
|
-
id
|
|
286
|
-
name
|
|
287
|
-
}
|
|
288
|
-
external_id
|
|
289
|
-
inserted_at
|
|
290
|
-
updated_at
|
|
291
281
|
}
|
|
292
282
|
parents {
|
|
293
283
|
alias
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
import { useHistory } from "react-router-dom";
|
|
5
|
+
import AddResourceMember from "@truedat/core/components/AddResourceMember";
|
|
6
|
+
import { linkTo } from "@truedat/core/routes";
|
|
7
|
+
import StructureCrumbs from "./StructureCrumbs";
|
|
8
|
+
|
|
9
|
+
const AddStructureMember = ({ id }) => {
|
|
10
|
+
const history = useHistory();
|
|
11
|
+
const onSuccess = () => history.push(linkTo.STRUCTURE_MEMBERS({ id }));
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<StructureCrumbs />
|
|
15
|
+
<AddResourceMember type="structure" id={`${id}`} onSuccess={onSuccess} />
|
|
16
|
+
</>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
AddStructureMember.propTypes = {
|
|
21
|
+
id: PropTypes.number,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default AddStructureMember;
|
|
@@ -22,6 +22,7 @@ import StructureParentRelations from "./StructureParentRelations";
|
|
|
22
22
|
import StructureVersions from "./StructureVersions";
|
|
23
23
|
import StructureMetadata from "./StructureMetadata";
|
|
24
24
|
import StructureNotesLoader from "./StructureNotesLoader";
|
|
25
|
+
import StructureRoles from "./StructureRoles";
|
|
25
26
|
import StructureStructureLinks from "./StructureStructureLinks";
|
|
26
27
|
import StructureStructureForm from "./StructureStructureForm";
|
|
27
28
|
|
|
@@ -79,6 +80,7 @@ export const StructureTabPane = ({ activeTab, tabVisibility }) => {
|
|
|
79
80
|
{activeTab === "children" && <StructureChildrenRelations />}
|
|
80
81
|
{activeTab === "versions" && <StructureVersions />}
|
|
81
82
|
{activeTab === "events" && <StructureEvents />}
|
|
83
|
+
{activeTab === "roles" && <StructureRoles />}
|
|
82
84
|
{activeTab === "rules" && tabVisibility.rules && (
|
|
83
85
|
<RuleImplementationsTable withoutColumns={["status"]} />
|
|
84
86
|
)}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
STRUCTURE_NOTES,
|
|
14
14
|
STRUCTURE_PARENTS,
|
|
15
15
|
STRUCTURE_PROFILE,
|
|
16
|
+
STRUCTURE_MEMBERS,
|
|
16
17
|
STRUCTURE_RULES,
|
|
17
18
|
STRUCTURE_VERSION,
|
|
18
19
|
STRUCTURE_VERSIONS,
|
|
@@ -32,6 +33,7 @@ export const StructureTabPaneRoutes = ({}) => (
|
|
|
32
33
|
<Route path={STRUCTURE_NOTES} component={StructureTabPane} />
|
|
33
34
|
<Route path={STRUCTURE_GRANTS} component={StructureTabPane} />
|
|
34
35
|
<Route path={STRUCTURE_METADATA} component={StructureTabPane} />
|
|
36
|
+
<Route path={STRUCTURE_MEMBERS} component={StructureTabPane} />
|
|
35
37
|
<Route path={STRUCTURE_RULES} component={StructureTabPane} />
|
|
36
38
|
<Route path={STRUCTURE_CHILDREN} component={StructureTabPane} />
|
|
37
39
|
<Route path={STRUCTURE_PARENTS} component={StructureTabPane} />
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
STRUCTURE_NOTES,
|
|
13
13
|
STRUCTURE_PARENTS,
|
|
14
14
|
STRUCTURE_PROFILE,
|
|
15
|
+
STRUCTURE_MEMBERS,
|
|
15
16
|
STRUCTURE_RULES,
|
|
16
17
|
STRUCTURE_VERSION,
|
|
17
18
|
STRUCTURE_VERSIONS,
|
|
@@ -31,6 +32,7 @@ export const StructureTabRoutes = () => (
|
|
|
31
32
|
<Route path={STRUCTURE_EVENTS} component={StructureTabs} />
|
|
32
33
|
<Route path={STRUCTURE_METADATA} component={StructureTabs} />
|
|
33
34
|
<Route path={STRUCTURE_NOTES} component={StructureTabs} />
|
|
35
|
+
<Route path={STRUCTURE_MEMBERS} component={StructureTabs} />
|
|
34
36
|
<Route path={STRUCTURE_RULES} component={StructureTabs} />
|
|
35
37
|
<Route path={STRUCTURE_LINEAGE} component={StructureTabs} />
|
|
36
38
|
<Route path={STRUCTURE_CHILDREN} component={StructureTabs} />
|
|
@@ -36,6 +36,7 @@ export const StructureTabs = ({
|
|
|
36
36
|
parents,
|
|
37
37
|
profile,
|
|
38
38
|
rules,
|
|
39
|
+
roles,
|
|
39
40
|
versions,
|
|
40
41
|
} = {},
|
|
41
42
|
structure,
|
|
@@ -144,6 +145,13 @@ export const StructureTabs = ({
|
|
|
144
145
|
content: events ? formatMessage({ id: "tabs.dd.audit" }) : false,
|
|
145
146
|
key: "events",
|
|
146
147
|
},
|
|
148
|
+
{
|
|
149
|
+
active: activeTab === "roles",
|
|
150
|
+
as: Link,
|
|
151
|
+
to: linkTo.STRUCTURE_MEMBERS(structure),
|
|
152
|
+
content: roles ? formatMessage({ id: "tabs.dd.roles" }) : false,
|
|
153
|
+
key: "roles",
|
|
154
|
+
},
|
|
147
155
|
])
|
|
148
156
|
: null;
|
|
149
157
|
return (
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
|
+
|
|
3
4
|
import { useIntl } from "react-intl";
|
|
4
5
|
import { Route, Switch, useRouteMatch } from "react-router-dom";
|
|
5
6
|
import { Unauthorized } from "@truedat/core/components";
|
|
@@ -12,7 +13,9 @@ import {
|
|
|
12
13
|
STRUCTURES_BULK_UPDATE,
|
|
13
14
|
STRUCTURE_EVENTS,
|
|
14
15
|
STRUCTURE_VERSION,
|
|
16
|
+
STRUCTURE_MEMBERS_NEW,
|
|
15
17
|
} from "@truedat/core/routes";
|
|
18
|
+
import AddStructureMember from "./AddStructureMember";
|
|
16
19
|
import StructureCrumbs from "./StructureCrumbs";
|
|
17
20
|
import StructureLoader from "./StructureLoader";
|
|
18
21
|
import UserSearchFiltersLoader from "./UserSearchFiltersLoader";
|
|
@@ -32,6 +35,10 @@ const RuleImplementationsLoader = React.lazy(() =>
|
|
|
32
35
|
import("@truedat/dq/components/RuleImplementationsLoader")
|
|
33
36
|
);
|
|
34
37
|
|
|
38
|
+
const RolesLoader = React.lazy(() =>
|
|
39
|
+
import("@truedat/auth/roles/components/RolesLoader")
|
|
40
|
+
);
|
|
41
|
+
|
|
35
42
|
const ConceptSelectorConceptsLoader = () => (
|
|
36
43
|
<ConceptsLoader
|
|
37
44
|
pageSize={7}
|
|
@@ -118,7 +125,18 @@ const AuthorizedRoutes = () => {
|
|
|
118
125
|
);
|
|
119
126
|
}}
|
|
120
127
|
/>
|
|
121
|
-
<
|
|
128
|
+
<Switch>
|
|
129
|
+
<Route
|
|
130
|
+
path={STRUCTURE_MEMBERS_NEW}
|
|
131
|
+
render={({ match }) => (
|
|
132
|
+
<>
|
|
133
|
+
<RolesLoader />
|
|
134
|
+
<AddStructureMember id={parseInt(match?.params?.id)} />
|
|
135
|
+
</>
|
|
136
|
+
)}
|
|
137
|
+
/>
|
|
138
|
+
<Route path={STRUCTURE} component={StructureView} />
|
|
139
|
+
</Switch>
|
|
122
140
|
</>
|
|
123
141
|
);
|
|
124
142
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import AddStructureMember from "../AddStructureMember";
|
|
4
|
+
|
|
5
|
+
const props = { id: 1 };
|
|
6
|
+
|
|
7
|
+
describe("<AddStructureMember />", () => {
|
|
8
|
+
it("matches the latest snapshot", () => {
|
|
9
|
+
const { container } = render(<AddStructureMember {...props} />);
|
|
10
|
+
expect(container).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react";
|
|
3
|
+
import { intl } from "@truedat/test/intl-stub";
|
|
4
|
+
import StructureRoles from "../StructureRoles";
|
|
5
|
+
|
|
6
|
+
// workaround for enzyme issue with React.useContext
|
|
7
|
+
// see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
|
|
8
|
+
jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
9
|
+
jest.mock("react-router-dom", () => ({
|
|
10
|
+
...jest.requireActual("react-router-dom"),
|
|
11
|
+
useParams: jest.fn().mockReturnValue({ id: 1 }),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe("<StructureRoles />", () => {
|
|
15
|
+
const props = {
|
|
16
|
+
type: "domain",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
it("matches the latest snapshot", () => {
|
|
20
|
+
const { container } = render(<StructureRoles {...props} />);
|
|
21
|
+
expect(container).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -15,6 +15,7 @@ const renderOpts = {
|
|
|
15
15
|
"tabs.dd.versions": "Versions",
|
|
16
16
|
"tabs.dd.grants": "Grants",
|
|
17
17
|
"tabs.dd.rules": "Rules",
|
|
18
|
+
"tabs.dd.roles": "Roles",
|
|
18
19
|
},
|
|
19
20
|
},
|
|
20
21
|
};
|
|
@@ -32,6 +33,7 @@ describe("<StructureTabs />", () => {
|
|
|
32
33
|
"grants",
|
|
33
34
|
"notes",
|
|
34
35
|
"rules",
|
|
36
|
+
"roles",
|
|
35
37
|
"events",
|
|
36
38
|
];
|
|
37
39
|
const structure = { id: 123 };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<AddStructureMember /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui segment ui text container"
|
|
7
|
+
>
|
|
8
|
+
<h2
|
|
9
|
+
class="ui header"
|
|
10
|
+
>
|
|
11
|
+
<i
|
|
12
|
+
aria-hidden="true"
|
|
13
|
+
class="id card outline icon"
|
|
14
|
+
/>
|
|
15
|
+
<div
|
|
16
|
+
class="content"
|
|
17
|
+
>
|
|
18
|
+
Add
|
|
19
|
+
</div>
|
|
20
|
+
</h2>
|
|
21
|
+
<form
|
|
22
|
+
class="ui form"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
class="required field"
|
|
26
|
+
>
|
|
27
|
+
<label
|
|
28
|
+
for="principal"
|
|
29
|
+
>
|
|
30
|
+
Member
|
|
31
|
+
</label>
|
|
32
|
+
<div
|
|
33
|
+
aria-expanded="false"
|
|
34
|
+
class="ui search selection dropdown"
|
|
35
|
+
required=""
|
|
36
|
+
role="combobox"
|
|
37
|
+
>
|
|
38
|
+
<input
|
|
39
|
+
aria-autocomplete="list"
|
|
40
|
+
autocomplete="off"
|
|
41
|
+
class="search"
|
|
42
|
+
tabindex="0"
|
|
43
|
+
type="text"
|
|
44
|
+
value=""
|
|
45
|
+
/>
|
|
46
|
+
<div
|
|
47
|
+
aria-atomic="true"
|
|
48
|
+
aria-live="polite"
|
|
49
|
+
class="divider default text"
|
|
50
|
+
role="alert"
|
|
51
|
+
>
|
|
52
|
+
Member
|
|
53
|
+
</div>
|
|
54
|
+
<i
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
class="dropdown icon"
|
|
57
|
+
/>
|
|
58
|
+
<div
|
|
59
|
+
class="menu transition"
|
|
60
|
+
role="listbox"
|
|
61
|
+
>
|
|
62
|
+
<div
|
|
63
|
+
class="message"
|
|
64
|
+
>
|
|
65
|
+
No results found.
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
<div
|
|
71
|
+
class="required field"
|
|
72
|
+
>
|
|
73
|
+
<label
|
|
74
|
+
for="role"
|
|
75
|
+
>
|
|
76
|
+
Role
|
|
77
|
+
</label>
|
|
78
|
+
<div
|
|
79
|
+
aria-expanded="false"
|
|
80
|
+
class="ui basic search selection dropdown"
|
|
81
|
+
required=""
|
|
82
|
+
role="combobox"
|
|
83
|
+
>
|
|
84
|
+
<input
|
|
85
|
+
aria-autocomplete="list"
|
|
86
|
+
autocomplete="off"
|
|
87
|
+
class="search"
|
|
88
|
+
id="role"
|
|
89
|
+
tabindex="0"
|
|
90
|
+
type="text"
|
|
91
|
+
value=""
|
|
92
|
+
/>
|
|
93
|
+
<div
|
|
94
|
+
aria-atomic="true"
|
|
95
|
+
aria-live="polite"
|
|
96
|
+
class="divider default text"
|
|
97
|
+
role="alert"
|
|
98
|
+
>
|
|
99
|
+
Role
|
|
100
|
+
</div>
|
|
101
|
+
<i
|
|
102
|
+
aria-hidden="true"
|
|
103
|
+
class="dropdown icon"
|
|
104
|
+
/>
|
|
105
|
+
<div
|
|
106
|
+
class="menu transition"
|
|
107
|
+
role="listbox"
|
|
108
|
+
>
|
|
109
|
+
<div
|
|
110
|
+
class="message"
|
|
111
|
+
>
|
|
112
|
+
No results found.
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div
|
|
118
|
+
class="field"
|
|
119
|
+
>
|
|
120
|
+
<label
|
|
121
|
+
for="description"
|
|
122
|
+
>
|
|
123
|
+
Description
|
|
124
|
+
</label>
|
|
125
|
+
<div
|
|
126
|
+
class="ui input"
|
|
127
|
+
>
|
|
128
|
+
<input
|
|
129
|
+
autocomplete="off"
|
|
130
|
+
id="description"
|
|
131
|
+
maxlength="120"
|
|
132
|
+
placeholder="Description"
|
|
133
|
+
type="text"
|
|
134
|
+
value=""
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
<div
|
|
139
|
+
class="actions"
|
|
140
|
+
>
|
|
141
|
+
<button
|
|
142
|
+
class="ui primary disabled right floated button"
|
|
143
|
+
disabled=""
|
|
144
|
+
tabindex="-1"
|
|
145
|
+
type="submit"
|
|
146
|
+
>
|
|
147
|
+
Add
|
|
148
|
+
</button>
|
|
149
|
+
<a
|
|
150
|
+
class="ui secondary button"
|
|
151
|
+
href="/"
|
|
152
|
+
role="button"
|
|
153
|
+
>
|
|
154
|
+
Cancel
|
|
155
|
+
</a>
|
|
156
|
+
</div>
|
|
157
|
+
</form>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
`;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<StructureRoles /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui centered one column grid"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="column"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="ui icon input"
|
|
13
|
+
>
|
|
14
|
+
<input
|
|
15
|
+
placeholder="user.search.placeholder"
|
|
16
|
+
type="text"
|
|
17
|
+
value=""
|
|
18
|
+
/>
|
|
19
|
+
<i
|
|
20
|
+
aria-hidden="true"
|
|
21
|
+
class="search link icon"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div
|
|
27
|
+
class="ui icon message"
|
|
28
|
+
>
|
|
29
|
+
<i
|
|
30
|
+
aria-hidden="true"
|
|
31
|
+
class="warning icon"
|
|
32
|
+
/>
|
|
33
|
+
<div
|
|
34
|
+
class="content"
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
class="header"
|
|
38
|
+
>
|
|
39
|
+
domain.members.empty
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
`;
|
|
@@ -59,6 +59,12 @@ exports[`<StructureTabPane /> matches the latest snapshot: profile 1`] = `
|
|
|
59
59
|
</ErrorBoundary>
|
|
60
60
|
`;
|
|
61
61
|
|
|
62
|
+
exports[`<StructureTabPane /> matches the latest snapshot: roles 1`] = `
|
|
63
|
+
<ErrorBoundary>
|
|
64
|
+
<StructureRoles />
|
|
65
|
+
</ErrorBoundary>
|
|
66
|
+
`;
|
|
67
|
+
|
|
62
68
|
exports[`<StructureTabPane /> matches the latest snapshot: versions 1`] = `
|
|
63
69
|
<ErrorBoundary>
|
|
64
70
|
<Connect(StructureVersions) />
|
|
@@ -38,6 +38,10 @@ exports[`<StructureTabRoutes /> matches the latest snapshot 1`] = `
|
|
|
38
38
|
component={[Function]}
|
|
39
39
|
path="/structures/:id/notes"
|
|
40
40
|
/>
|
|
41
|
+
<Route
|
|
42
|
+
component={[Function]}
|
|
43
|
+
path="/structures/:id/members"
|
|
44
|
+
/>
|
|
41
45
|
<Route
|
|
42
46
|
component={[Function]}
|
|
43
47
|
path="/structures/:id/rules"
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
STRUCTURE_PARENTS,
|
|
12
12
|
STRUCTURE_PROFILE,
|
|
13
13
|
STRUCTURE_RULES,
|
|
14
|
+
STRUCTURE_MEMBERS,
|
|
14
15
|
STRUCTURE_VERSION,
|
|
15
16
|
STRUCTURE_VERSIONS,
|
|
16
17
|
STRUCTURE_VERSION_VERSIONS,
|
|
@@ -26,6 +27,7 @@ describe("selectors: defaultTab", () => {
|
|
|
26
27
|
const parents = truthy;
|
|
27
28
|
const profile = truthy;
|
|
28
29
|
const rules = truthy;
|
|
30
|
+
const roles = truthy;
|
|
29
31
|
const links = truthy;
|
|
30
32
|
const versions = truthy;
|
|
31
33
|
const grants = truthy;
|
|
@@ -38,6 +40,7 @@ describe("selectors: defaultTab", () => {
|
|
|
38
40
|
expect(defaultTab({ parents, profile })).toBe("parents");
|
|
39
41
|
expect(defaultTab({ profile, rules })).toBe("profile");
|
|
40
42
|
expect(defaultTab({ links, rules })).toBe("rules");
|
|
43
|
+
expect(defaultTab({ links, roles })).toBe("roles");
|
|
41
44
|
expect(defaultTab({ links, versions })).toBe("links");
|
|
42
45
|
expect(defaultTab({ versions })).toBe("versions");
|
|
43
46
|
expect(defaultTab({})).toBe(undefined);
|
|
@@ -56,6 +59,7 @@ describe("selectors: getActiveTab", () => {
|
|
|
56
59
|
expect(getActiveTab(tabVisibility, STRUCTURE_PARENTS)).toBe("parents");
|
|
57
60
|
expect(getActiveTab(tabVisibility, STRUCTURE_PROFILE)).toBe("profile");
|
|
58
61
|
expect(getActiveTab(tabVisibility, STRUCTURE_RULES)).toBe("rules");
|
|
62
|
+
expect(getActiveTab(tabVisibility, STRUCTURE_MEMBERS)).toBe("roles");
|
|
59
63
|
expect(getActiveTab(tabVisibility, STRUCTURE_LINKS)).toBe("links");
|
|
60
64
|
expect(getActiveTab(tabVisibility, STRUCTURE_LINKS_NEW)).toBe("links");
|
|
61
65
|
expect(getActiveTab(tabVisibility, STRUCTURE_VERSIONS)).toBe("versions");
|
|
@@ -196,4 +196,11 @@ describe("selectors: getTabVisibility", () => {
|
|
|
196
196
|
grants: true,
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
|
+
|
|
200
|
+
it("should include roles if manage_structure_acl_entry action is present in structureActions", () => {
|
|
201
|
+
expect(getTabVisibility({})).toMatchObject({ roles: false });
|
|
202
|
+
expect(
|
|
203
|
+
getTabVisibility({ structureActions: { manage_structure_acl_entry: {} } })
|
|
204
|
+
).toMatchObject({ roles: true });
|
|
205
|
+
});
|
|
199
206
|
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
STRUCTURE_PARENTS,
|
|
10
10
|
STRUCTURE_PROFILE,
|
|
11
11
|
STRUCTURE_STRUCTURE_LINKS,
|
|
12
|
+
STRUCTURE_MEMBERS,
|
|
12
13
|
STRUCTURE_RULES,
|
|
13
14
|
STRUCTURE_LINKS,
|
|
14
15
|
STRUCTURE_LINKS_NEW,
|
|
@@ -29,6 +30,7 @@ export const defaultTab = _.cond([
|
|
|
29
30
|
[_.conformsTo({ parents: _.identity }), _.constant("parents")],
|
|
30
31
|
[_.conformsTo({ profile: _.identity }), _.constant("profile")],
|
|
31
32
|
[_.conformsTo({ rules: _.identity }), _.constant("rules")],
|
|
33
|
+
[_.conformsTo({ roles: _.identity }), _.constant("roles")],
|
|
32
34
|
[_.conformsTo({ links: _.identity }), _.constant("links")],
|
|
33
35
|
[_.conformsTo({ versions: _.identity }), _.constant("versions")],
|
|
34
36
|
]);
|
|
@@ -45,6 +47,7 @@ export const getActiveTab = (tabVisibility, path) => {
|
|
|
45
47
|
[_.eq(STRUCTURE_PARENTS), _.constant("parents")],
|
|
46
48
|
[_.eq(STRUCTURE_PROFILE), _.constant("profile")],
|
|
47
49
|
[_.eq(STRUCTURE_STRUCTURE_LINKS), _.constant("structureLinks")],
|
|
50
|
+
[_.eq(STRUCTURE_MEMBERS), _.constant("roles")],
|
|
48
51
|
[_.eq(STRUCTURE_RULES), _.constant("rules")],
|
|
49
52
|
[_.eq(STRUCTURE_LINKS), _.constant("links")],
|
|
50
53
|
[_.eq(STRUCTURE_LINKS_NEW), _.constant("links")],
|
|
@@ -39,6 +39,9 @@ const versionsTabVisible = notEmptyPath("structureVersions");
|
|
|
39
39
|
const structureLinksTabVisible = (state) =>
|
|
40
40
|
_.has("create_struct_to_struct_link", state?.structureActions) ||
|
|
41
41
|
state?.structure?.data_structure_link_count > 0;
|
|
42
|
+
const rolesTabVisible = (state) =>
|
|
43
|
+
_.has("manage_structure_acl_entry", state?.structureActions) ||
|
|
44
|
+
!_.isEmpty(state?.structure?.roles);
|
|
42
45
|
const rulesTabVisible = (state) => state?.structure?.implementation_count > 0;
|
|
43
46
|
const lineageTabVisible = _.anyPass([_.path("structure.degree.in")]);
|
|
44
47
|
const impactTabVisible = _.anyPass([_.path("structure.degree.out")]);
|
|
@@ -65,4 +68,5 @@ export const getTabVisibility = (state) => ({
|
|
|
65
68
|
parents: parentsTabVisible(state),
|
|
66
69
|
children: childrenTabVisible(state),
|
|
67
70
|
grants: grantsTabVisible(state),
|
|
71
|
+
roles: rolesTabVisible(state),
|
|
68
72
|
});
|