@truedat/dd 7.8.4 → 7.8.5
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/components/StructureTabPane.js +19 -23
- package/src/components/StructureTabPaneRoutes.js +9 -3
- package/src/components/StructureTabRoutes.js +62 -53
- package/src/components/StructureTabs.js +143 -168
- package/src/components/__tests__/StructureTabPane.spec.js +69 -46
- package/src/components/__tests__/StructureTabs.spec.js +5 -2
- package/src/components/__tests__/__snapshots__/StructureTabPane.spec.js.snap +8 -0
- package/src/hooks/useCustomTabs.js +14 -0
- package/src/selectors/__tests__/getActiveTab.spec.js +21 -18
- package/src/selectors/getActiveTab.js +8 -4
- package/src/selectors/getTabVisibility.js +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "7.8.
|
|
3
|
+
"version": "7.8.5",
|
|
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.8.
|
|
51
|
+
"@truedat/test": "7.8.5",
|
|
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": "54905b29b5250d45eed5e3578b0276f1c67d6f69"
|
|
87
87
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
1
2
|
import { lazy } from "react";
|
|
2
3
|
import PropTypes from "prop-types";
|
|
3
|
-
import {
|
|
4
|
+
import { useSelector } from "react-redux";
|
|
4
5
|
import { Route, Routes } from "react-router";
|
|
5
6
|
import { ErrorBoundary } from "@truedat/core/components";
|
|
6
|
-
import {
|
|
7
|
-
STRUCTURE_LINKS_NEW,
|
|
8
|
-
STRUCTURE_STRUCTURE_LINKS_NEW,
|
|
9
|
-
STRUCTURE_NOTES_EDIT,
|
|
10
|
-
} from "@truedat/core/routes";
|
|
11
7
|
import { getActiveTab } from "../selectors/getActiveTab";
|
|
8
|
+
import { useStructureCustomTabs } from "../hooks/useCustomTabs";
|
|
12
9
|
import {
|
|
13
10
|
getTabVisibility,
|
|
14
11
|
getLinkedImplementationsToStructuresColumns,
|
|
@@ -43,7 +40,19 @@ const RuleImplementationsTable = lazy(
|
|
|
43
40
|
() => import("@truedat/dq/components/RuleImplementationsTable")
|
|
44
41
|
);
|
|
45
42
|
|
|
46
|
-
|
|
43
|
+
const CustomTab = ({ tabs, activeTab }) => {
|
|
44
|
+
if (_.isEmpty(tabs)) return null;
|
|
45
|
+
const tab = _.find((tab) => (tab.name === activeTab))(tabs);
|
|
46
|
+
return tab?.content;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const StructureTabPane = ({ path }) => {
|
|
50
|
+
const customTabs = useStructureCustomTabs();
|
|
51
|
+
const tabVisibility = useSelector(getTabVisibility);
|
|
52
|
+
const structureTabsOrder = useSelector(state => state.structureTabsOrder);
|
|
53
|
+
const columns = useSelector(state => getLinkedImplementationsToStructuresColumns(state));
|
|
54
|
+
const activeTab = getActiveTab({ tabVisibility, path, structureTabsOrder, customTabs });
|
|
55
|
+
|
|
47
56
|
return (
|
|
48
57
|
<ErrorBoundary>
|
|
49
58
|
{activeTab === "fields" && <StructureFields />}
|
|
@@ -83,24 +92,11 @@ export const StructureTabPane = ({ activeTab, tabVisibility, columns }) => {
|
|
|
83
92
|
)}
|
|
84
93
|
{activeTab === "lineage" && <StructureLineage />}
|
|
85
94
|
{activeTab === "impact" && <StructureImpact />}
|
|
95
|
+
{<CustomTab tabs={customTabs} activeTab={activeTab} />}
|
|
86
96
|
</ErrorBoundary>
|
|
87
97
|
);
|
|
88
98
|
};
|
|
89
99
|
|
|
90
|
-
StructureTabPane.propTypes = {
|
|
91
|
-
activeTab: PropTypes.string,
|
|
92
|
-
tabVisibility: PropTypes.object,
|
|
93
|
-
columns: PropTypes.array,
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const mapStateToProps = ({ structureTabsOrder, ...state }, { path }) => {
|
|
97
|
-
const tabVisibility = getTabVisibility(state);
|
|
98
|
-
const activeTab = getActiveTab(tabVisibility, path, structureTabsOrder);
|
|
99
|
-
return {
|
|
100
|
-
tabVisibility,
|
|
101
|
-
activeTab,
|
|
102
|
-
columns: getLinkedImplementationsToStructuresColumns(state),
|
|
103
|
-
};
|
|
104
|
-
};
|
|
100
|
+
StructureTabPane.propTypes = { path: PropTypes.string, };
|
|
105
101
|
|
|
106
|
-
export default
|
|
102
|
+
export default StructureTabPane;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
1
2
|
import { lazy } from "react";
|
|
2
3
|
import { Route, Routes } from "react-router";
|
|
3
4
|
import {
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
STRUCTURE_VERSIONS,
|
|
22
23
|
STRUCTURE_VERSION_VERSIONS,
|
|
23
24
|
} from "@truedat/core/routes";
|
|
25
|
+
import { useStructureCustomTabs } from "../hooks/useCustomTabs";
|
|
24
26
|
import { useParams } from "react-router";
|
|
25
27
|
import StructureTabPane from "./StructureTabPane";
|
|
26
28
|
|
|
@@ -32,8 +34,9 @@ const StructureEventsLoader = () => {
|
|
|
32
34
|
return <EventsLoader resource_id={id} resource_type="data_structure" />;
|
|
33
35
|
};
|
|
34
36
|
|
|
35
|
-
export const StructureTabPaneRoutes = ({}) =>
|
|
36
|
-
|
|
37
|
+
export const StructureTabPaneRoutes = ({ }) => {
|
|
38
|
+
const customTabs = useStructureCustomTabs();
|
|
39
|
+
return <Routes>
|
|
37
40
|
<Route index exact element={<StructureTabPane path={STRUCTURE} />} />
|
|
38
41
|
|
|
39
42
|
<Route path="versions">
|
|
@@ -110,7 +113,10 @@ export const StructureTabPaneRoutes = ({}) => (
|
|
|
110
113
|
path="grants"
|
|
111
114
|
element={<StructureTabPane path={STRUCTURE_GRANTS} />}
|
|
112
115
|
/>
|
|
116
|
+
{_.map((tab) => (
|
|
117
|
+
<Route path={tab.name} element={<StructureTabPane path={tab.route} />} />
|
|
118
|
+
))(customTabs)}
|
|
113
119
|
</Routes>
|
|
114
|
-
|
|
120
|
+
};
|
|
115
121
|
|
|
116
122
|
export default StructureTabPaneRoutes;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
1
2
|
import { Route, Routes } from "react-router";
|
|
2
3
|
import {
|
|
3
4
|
STRUCTURE,
|
|
@@ -20,64 +21,72 @@ import {
|
|
|
20
21
|
STRUCTURE_VERSION_VERSIONS,
|
|
21
22
|
STRUCTURE_METADATA,
|
|
22
23
|
} from "@truedat/core/routes";
|
|
24
|
+
import { useStructureCustomTabs } from "../hooks/useCustomTabs";
|
|
23
25
|
import StructureTabs from "./StructureTabs";
|
|
24
26
|
|
|
25
|
-
export const StructureTabRoutes = () =>
|
|
26
|
-
|
|
27
|
-
<Route index exact element={<StructureTabs path={STRUCTURE} />} />
|
|
27
|
+
export const StructureTabRoutes = () => {
|
|
28
|
+
const customTabs = useStructureCustomTabs();
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
return (
|
|
31
|
+
<Routes>
|
|
32
|
+
<Route index exact element={<StructureTabs path={STRUCTURE} />} />
|
|
31
33
|
|
|
32
|
-
<Route path="
|
|
33
|
-
<Route index element={<StructureTabs path={
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
element={<StructureTabs path={
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
<Route path="versions">
|
|
35
|
+
<Route index element={<StructureTabs path={STRUCTURE_VERSIONS} />} />
|
|
36
|
+
|
|
37
|
+
<Route path=":version">
|
|
38
|
+
<Route index element={<StructureTabs path={STRUCTURE_VERSION} />} />
|
|
39
|
+
<Route
|
|
40
|
+
path="versions"
|
|
41
|
+
element={<StructureTabs path={STRUCTURE_VERSION_VERSIONS} />}
|
|
42
|
+
/>
|
|
43
|
+
<Route
|
|
44
|
+
path="fields"
|
|
45
|
+
element={<StructureTabs path={STRUCTURE_VERSION_FIELDS} />}
|
|
46
|
+
/>
|
|
47
|
+
</Route>
|
|
42
48
|
</Route>
|
|
43
|
-
</Route>
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
50
|
+
<Route
|
|
51
|
+
path="profile"
|
|
52
|
+
element={<StructureTabs path={STRUCTURE_PROFILE} />}
|
|
53
|
+
/>
|
|
54
|
+
<Route path="links/*" element={<StructureTabs path={STRUCTURE_LINKS} />} />
|
|
55
|
+
<Route
|
|
56
|
+
path="structureLinks/*"
|
|
57
|
+
element={<StructureTabs path={STRUCTURE_STRUCTURE_LINKS} />}
|
|
58
|
+
/>
|
|
59
|
+
<Route path="events" element={<StructureTabs path={STRUCTURE_EVENTS} />} />
|
|
60
|
+
<Route
|
|
61
|
+
path="metadata"
|
|
62
|
+
element={<StructureTabs path={STRUCTURE_METADATA} />}
|
|
63
|
+
/>
|
|
64
|
+
<Route path="notes/*" element={<StructureTabs path={STRUCTURE_NOTES} />} />
|
|
65
|
+
<Route
|
|
66
|
+
path="members"
|
|
67
|
+
element={<StructureTabs path={STRUCTURE_MEMBERS} />}
|
|
68
|
+
/>
|
|
69
|
+
<Route path="rules" element={<StructureTabs path={STRUCTURE_RULES} />} />
|
|
70
|
+
<Route
|
|
71
|
+
path="lineage"
|
|
72
|
+
element={<StructureTabs path={STRUCTURE_LINEAGE} />}
|
|
73
|
+
/>
|
|
74
|
+
<Route
|
|
75
|
+
path="children"
|
|
76
|
+
element={<StructureTabs path={STRUCTURE_CHILDREN} />}
|
|
77
|
+
/>
|
|
78
|
+
<Route path="fields" element={<StructureTabs path={STRUCTURE_FIELDS} />} />
|
|
79
|
+
<Route
|
|
80
|
+
path="parents"
|
|
81
|
+
element={<StructureTabs path={STRUCTURE_PARENTS} />}
|
|
82
|
+
/>
|
|
83
|
+
<Route path="impact" element={<StructureTabs path={STRUCTURE_IMPACT} />} />
|
|
84
|
+
<Route path="grants" element={<StructureTabs path={STRUCTURE_GRANTS} />} />
|
|
85
|
+
{_.map((tab) => (
|
|
86
|
+
<Route path={tab.name} element={<StructureTabs path={`/structures/:id/${tab.name}`} />} />
|
|
87
|
+
))(customTabs)}
|
|
88
|
+
</Routes>
|
|
89
|
+
)
|
|
90
|
+
};
|
|
82
91
|
|
|
83
92
|
export default StructureTabRoutes;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
+
import { compile } from "path-to-regexp";
|
|
2
3
|
import PropTypes from "prop-types";
|
|
3
4
|
import { Divider, Menu } from "semantic-ui-react";
|
|
4
5
|
import { Link } from "react-router";
|
|
5
|
-
import {
|
|
6
|
+
import { useSelector } from "react-redux";
|
|
6
7
|
import { useIntl } from "react-intl";
|
|
7
8
|
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
import { useStructureCustomTabs } from "../hooks/useCustomTabs";
|
|
8
10
|
import { getActiveTab } from "../selectors/getActiveTab";
|
|
9
11
|
import { getTabVisibility } from "../selectors/getTabVisibility";
|
|
10
12
|
|
|
@@ -19,157 +21,151 @@ const versionsLink = ({ id }, version) =>
|
|
|
19
21
|
? linkTo.STRUCTURE_VERSIONS({ id })
|
|
20
22
|
: linkTo.STRUCTURE_VERSION_VERSIONS({ id, version });
|
|
21
23
|
|
|
22
|
-
export const StructureTabs = ({
|
|
23
|
-
activeTab,
|
|
24
|
-
tabVisibility: {
|
|
25
|
-
children,
|
|
26
|
-
events,
|
|
27
|
-
fields,
|
|
28
|
-
grants,
|
|
29
|
-
impact,
|
|
30
|
-
lineage,
|
|
31
|
-
links,
|
|
32
|
-
structureLinks,
|
|
33
|
-
metadata,
|
|
34
|
-
notes,
|
|
35
|
-
parents,
|
|
36
|
-
profile,
|
|
37
|
-
rules,
|
|
38
|
-
roles,
|
|
39
|
-
versions,
|
|
40
|
-
} = {},
|
|
41
|
-
structure,
|
|
42
|
-
structureTabsOrder,
|
|
43
|
-
version,
|
|
44
|
-
}) => {
|
|
24
|
+
export const StructureTabs = ({ path }) => {
|
|
45
25
|
const { formatMessage } = useIntl();
|
|
26
|
+
const customTabs = useStructureCustomTabs();
|
|
27
|
+
const version = useSelector(state => state.structureVersion);
|
|
28
|
+
const structure = useSelector(state => state.structure);
|
|
29
|
+
const structureTabsOrder = useSelector(state => state.structureTabsOrder);
|
|
30
|
+
const tabVisibility = useSelector(getTabVisibility);
|
|
31
|
+
const activeTab = getActiveTab({ tabVisibility, path, structureTabsOrder, customTabs });
|
|
32
|
+
|
|
33
|
+
const customTabsItems = _.map((tab) => ({
|
|
34
|
+
active: activeTab === tab.name,
|
|
35
|
+
as: Link,
|
|
36
|
+
to: compile(tab.route)({ id: structure.id }),
|
|
37
|
+
content: formatMessage({ id: `tabs.dd.${tab.name}` }),
|
|
38
|
+
key: tab.name,
|
|
39
|
+
}))(customTabs);
|
|
40
|
+
|
|
46
41
|
const items = !_.isEmpty(structure)
|
|
47
42
|
? _.filter("content")([
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
43
|
+
{
|
|
44
|
+
active: activeTab === "fields",
|
|
45
|
+
as: Link,
|
|
46
|
+
to: structureFields(structure, version),
|
|
47
|
+
content: tabVisibility?.fields ? formatMessage({ id: "tabs.dd.fields" }) : false,
|
|
48
|
+
key: "fields",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
active: activeTab === "children",
|
|
52
|
+
as: Link,
|
|
53
|
+
to: linkTo.STRUCTURE_CHILDREN(structure),
|
|
54
|
+
content: tabVisibility?.children ? formatMessage({ id: "tabs.dd.children" }) : false,
|
|
55
|
+
key: "children",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
active: activeTab === "notes",
|
|
59
|
+
as: Link,
|
|
60
|
+
to: linkTo.STRUCTURE_NOTES(structure),
|
|
61
|
+
content: tabVisibility?.notes ? formatMessage({ id: "tabs.dd.notes" }) : false,
|
|
62
|
+
key: "notes",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
active: activeTab === "parents",
|
|
66
|
+
as: Link,
|
|
67
|
+
to: linkTo.STRUCTURE_PARENTS(structure),
|
|
68
|
+
content: tabVisibility?.parents ? formatMessage({ id: "tabs.dd.parents" }) : false,
|
|
69
|
+
key: "parents",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
active: activeTab === "grants",
|
|
73
|
+
as: Link,
|
|
74
|
+
to: linkTo.STRUCTURE_GRANTS(structure),
|
|
75
|
+
content: tabVisibility?.grants ? formatMessage({ id: "tabs.dd.grants" }) : false,
|
|
76
|
+
key: "grants",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
active: activeTab === "metadata",
|
|
80
|
+
as: Link,
|
|
81
|
+
to: linkTo.STRUCTURE_METADATA(structure),
|
|
82
|
+
content: tabVisibility?.metadata ? formatMessage({ id: "tabs.dd.metadata" }) : false,
|
|
83
|
+
key: "metadata",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
active: activeTab === "profile",
|
|
87
|
+
as: Link,
|
|
88
|
+
to: linkTo.STRUCTURE_PROFILE(structure),
|
|
89
|
+
content: tabVisibility?.profile ? formatMessage({ id: "tabs.dd.profile" }) : false,
|
|
90
|
+
key: "profile",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
active: activeTab === "rules",
|
|
94
|
+
as: Link,
|
|
95
|
+
to: linkTo.STRUCTURE_RULES(structure),
|
|
96
|
+
content: tabVisibility?.rules ? formatMessage({ id: "tabs.dd.rules" }) : false,
|
|
97
|
+
key: "rules",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
active: activeTab === "links",
|
|
101
|
+
as: Link,
|
|
102
|
+
to: linkTo.STRUCTURE_LINKS(structure),
|
|
103
|
+
content: tabVisibility?.links ? formatMessage({ id: "tabs.dd.links" }) : false,
|
|
104
|
+
key: "links",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
active: activeTab === "structureLinks",
|
|
108
|
+
as: Link,
|
|
109
|
+
to: linkTo.STRUCTURE_STRUCTURE_LINKS(structure),
|
|
110
|
+
content: tabVisibility?.structureLinks
|
|
111
|
+
? formatMessage({ id: "tabs.dd.structureLinks" })
|
|
112
|
+
: false,
|
|
113
|
+
key: "structureLinks",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
active: activeTab === "lineage",
|
|
117
|
+
as: Link,
|
|
118
|
+
to: linkTo.STRUCTURE_LINEAGE(structure),
|
|
119
|
+
content: tabVisibility?.lineage ? formatMessage({ id: "tabs.dd.lineage" }) : false,
|
|
120
|
+
key: "lineage",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
active: activeTab === "impact",
|
|
124
|
+
as: Link,
|
|
125
|
+
to: linkTo.STRUCTURE_IMPACT(structure),
|
|
126
|
+
content: tabVisibility?.impact ? formatMessage({ id: "tabs.dd.impact" }) : false,
|
|
127
|
+
key: "impact",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
active: activeTab === "versions",
|
|
131
|
+
as: Link,
|
|
132
|
+
to: versionsLink(structure, version),
|
|
133
|
+
content: tabVisibility?.versions ? formatMessage({ id: "tabs.dd.versions" }) : false,
|
|
134
|
+
key: "versions",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
active: activeTab === "events",
|
|
138
|
+
as: Link,
|
|
139
|
+
to: linkTo.STRUCTURE_EVENTS(structure),
|
|
140
|
+
content: tabVisibility?.events ? formatMessage({ id: "tabs.dd.audit" }) : false,
|
|
141
|
+
key: "events",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
active: activeTab === "roles",
|
|
145
|
+
as: Link,
|
|
146
|
+
to: linkTo.STRUCTURE_MEMBERS(structure),
|
|
147
|
+
content: tabVisibility?.roles ? formatMessage({ id: "tabs.dd.roles" }) : false,
|
|
148
|
+
key: "roles",
|
|
149
|
+
},
|
|
150
|
+
...customTabsItems,
|
|
151
|
+
])
|
|
156
152
|
: null;
|
|
157
153
|
|
|
158
154
|
structureTabsOrder
|
|
159
155
|
? items.sort((a, b) => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
156
|
+
const aIndex = _.indexOf(a.key)(structureTabsOrder);
|
|
157
|
+
const bIndex = _.indexOf(b.key)(structureTabsOrder);
|
|
158
|
+
if (aIndex !== -1 && bIndex !== -1) {
|
|
159
|
+
return aIndex - bIndex;
|
|
160
|
+
}
|
|
161
|
+
if (aIndex !== -1) {
|
|
162
|
+
return -1;
|
|
163
|
+
}
|
|
164
|
+
if (bIndex !== -1) {
|
|
165
|
+
return 1;
|
|
166
|
+
}
|
|
167
|
+
return 0;
|
|
168
|
+
})
|
|
173
169
|
: items;
|
|
174
170
|
|
|
175
171
|
return (
|
|
@@ -187,27 +183,6 @@ export const StructureTabs = ({
|
|
|
187
183
|
);
|
|
188
184
|
};
|
|
189
185
|
|
|
190
|
-
StructureTabs.propTypes = {
|
|
191
|
-
structure: PropTypes.object,
|
|
192
|
-
structureTabsOrder: PropTypes.array,
|
|
193
|
-
version: PropTypes.string,
|
|
194
|
-
activeTab: PropTypes.string,
|
|
195
|
-
tabVisibility: PropTypes.object,
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const mapStateToProps = ({ structureTabsOrder, ...state }, ownProps) => {
|
|
199
|
-
const { path } = ownProps;
|
|
200
|
-
const { structureVersion: version, structure } = state;
|
|
201
|
-
const tabVisibility = getTabVisibility(state, path);
|
|
202
|
-
const activeTab = getActiveTab(tabVisibility, path, structureTabsOrder);
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
activeTab,
|
|
206
|
-
structure,
|
|
207
|
-
structureTabsOrder,
|
|
208
|
-
tabVisibility,
|
|
209
|
-
version,
|
|
210
|
-
};
|
|
211
|
-
};
|
|
186
|
+
StructureTabs.propTypes = { path: PropTypes.string, };
|
|
212
187
|
|
|
213
|
-
export default
|
|
188
|
+
export default StructureTabs;
|
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
|
+
import { waitFor } from "@testing-library/react";
|
|
3
4
|
import { StructureTabPane } from "../StructureTabPane";
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
STRUCTURE_CHILDREN,
|
|
7
|
+
STRUCTURE_FIELDS,
|
|
8
|
+
STRUCTURE_METADATA,
|
|
9
|
+
STRUCTURE_NOTES,
|
|
10
|
+
STRUCTURE_NOTES_EDIT,
|
|
11
|
+
STRUCTURE_PARENTS,
|
|
12
|
+
STRUCTURE_PROFILE,
|
|
13
|
+
STRUCTURE_STRUCTURE_LINKS,
|
|
14
|
+
STRUCTURE_MEMBERS,
|
|
15
|
+
STRUCTURE_RULES,
|
|
16
|
+
STRUCTURE_LINKS,
|
|
17
|
+
STRUCTURE_VERSIONS,
|
|
18
|
+
STRUCTURE_GRANTS,
|
|
19
|
+
STRUCTURE_EVENTS,
|
|
20
|
+
STRUCTURE_LINEAGE,
|
|
21
|
+
STRUCTURE_IMPACT,
|
|
22
|
+
} from "@truedat/core/routes";
|
|
23
|
+
import * as getTabVisibilityModule from "../../selectors/getTabVisibility";
|
|
24
|
+
import * as useCustomTabsModule from "../../hooks/useCustomTabs";
|
|
5
25
|
|
|
6
26
|
jest.mock("../StructureFields", () => () => <div>StructureFields</div>);
|
|
7
27
|
jest.mock("../StructureNotes", () => () => <div>StructureNotes</div>);
|
|
@@ -48,18 +68,21 @@ describe("<StructureTabPane />", () => {
|
|
|
48
68
|
rules: true,
|
|
49
69
|
};
|
|
50
70
|
|
|
71
|
+
const state = {
|
|
72
|
+
structureTabsOrder: [],
|
|
73
|
+
};
|
|
74
|
+
|
|
51
75
|
it("renders correctly with fields tab", async () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
76
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
77
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_FIELDS} />, { state });
|
|
55
78
|
await waitForLoad(rendered);
|
|
56
79
|
expect(rendered.container).toMatchSnapshot();
|
|
57
80
|
});
|
|
58
81
|
|
|
59
82
|
it("renders correctly with notes edit route", async () => {
|
|
60
83
|
const rendered = render(
|
|
61
|
-
<StructureTabPane
|
|
62
|
-
{ routes: [STRUCTURE_NOTES_EDIT] }
|
|
84
|
+
<StructureTabPane path={STRUCTURE_NOTES_EDIT} />,
|
|
85
|
+
{ routes: [STRUCTURE_NOTES_EDIT], state }
|
|
63
86
|
);
|
|
64
87
|
await waitForLoad(rendered);
|
|
65
88
|
expect(rendered.container).toMatchSnapshot();
|
|
@@ -67,120 +90,120 @@ describe("<StructureTabPane />", () => {
|
|
|
67
90
|
|
|
68
91
|
it("renders correctly with notes default route", async () => {
|
|
69
92
|
const rendered = render(
|
|
70
|
-
<StructureTabPane
|
|
93
|
+
<StructureTabPane path={STRUCTURE_NOTES} />, { state }
|
|
71
94
|
);
|
|
72
95
|
await waitForLoad(rendered);
|
|
73
96
|
expect(rendered.container).toMatchSnapshot();
|
|
74
97
|
});
|
|
75
98
|
|
|
76
99
|
it("renders correctly with grants tab", async () => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
100
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
101
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_GRANTS} />, { state });
|
|
80
102
|
await waitForLoad(rendered);
|
|
81
103
|
expect(rendered.container).toMatchSnapshot();
|
|
82
104
|
});
|
|
83
105
|
|
|
84
106
|
it("renders correctly with profile tab", async () => {
|
|
107
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
85
108
|
const rendered = render(
|
|
86
|
-
<StructureTabPane
|
|
109
|
+
<StructureTabPane path={STRUCTURE_PROFILE} />, { state }
|
|
87
110
|
);
|
|
88
111
|
await waitForLoad(rendered);
|
|
89
112
|
expect(rendered.container).toMatchSnapshot();
|
|
90
113
|
});
|
|
91
114
|
|
|
92
115
|
it("renders correctly with metadata tab", async () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
);
|
|
116
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
117
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_METADATA} />, { state });
|
|
96
118
|
await waitForLoad(rendered);
|
|
97
119
|
expect(rendered.container).toMatchSnapshot();
|
|
98
120
|
});
|
|
99
121
|
|
|
100
122
|
it("renders correctly with rules tab", async () => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
activeTab="rules"
|
|
104
|
-
tabVisibility={tabVisibility}
|
|
105
|
-
columns={[]}
|
|
106
|
-
/>
|
|
107
|
-
);
|
|
123
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
124
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_RULES} />, { state });
|
|
108
125
|
await waitForLoad(rendered);
|
|
109
126
|
expect(rendered.container).toMatchSnapshot();
|
|
110
127
|
});
|
|
111
128
|
|
|
112
129
|
it("renders correctly with links tab", async () => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
130
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
131
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_LINKS} />, { state });
|
|
116
132
|
await waitForLoad(rendered);
|
|
117
133
|
expect(rendered.container).toMatchSnapshot();
|
|
118
134
|
});
|
|
119
135
|
|
|
120
136
|
it("renders correctly with structure links tab", async () => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
activeTab="structureLinks"
|
|
124
|
-
tabVisibility={tabVisibility}
|
|
125
|
-
/>
|
|
137
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
138
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_STRUCTURE_LINKS} />, { state }
|
|
126
139
|
);
|
|
127
140
|
await waitForLoad(rendered);
|
|
128
141
|
expect(rendered.container).toMatchSnapshot();
|
|
129
142
|
});
|
|
130
143
|
|
|
131
144
|
it("renders correctly with parents tab", async () => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
);
|
|
145
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
146
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_PARENTS} />, { state });
|
|
135
147
|
await waitForLoad(rendered);
|
|
136
148
|
expect(rendered.container).toMatchSnapshot();
|
|
137
149
|
});
|
|
138
150
|
|
|
139
151
|
it("renders correctly with children tab", async () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
);
|
|
152
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
153
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_CHILDREN} />, { state });
|
|
143
154
|
await waitForLoad(rendered);
|
|
144
155
|
expect(rendered.container).toMatchSnapshot();
|
|
145
156
|
});
|
|
146
157
|
|
|
147
158
|
it("renders correctly with versions tab", async () => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
);
|
|
159
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
160
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_VERSIONS} />, { state });
|
|
151
161
|
await waitForLoad(rendered);
|
|
152
162
|
expect(rendered.container).toMatchSnapshot();
|
|
153
163
|
});
|
|
154
164
|
|
|
155
165
|
it("renders correctly with events tab", async () => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
);
|
|
166
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
167
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_EVENTS} />, { state });
|
|
159
168
|
await waitForLoad(rendered);
|
|
160
169
|
expect(rendered.container).toMatchSnapshot();
|
|
161
170
|
});
|
|
162
171
|
|
|
163
172
|
it("renders correctly with roles tab", async () => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
);
|
|
173
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
174
|
+
const rendered = render(<StructureTabPane path={STRUCTURE_MEMBERS} />, { state });
|
|
167
175
|
await waitForLoad(rendered);
|
|
168
176
|
expect(rendered.container).toMatchSnapshot();
|
|
169
177
|
});
|
|
170
178
|
|
|
171
179
|
it("renders correctly with lineage tab", async () => {
|
|
180
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
172
181
|
const rendered = render(
|
|
173
|
-
<StructureTabPane
|
|
182
|
+
<StructureTabPane path={STRUCTURE_LINEAGE} />, { state }
|
|
174
183
|
);
|
|
175
184
|
await waitForLoad(rendered);
|
|
176
185
|
expect(rendered.container).toMatchSnapshot();
|
|
177
186
|
});
|
|
178
187
|
|
|
179
188
|
it("renders correctly with impact tab", async () => {
|
|
189
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
190
|
+
const rendered = render(
|
|
191
|
+
<StructureTabPane path={STRUCTURE_IMPACT} />, { state }
|
|
192
|
+
);
|
|
193
|
+
await waitForLoad(rendered);
|
|
194
|
+
expect(rendered.container).toMatchSnapshot();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("renders correctly with custom tab", async () => {
|
|
198
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
199
|
+
jest.spyOn(useCustomTabsModule, "useStructureCustomTabs").mockReturnValue([{ name: "custom", route: "/structures/:id/custom", content: <p>Custom</p> },]);
|
|
180
200
|
const rendered = render(
|
|
181
|
-
<StructureTabPane
|
|
201
|
+
<StructureTabPane path={"/structures/:id/custom"} />, { state }
|
|
182
202
|
);
|
|
183
203
|
await waitForLoad(rendered);
|
|
204
|
+
await waitFor(() => {
|
|
205
|
+
expect(rendered.getByText("Custom")).toBeInTheDocument();
|
|
206
|
+
});
|
|
184
207
|
expect(rendered.container).toMatchSnapshot();
|
|
185
208
|
});
|
|
186
209
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import { render, waitForLoad } from "@truedat/test/render";
|
|
3
3
|
import { StructureTabs } from "../StructureTabs";
|
|
4
|
+
import * as getTabVisibilityModule from "../../selectors/getTabVisibility";
|
|
4
5
|
|
|
5
6
|
describe("<StructureTabs />", () => {
|
|
6
7
|
const tabs = [
|
|
@@ -27,8 +28,10 @@ describe("<StructureTabs />", () => {
|
|
|
27
28
|
const activeTab = "metadata";
|
|
28
29
|
|
|
29
30
|
it("matches the latest snapshot: " + activeTab, async () => {
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
jest.spyOn(getTabVisibilityModule, "getTabVisibility").mockReturnValue(tabVisibility);
|
|
32
|
+
|
|
33
|
+
const props = { path: "/structures/:id/metadata" };
|
|
34
|
+
const rendered = render(<StructureTabs {...props} />, { state: { structure, structureVersion: version, structureTabsOrder: [] } });
|
|
32
35
|
await waitForLoad(rendered);
|
|
33
36
|
expect(rendered.container).toMatchSnapshot();
|
|
34
37
|
});
|
|
@@ -8,6 +8,14 @@ exports[`<StructureTabPane /> renders correctly with children tab 1`] = `
|
|
|
8
8
|
</div>
|
|
9
9
|
`;
|
|
10
10
|
|
|
11
|
+
exports[`<StructureTabPane /> renders correctly with custom tab 1`] = `
|
|
12
|
+
<div>
|
|
13
|
+
<p>
|
|
14
|
+
Custom
|
|
15
|
+
</p>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
|
|
11
19
|
exports[`<StructureTabPane /> renders correctly with events tab 1`] = `
|
|
12
20
|
<div>
|
|
13
21
|
<div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { useWebContext } from "@truedat/core/webContext";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
export function useStructureCustomTabs() {
|
|
6
|
+
const { structureTabs } = useWebContext();
|
|
7
|
+
|
|
8
|
+
return useMemo(() => {
|
|
9
|
+
if (!structureTabs?.customTabs) return [];
|
|
10
|
+
return _.map((tab) => ({ ...tab, route: `/structures/:id/${tab.name}` }))(
|
|
11
|
+
structureTabs.customTabs
|
|
12
|
+
);
|
|
13
|
+
}, [structureTabs]);
|
|
14
|
+
}
|
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
STRUCTURE_VERSION_VERSIONS,
|
|
18
18
|
STRUCTURE_GRANTS,
|
|
19
19
|
} from "@truedat/core/routes";
|
|
20
|
+
const customPath = "/structures/:id/custom";
|
|
21
|
+
|
|
20
22
|
import { defaultTab, getActiveTab } from "../getActiveTab";
|
|
21
23
|
|
|
22
24
|
describe("selectors: defaultTab", () => {
|
|
@@ -79,25 +81,26 @@ describe("selectors: getActiveTab", () => {
|
|
|
79
81
|
const tabVisibility = { fields: true };
|
|
80
82
|
|
|
81
83
|
it("should determine value according to path and tab visibility", () => {
|
|
82
|
-
expect(getActiveTab(tabVisibility, STRUCTURE)).toBe("fields");
|
|
83
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_VERSION)).toBe("fields");
|
|
84
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_CHILDREN)).toBe("children");
|
|
85
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_NOTES)).toBe("notes");
|
|
86
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_NOTES_EDIT)).toBe("notes");
|
|
87
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_PARENTS)).toBe("parents");
|
|
88
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_PROFILE)).toBe("profile");
|
|
89
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_RULES)).toBe("rules");
|
|
90
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_MEMBERS)).toBe("roles");
|
|
91
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_LINKS)).toBe("links");
|
|
92
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_LINKS_NEW)).toBe("links");
|
|
93
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_VERSIONS)).toBe("versions");
|
|
94
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_VERSION_VERSIONS)).toBe(
|
|
84
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE })).toBe("fields");
|
|
85
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_VERSION })).toBe("fields");
|
|
86
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_CHILDREN })).toBe("children");
|
|
87
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_NOTES })).toBe("notes");
|
|
88
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_NOTES_EDIT })).toBe("notes");
|
|
89
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_PARENTS })).toBe("parents");
|
|
90
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_PROFILE })).toBe("profile");
|
|
91
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_RULES })).toBe("rules");
|
|
92
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_MEMBERS })).toBe("roles");
|
|
93
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_LINKS })).toBe("links");
|
|
94
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_LINKS_NEW })).toBe("links");
|
|
95
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_VERSIONS })).toBe("versions");
|
|
96
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_VERSION_VERSIONS })).toBe(
|
|
95
97
|
"versions"
|
|
96
98
|
);
|
|
97
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_EVENTS)).toBe("events");
|
|
98
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_LINEAGE)).toBe("lineage");
|
|
99
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_IMPACT)).toBe("impact");
|
|
100
|
-
expect(getActiveTab(tabVisibility, STRUCTURE_GRANTS)).toBe("grants");
|
|
101
|
-
expect(getActiveTab(tabVisibility, "foo")).toBe(undefined);
|
|
99
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_EVENTS })).toBe("events");
|
|
100
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_LINEAGE })).toBe("lineage");
|
|
101
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_IMPACT })).toBe("impact");
|
|
102
|
+
expect(getActiveTab({ tabVisibility, path: STRUCTURE_GRANTS })).toBe("grants");
|
|
103
|
+
expect(getActiveTab({ tabVisibility, path: "foo" })).toBe(undefined);
|
|
104
|
+
expect(getActiveTab({ tabVisibility, path: customPath, customTabs: [{ name: "custom", route: customPath }] })).toBe("custom");
|
|
102
105
|
});
|
|
103
106
|
});
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
STRUCTURE_IMPACT,
|
|
24
24
|
} from "@truedat/core/routes";
|
|
25
25
|
|
|
26
|
-
export const defaultTab = (tabVisibility, tabsOrder = []) => {
|
|
26
|
+
export const defaultTab = (tabVisibility, tabsOrder = [], customTabs = []) => {
|
|
27
27
|
const defaultOrder = [
|
|
28
28
|
"fields",
|
|
29
29
|
"children",
|
|
@@ -36,15 +36,18 @@ export const defaultTab = (tabVisibility, tabsOrder = []) => {
|
|
|
36
36
|
"roles",
|
|
37
37
|
"links",
|
|
38
38
|
"versions",
|
|
39
|
+
..._.map((tab) => tab.name)(customTabs),
|
|
39
40
|
];
|
|
40
41
|
|
|
41
42
|
return _.find((tab) => tabVisibility[tab])([...tabsOrder, ...defaultOrder]);
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
const getCustomTabs = (customTabs) => _.map((tab) => [_.eq(tab.route), _.constant(tab.name)])(customTabs)
|
|
46
|
+
|
|
47
|
+
export const getActiveTab = ({ tabVisibility, path, tabsOrder, customTabs }) => {
|
|
45
48
|
return _.cond([
|
|
46
|
-
[_.eq(STRUCTURE), _.constant(defaultTab(tabVisibility, tabsOrder))],
|
|
47
|
-
[_.eq(STRUCTURE_VERSION), _.constant(defaultTab(tabVisibility, tabsOrder))],
|
|
49
|
+
[_.eq(STRUCTURE), _.constant(defaultTab(tabVisibility, tabsOrder, customTabs))],
|
|
50
|
+
[_.eq(STRUCTURE_VERSION), _.constant(defaultTab(tabVisibility, tabsOrder, customTabs))],
|
|
48
51
|
[_.eq(STRUCTURE_VERSION_FIELDS), _.constant("fields")],
|
|
49
52
|
[_.eq(STRUCTURE_FIELDS), _.constant("fields")],
|
|
50
53
|
[_.eq(STRUCTURE_CHILDREN), _.constant("children")],
|
|
@@ -64,5 +67,6 @@ export const getActiveTab = (tabVisibility, path, tabsOrder) => {
|
|
|
64
67
|
[_.eq(STRUCTURE_EVENTS), _.constant("events")],
|
|
65
68
|
[_.eq(STRUCTURE_LINEAGE), _.constant("lineage")],
|
|
66
69
|
[_.eq(STRUCTURE_IMPACT), _.constant("impact")],
|
|
70
|
+
...getCustomTabs(customTabs),
|
|
67
71
|
])(path);
|
|
68
72
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
+
import { createSelector } from "reselect";
|
|
2
3
|
import { getStructureToConceptLinks } from "./getStructureLinks";
|
|
3
4
|
import { metadataViewsSelector } from "./metadataViewsSelector";
|
|
4
5
|
|
|
@@ -58,7 +59,7 @@ const eventsTabVisible = _.flow(
|
|
|
58
59
|
);
|
|
59
60
|
const grantsTabVisible = _.flow(_.path("structure.grants"), notEmpty);
|
|
60
61
|
|
|
61
|
-
export const getTabVisibility = (state) => ({
|
|
62
|
+
export const getTabVisibility = createSelector([state => state], (state) => ({
|
|
62
63
|
fields: fieldsTabVisible(state),
|
|
63
64
|
profile: profileTabVisible(state),
|
|
64
65
|
links: linksTabVisible(state),
|
|
@@ -74,4 +75,4 @@ export const getTabVisibility = (state) => ({
|
|
|
74
75
|
children: childrenTabVisible(state),
|
|
75
76
|
grants: grantsTabVisible(state),
|
|
76
77
|
roles: rolesTabVisible(state),
|
|
77
|
-
});
|
|
78
|
+
}));
|