@eeacms/volto-marine-policy 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -1
- package/jest-addon.config.js +4 -4
- package/package.json +9 -8
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesExplorerEdit.js +5 -0
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesExplorerView.js +115 -0
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesFilters.jsx +406 -0
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesFilters.test.jsxZ +91 -0
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesListing.jsx +383 -0
- package/src/components/Blocks/DemoSitesExplorer/DemoSitesMap.jsx +230 -0
- package/src/components/Blocks/DemoSitesExplorer/FeatureDisplay.jsx +97 -0
- package/src/components/Blocks/DemoSitesExplorer/FeatureDisplay.test.jsxZ +48 -0
- package/src/components/Blocks/DemoSitesExplorer/FeatureInteraction.jsx +95 -0
- package/src/components/Blocks/DemoSitesExplorer/InfoOverlay.jsx +79 -0
- package/src/components/Blocks/DemoSitesExplorer/hooks.js +20 -0
- package/src/components/Blocks/DemoSitesExplorer/images/icon-depth.png +0 -0
- package/src/components/Blocks/DemoSitesExplorer/images/icon-light.png +0 -0
- package/src/components/Blocks/DemoSitesExplorer/images/search.svg +3 -0
- package/src/components/Blocks/DemoSitesExplorer/index.js +16 -0
- package/src/components/Blocks/DemoSitesExplorer/mockJsdom.js +8 -0
- package/src/components/Blocks/DemoSitesExplorer/styles.less +376 -0
- package/src/components/Blocks/DemoSitesExplorer/utils.js +193 -0
- package/src/components/Blocks/DemoSitesExplorer/utils.test.jsZ +63 -0
- package/src/components/index.js +1 -0
- package/src/components/theme/DatabaseItemView/DatabaseItemView.jsx +0 -1
- package/src/express-middleware.js +37 -0
- package/src/index.js +13 -12
- package/theme/extras/print.less +64 -0
- package/theme/globals/site.overrides +11 -6
- package/theme/globals/site.variables +1 -0
- package/src/components/Blocks/ContextNavigation/Accordion.jsx +0 -85
- package/src/components/Blocks/ContextNavigation/Accordion.test.jsx +0 -106
- package/src/components/Blocks/ContextNavigation/AccordionContent.jsx +0 -66
- package/src/components/Blocks/ContextNavigation/ContextNavigation.jsx +0 -41
- package/src/components/Blocks/ContextNavigation/Edit.jsx +0 -41
- package/src/components/Blocks/ContextNavigation/Edit.test.jsx +0 -71
- package/src/components/Blocks/ContextNavigation/View.jsx +0 -42
- package/src/components/Blocks/ContextNavigation/View.test.jsx +0 -71
- package/src/components/Blocks/ContextNavigation/index.js +0 -25
- package/src/components/Blocks/ContextNavigation/schema.js +0 -43
- package/src/components/Blocks/ContextNavigation/styles.less +0 -65
package/src/index.js
CHANGED
|
@@ -14,7 +14,6 @@ import installMsfdDataExplorerBlock from './components/Blocks/MsfdDataExplorerBl
|
|
|
14
14
|
import { breadcrumb, localnavigation } from './reducers';
|
|
15
15
|
import customBlockTemplates from '@eeacms/volto-marine-policy/components/Blocks/CustomBlockTemplates/customBlockTemplates';
|
|
16
16
|
import TextAlignWidget from './components/Widgets/TextAlign';
|
|
17
|
-
import installContextNavigation from './components/Blocks/ContextNavigation';
|
|
18
17
|
import './slate-styles.less';
|
|
19
18
|
|
|
20
19
|
import installSearchEngine from './search';
|
|
@@ -29,7 +28,7 @@ import { linkDeserializer } from '@plone/volto-slate/editor/plugins/AdvancedLink
|
|
|
29
28
|
import LinkEditSchema from '@plone/volto-slate/editor/plugins/AdvancedLink/schema';
|
|
30
29
|
import { getBlocks } from '@plone/volto/helpers';
|
|
31
30
|
import { defineMessages } from 'react-intl'; // , defineMessages
|
|
32
|
-
|
|
31
|
+
import installDemoSitesExplorer from './components/Blocks/DemoSitesExplorer';
|
|
33
32
|
import marineLogo from '@eeacms/volto-marine-policy/../theme/assets/images/Header/wise-marine-logo.svg';
|
|
34
33
|
import marineLogoWhite from '@eeacms/volto-marine-policy/../theme/assets/images/Header/wise-marine-logo-white.svg';
|
|
35
34
|
import eeaWhiteLogo from '@eeacms/volto-eea-design-system/../theme/themes/eea/assets/logo/eea-logo-white.svg';
|
|
@@ -110,6 +109,11 @@ const applyConfig = (config) => {
|
|
|
110
109
|
localnavigation,
|
|
111
110
|
};
|
|
112
111
|
|
|
112
|
+
if (__SERVER__) {
|
|
113
|
+
const installExpressMiddleware = require('./express-middleware').default;
|
|
114
|
+
config = installExpressMiddleware(config);
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
config.widgets.widget.text_align = TextAlignWidget;
|
|
114
118
|
// check if it breaks the 'theme' field in volto-tabs-block in the 'horizontal carousel' layout
|
|
115
119
|
// We have a 'theme' field in the wise catalogue metadata (CatalogueMetadata)
|
|
@@ -127,12 +131,12 @@ const applyConfig = (config) => {
|
|
|
127
131
|
};
|
|
128
132
|
|
|
129
133
|
// on home contextNavigation should return false
|
|
130
|
-
config.blocks.blocksConfig.contextNavigation = {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
134
|
+
// config.blocks.blocksConfig.contextNavigation = {
|
|
135
|
+
// ...config.blocks.blocksConfig.contextNavigation,
|
|
136
|
+
// blockHasValue: (data) => {
|
|
137
|
+
// return data.pathname !== '/';
|
|
138
|
+
// },
|
|
139
|
+
// };
|
|
136
140
|
config.blocks.blocksConfig.listing = {
|
|
137
141
|
...config.blocks.blocksConfig.listing,
|
|
138
142
|
variations: [
|
|
@@ -269,9 +273,6 @@ const applyConfig = (config) => {
|
|
|
269
273
|
|
|
270
274
|
config.settings.openExternalLinkInNewTab = true;
|
|
271
275
|
|
|
272
|
-
if (config.blocks.blocksConfig.contextNavigation)
|
|
273
|
-
config.blocks.blocksConfig.contextNavigation.restricted = false;
|
|
274
|
-
|
|
275
276
|
config.settings.pluggableStyles = [
|
|
276
277
|
...(config.settings.pluggableStyles || []),
|
|
277
278
|
{
|
|
@@ -519,7 +520,7 @@ const applyConfig = (config) => {
|
|
|
519
520
|
const final = [
|
|
520
521
|
installMsfdDataExplorerBlock,
|
|
521
522
|
installSearchEngine,
|
|
522
|
-
|
|
523
|
+
installDemoSitesExplorer,
|
|
523
524
|
].reduce((acc, apply) => apply(acc), config);
|
|
524
525
|
|
|
525
526
|
return final;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@media print {
|
|
2
|
+
a {
|
|
3
|
+
word-break: break-word;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.logo {
|
|
7
|
+
margin-left: 0 !important;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.block.call-to-action,
|
|
11
|
+
.block.context-navigation {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.content-box-inner {
|
|
16
|
+
padding: 25px !important;
|
|
17
|
+
|
|
18
|
+
.column-blocks-wrapper {
|
|
19
|
+
margin-bottom: 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[class~='container'] > [class*='styled-'] {
|
|
24
|
+
margin-top: 0.5rem;
|
|
25
|
+
margin-bottom: 0.5rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.ui.section.divider {
|
|
29
|
+
margin-top: 0.5rem;
|
|
30
|
+
margin-bottom: 0.5rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.ui.grid > .row > [class*='twelve wide'].column,
|
|
34
|
+
.ui.grid > .column.row > [class*='twelve wide'].column,
|
|
35
|
+
.ui.grid > [class*='twelve wide'].column,
|
|
36
|
+
.ui.column.grid > [class*='twelve wide'].column {
|
|
37
|
+
padding: 0 25px !important;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.visualization,
|
|
41
|
+
.content-box-inner,
|
|
42
|
+
.embed-map,
|
|
43
|
+
.embed-tableau,
|
|
44
|
+
.embed-map-visualization,
|
|
45
|
+
.embed-visualization {
|
|
46
|
+
break-inside: avoid;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@media print and (min-width: 600px) {
|
|
51
|
+
.columns-view {
|
|
52
|
+
.ui.grid > .row > [class*='four wide computer'].column,
|
|
53
|
+
.ui.grid > .column.row > [class*='four wide computer'].column,
|
|
54
|
+
.ui.grid > [class*='four wide computer'].column,
|
|
55
|
+
.ui.column.grid > [class*='four wide computer'].column {
|
|
56
|
+
width: @fourWide !important;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@page {
|
|
62
|
+
margin-top: 15mm;
|
|
63
|
+
margin-bottom: 15mm;
|
|
64
|
+
}
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
Global Overrides
|
|
3
3
|
*******************************/
|
|
4
4
|
|
|
5
|
+
@import '../extras/print';
|
|
6
|
+
|
|
5
7
|
.documentFirstHeading {
|
|
6
8
|
border-bottom: none !important;
|
|
7
|
-
|
|
9
|
+
|
|
8
10
|
&::before {
|
|
9
11
|
border-bottom: none !important;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
|
|
14
15
|
#page-document > blockquote {
|
|
15
16
|
margin-right: revert !important;
|
|
16
17
|
margin-left: revert !important;
|
|
@@ -200,7 +201,9 @@ body.view-viewview .full {
|
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
body.view-viewview.has-toolbar-collapsed:not(.has-sidebar):not(
|
|
204
|
+
body.view-viewview.has-toolbar-collapsed:not(.has-sidebar):not(
|
|
205
|
+
.has-sidebar-collapsed
|
|
206
|
+
) {
|
|
204
207
|
.full > div {
|
|
205
208
|
width: calc(100% - @collapsedToolbarWidth) !important;
|
|
206
209
|
}
|
|
@@ -233,7 +236,9 @@ body.view-viewview .full {
|
|
|
233
236
|
|
|
234
237
|
@media screen and (max-width: @largestMobileScreen) {
|
|
235
238
|
body.view-viewview.has-toolbar:not(.has-sidebar):not(.has-sidebar-collapsed),
|
|
236
|
-
body.view-viewview.has-toolbar-collapsed:not(.has-sidebar):not(
|
|
239
|
+
body.view-viewview.has-toolbar-collapsed:not(.has-sidebar):not(
|
|
240
|
+
.has-sidebar-collapsed
|
|
241
|
+
) {
|
|
237
242
|
.full > div {
|
|
238
243
|
width: 100% !important;
|
|
239
244
|
}
|
|
@@ -373,8 +378,8 @@ body.custom-page-header .breadcrumbs {
|
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
@media only screen and (max-height: @tabletBreakpoint) {
|
|
376
|
-
#toolbar .toolbar-content.show {
|
|
381
|
+
#toolbar .toolbar-content.show {
|
|
377
382
|
max-height: 700px !important;
|
|
378
383
|
z-index: 5;
|
|
384
|
+
}
|
|
379
385
|
}
|
|
380
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Accordion as SemanticAccordion, Icon } from 'semantic-ui-react';
|
|
3
|
-
import AccordionContent from './AccordionContent';
|
|
4
|
-
import { useHistory } from 'react-router-dom';
|
|
5
|
-
|
|
6
|
-
const Accordion = (props) => {
|
|
7
|
-
const { items = {}, curent_location, activeMenu, data = {} } = props;
|
|
8
|
-
const [currentIndex, setIndex] = React.useState(activeMenu ?? 0);
|
|
9
|
-
const [showChildren, setShowChildren] = React.useState(false);
|
|
10
|
-
const history = useHistory();
|
|
11
|
-
|
|
12
|
-
const handleClick = (e, item) => {
|
|
13
|
-
let itemUrl = '/' + item['@id'].split('/').slice(3).join('/');
|
|
14
|
-
history.push(itemUrl);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const handleIconClick = (e, index) => {
|
|
18
|
-
e.stopPropagation();
|
|
19
|
-
const newIndex = currentIndex === index ? -1 : index;
|
|
20
|
-
setIndex(newIndex);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<>
|
|
25
|
-
<div className="context-navigation-header">{data?.title}</div>
|
|
26
|
-
{items.map((item, index) => {
|
|
27
|
-
const { id } = item;
|
|
28
|
-
const active = currentIndex === index;
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<SemanticAccordion id={id} key={index} className="secondary">
|
|
32
|
-
<SemanticAccordion.Title
|
|
33
|
-
role="button"
|
|
34
|
-
tabIndex={0}
|
|
35
|
-
active={activeMenu === index}
|
|
36
|
-
aria-expanded={activeMenu === index}
|
|
37
|
-
index={index}
|
|
38
|
-
onClick={(e) => {
|
|
39
|
-
handleClick(e, item);
|
|
40
|
-
}}
|
|
41
|
-
onKeyDown={(e) => {
|
|
42
|
-
if (e.keyCode === 13 || e.keyCode === 32) {
|
|
43
|
-
e.preventDefault();
|
|
44
|
-
handleClick(e, item);
|
|
45
|
-
}
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
48
|
-
<span className="item-title">{item.title}</span>
|
|
49
|
-
{active && showChildren ? (
|
|
50
|
-
<Icon
|
|
51
|
-
className="ri-arrow-up-s-line"
|
|
52
|
-
onClick={(e) => {
|
|
53
|
-
handleIconClick(e, index);
|
|
54
|
-
}}
|
|
55
|
-
/>
|
|
56
|
-
) : showChildren ? (
|
|
57
|
-
<Icon
|
|
58
|
-
className="ri-arrow-down-s-line"
|
|
59
|
-
onClick={(e) => {
|
|
60
|
-
handleIconClick(e, index);
|
|
61
|
-
}}
|
|
62
|
-
/>
|
|
63
|
-
) : null}
|
|
64
|
-
</SemanticAccordion.Title>
|
|
65
|
-
<SemanticAccordion.Content active={active && showChildren}>
|
|
66
|
-
<AccordionContent
|
|
67
|
-
curent_location={curent_location}
|
|
68
|
-
key={index}
|
|
69
|
-
main={{
|
|
70
|
-
title: item.title,
|
|
71
|
-
href: item['@id'],
|
|
72
|
-
url: item.url,
|
|
73
|
-
}}
|
|
74
|
-
data={data}
|
|
75
|
-
setShowChildren={setShowChildren}
|
|
76
|
-
/>
|
|
77
|
-
</SemanticAccordion.Content>
|
|
78
|
-
</SemanticAccordion>
|
|
79
|
-
);
|
|
80
|
-
})}
|
|
81
|
-
</>
|
|
82
|
-
);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export default Accordion;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { MemoryRouter } from 'react-router-dom';
|
|
3
|
-
import configureStore from 'redux-mock-store';
|
|
4
|
-
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
|
|
5
|
-
import '@testing-library/jest-dom/extend-expect';
|
|
6
|
-
import { Provider } from 'react-intl-redux';
|
|
7
|
-
import Accordion from './Accordion';
|
|
8
|
-
|
|
9
|
-
const mockStore = configureStore();
|
|
10
|
-
|
|
11
|
-
describe('RASTAccordion', () => {
|
|
12
|
-
let store;
|
|
13
|
-
let data;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
store = mockStore({
|
|
17
|
-
userSession: { token: '1234' },
|
|
18
|
-
intl: {
|
|
19
|
-
locale: 'en',
|
|
20
|
-
messages: {},
|
|
21
|
-
},
|
|
22
|
-
content: {
|
|
23
|
-
subrequests: {},
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
data = {
|
|
28
|
-
items: [
|
|
29
|
-
{
|
|
30
|
-
id: 'item1',
|
|
31
|
-
title: 'Item 1',
|
|
32
|
-
'@id': '/item1',
|
|
33
|
-
'@type': 'Folder',
|
|
34
|
-
href: '/item1-href',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: 'item2',
|
|
38
|
-
title: 'Item 2',
|
|
39
|
-
'@id': '/item2',
|
|
40
|
-
'@type': 'Folder',
|
|
41
|
-
href: '/item2-href',
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
activeMenu: 1,
|
|
45
|
-
curent_location: '/item1-href',
|
|
46
|
-
data: { title: "Accordion's Title" },
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('renders the component with initial data', () => {
|
|
51
|
-
const { getByText } = render(
|
|
52
|
-
<Provider store={store}>
|
|
53
|
-
<MemoryRouter>
|
|
54
|
-
<Accordion {...data} />
|
|
55
|
-
</MemoryRouter>
|
|
56
|
-
</Provider>,
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
expect(getByText('Item 1')).toBeInTheDocument();
|
|
60
|
-
expect(getByText('Item 2')).toBeInTheDocument();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('navigates to correct path on item click', () => {
|
|
64
|
-
const { getByText, history } = render(
|
|
65
|
-
<Provider store={store}>
|
|
66
|
-
<MemoryRouter>
|
|
67
|
-
<Accordion {...data} />
|
|
68
|
-
</MemoryRouter>
|
|
69
|
-
</Provider>,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
fireEvent.click(getByText('Item 1'));
|
|
73
|
-
waitFor(() => expect(history.location.pathname).toBe('/item1'));
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('clicks on accordion items', () => {
|
|
77
|
-
const { container } = render(
|
|
78
|
-
<Provider store={store}>
|
|
79
|
-
<MemoryRouter>
|
|
80
|
-
<Accordion {...data} />
|
|
81
|
-
</MemoryRouter>
|
|
82
|
-
</Provider>,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
screen.debug();
|
|
86
|
-
|
|
87
|
-
// check that item1 is expanded by default
|
|
88
|
-
expect(container.querySelector('#item2 .active.title')).toBeInTheDocument();
|
|
89
|
-
|
|
90
|
-
const item1 = container.querySelector('#item1');
|
|
91
|
-
fireEvent.click(item1);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('responds to keyboard events', () => {
|
|
95
|
-
const { getByText } = render(
|
|
96
|
-
<Provider store={store}>
|
|
97
|
-
<MemoryRouter>
|
|
98
|
-
<Accordion {...data} />
|
|
99
|
-
</MemoryRouter>
|
|
100
|
-
</Provider>,
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
fireEvent.keyDown(getByText('Item 1'), { keyCode: 13 }); // Enter key
|
|
104
|
-
waitFor(() => expect(getByText('Content of Item 1')).toBeVisible());
|
|
105
|
-
});
|
|
106
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { List } from 'semantic-ui-react';
|
|
3
|
-
import { Link } from 'react-router-dom';
|
|
4
|
-
import { compose } from 'redux';
|
|
5
|
-
import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
|
|
6
|
-
import { useChildren } from './View';
|
|
7
|
-
|
|
8
|
-
const AccordionContent = (props) => {
|
|
9
|
-
const {
|
|
10
|
-
main,
|
|
11
|
-
curent_location,
|
|
12
|
-
data: { types = [] },
|
|
13
|
-
setShowChildren,
|
|
14
|
-
} = props;
|
|
15
|
-
const location = main.url;
|
|
16
|
-
|
|
17
|
-
// React.useEffect(() => {
|
|
18
|
-
// const action = getContent(location, null, location);
|
|
19
|
-
// dispatch(action);
|
|
20
|
-
// }, [location, dispatch]);
|
|
21
|
-
|
|
22
|
-
// items = useSelector(
|
|
23
|
-
// (state) => state.content?.subrequests?.[location]?.data?.items || [],
|
|
24
|
-
// );
|
|
25
|
-
const items = useChildren(location);
|
|
26
|
-
|
|
27
|
-
React.useEffect(() => {
|
|
28
|
-
const filteredItems = items.filter((item) =>
|
|
29
|
-
types.length ? types.includes(item['@type']) : item,
|
|
30
|
-
);
|
|
31
|
-
if (filteredItems.length) setShowChildren(true);
|
|
32
|
-
}, [items, setShowChildren, types]);
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="dataset-content">
|
|
36
|
-
<div>
|
|
37
|
-
{items.length
|
|
38
|
-
? items
|
|
39
|
-
.filter((item) =>
|
|
40
|
-
types.length ? types.includes(item['@type']) : item,
|
|
41
|
-
)
|
|
42
|
-
.map((item) => (
|
|
43
|
-
<List.Item
|
|
44
|
-
key={item.id}
|
|
45
|
-
className={`${
|
|
46
|
-
item['@id'].endsWith(curent_location.pathname)
|
|
47
|
-
? 'active'
|
|
48
|
-
: ''
|
|
49
|
-
}`}
|
|
50
|
-
>
|
|
51
|
-
<List.Content>
|
|
52
|
-
<div className="dataset-item">
|
|
53
|
-
<Link to={flattenToAppURL(getBaseUrl(item['@id']))}>
|
|
54
|
-
{item.title}
|
|
55
|
-
</Link>
|
|
56
|
-
</div>
|
|
57
|
-
</List.Content>
|
|
58
|
-
</List.Item>
|
|
59
|
-
))
|
|
60
|
-
: null}
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export default compose()(AccordionContent);
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { compose } from 'redux';
|
|
3
|
-
|
|
4
|
-
import Accordion from './Accordion';
|
|
5
|
-
import { useLocation } from 'react-router-dom';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A navigation slot implementation, similar to the classic Plone navigation
|
|
9
|
-
* portlet. It uses the same API, so the options are similar to
|
|
10
|
-
* INavigationPortlet
|
|
11
|
-
*/
|
|
12
|
-
export function ContextNavigationComponent(props) {
|
|
13
|
-
const { items, data } = props;
|
|
14
|
-
let activeMenu = null;
|
|
15
|
-
|
|
16
|
-
const curent_location = useLocation();
|
|
17
|
-
for (let i = 0; i < items.length; i++) {
|
|
18
|
-
let itemUrl = '/' + items[i]['@id'].split('/').slice(3).join('/');
|
|
19
|
-
items[i].is_active = false;
|
|
20
|
-
if (curent_location.pathname.includes(itemUrl)) {
|
|
21
|
-
activeMenu = i;
|
|
22
|
-
items[i].is_active = true;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<>
|
|
28
|
-
{items.length ? (
|
|
29
|
-
<Accordion
|
|
30
|
-
items={items}
|
|
31
|
-
curent_location={curent_location}
|
|
32
|
-
activeMenu={activeMenu}
|
|
33
|
-
data={data}
|
|
34
|
-
/>
|
|
35
|
-
) : null}
|
|
36
|
-
</>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// withContentNavigation
|
|
41
|
-
export default compose()(ContextNavigationComponent);
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useSelector } from 'react-redux';
|
|
3
|
-
import { SidebarPortal } from '@plone/volto/components';
|
|
4
|
-
import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
|
|
5
|
-
|
|
6
|
-
import View from './View';
|
|
7
|
-
import schema from './schema';
|
|
8
|
-
|
|
9
|
-
export default function Edit(props) {
|
|
10
|
-
const {
|
|
11
|
-
block,
|
|
12
|
-
data = {},
|
|
13
|
-
onChangeBlock,
|
|
14
|
-
selected,
|
|
15
|
-
id,
|
|
16
|
-
formData = {},
|
|
17
|
-
} = props;
|
|
18
|
-
const contentTypes = useSelector((state) => state?.types.types);
|
|
19
|
-
const blockSchema = schema({ formData, data, contentTypes });
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div>
|
|
23
|
-
<View data={data} id={id} mode="edit" />
|
|
24
|
-
<SidebarPortal selected={selected}>
|
|
25
|
-
<BlockDataForm
|
|
26
|
-
block={block}
|
|
27
|
-
title={blockSchema.title}
|
|
28
|
-
schema={blockSchema}
|
|
29
|
-
onChangeField={(id, value) => {
|
|
30
|
-
onChangeBlock(block, {
|
|
31
|
-
...data,
|
|
32
|
-
[id]: value,
|
|
33
|
-
});
|
|
34
|
-
}}
|
|
35
|
-
onChangeBlock={onChangeBlock}
|
|
36
|
-
formData={data}
|
|
37
|
-
/>
|
|
38
|
-
</SidebarPortal>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import { Provider } from 'react-intl-redux';
|
|
4
|
-
import configureStore from 'redux-mock-store';
|
|
5
|
-
import ContextNavigationEdit from './Edit';
|
|
6
|
-
import { Router } from 'react-router-dom';
|
|
7
|
-
import { createMemoryHistory } from 'history';
|
|
8
|
-
import '@testing-library/jest-dom/extend-expect';
|
|
9
|
-
|
|
10
|
-
const mockStore = configureStore();
|
|
11
|
-
|
|
12
|
-
jest.mock('@plone/volto/components', () => ({
|
|
13
|
-
SidebarPortal: ({ children }) => (
|
|
14
|
-
<div>
|
|
15
|
-
<div>SidebarPortal</div>
|
|
16
|
-
{children}
|
|
17
|
-
</div>
|
|
18
|
-
),
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
|
-
jest.mock('@plone/volto/components/manage/Form/BlockDataForm', () => {
|
|
22
|
-
return {
|
|
23
|
-
__esModule: true,
|
|
24
|
-
default: ({ params }) => {
|
|
25
|
-
return <div>BlockDataForm {params}</div>;
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const store = mockStore({
|
|
31
|
-
userSession: { token: '1234' },
|
|
32
|
-
intl: {
|
|
33
|
-
locale: 'en',
|
|
34
|
-
messages: {},
|
|
35
|
-
},
|
|
36
|
-
content: {
|
|
37
|
-
subrequests: {},
|
|
38
|
-
},
|
|
39
|
-
types: {
|
|
40
|
-
types: [],
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('ContextNavigationEdit', () => {
|
|
45
|
-
it('renders corectly', () => {
|
|
46
|
-
const history = createMemoryHistory();
|
|
47
|
-
const { getByText } = render(
|
|
48
|
-
<Provider store={store}>
|
|
49
|
-
<Router history={history}>
|
|
50
|
-
<ContextNavigationEdit />
|
|
51
|
-
</Router>
|
|
52
|
-
</Provider>,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
expect(getByText('SidebarPortal')).toBeInTheDocument();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('renders corectly', () => {
|
|
59
|
-
const history = createMemoryHistory();
|
|
60
|
-
const { getByText } = render(
|
|
61
|
-
<Provider store={store}>
|
|
62
|
-
<Router history={history}>
|
|
63
|
-
<ContextNavigationEdit selected={true} onChangeBlock={() => {}} />
|
|
64
|
-
</Router>
|
|
65
|
-
</Provider>,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
// expect(getByText('InlineForm')).toBeInTheDocument();
|
|
69
|
-
expect(getByText('SidebarPortal')).toBeInTheDocument();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import './styles.less';
|
|
3
|
-
import ContextNavigation from './ContextNavigation';
|
|
4
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
5
|
-
import { getContent } from '@plone/volto/actions';
|
|
6
|
-
|
|
7
|
-
export function useChildren(location) {
|
|
8
|
-
const dispatch = useDispatch();
|
|
9
|
-
React.useEffect(() => {
|
|
10
|
-
const action = getContent(location, null, location);
|
|
11
|
-
dispatch(action);
|
|
12
|
-
}, [location, dispatch]);
|
|
13
|
-
|
|
14
|
-
const items = useSelector(
|
|
15
|
-
(state) => state.content.subrequests?.[location]?.data?.items || [],
|
|
16
|
-
);
|
|
17
|
-
return items;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default function View(props) {
|
|
21
|
-
const { data } = props;
|
|
22
|
-
let root_path = data?.root_path;
|
|
23
|
-
if (typeof root_path === 'undefined') {
|
|
24
|
-
root_path = '/';
|
|
25
|
-
}
|
|
26
|
-
let items = useChildren(root_path);
|
|
27
|
-
if (root_path === '/') {
|
|
28
|
-
items = [];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<div className="block rast-block">
|
|
33
|
-
<ContextNavigation
|
|
34
|
-
items={items}
|
|
35
|
-
location={{
|
|
36
|
-
pathname: root_path,
|
|
37
|
-
}}
|
|
38
|
-
data={data}
|
|
39
|
-
/>
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|