@plone/volto 18.0.0-alpha.41 → 18.0.0-alpha.43
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 +114 -0
- package/finalreleasechangelog.py +48 -0
- package/locales/ca/LC_MESSAGES/volto.po +39 -13
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +40 -14
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +39 -13
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +40 -14
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +40 -14
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +40 -14
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +40 -14
- package/locales/fr.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +40 -14
- package/locales/hi.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +40 -14
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +39 -13
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +39 -13
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +39 -13
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +40 -14
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +39 -13
- package/locales/ro.json +1 -1
- package/locales/volto.pot +40 -14
- package/locales/zh_CN/LC_MESSAGES/volto.po +40 -14
- package/locales/zh_CN.json +1 -1
- package/package.json +5 -6
- package/razzle.config.js +3 -3
- package/src/components/index.js +0 -1
- package/src/components/manage/Actions/Actions.stories.jsx +138 -0
- package/src/components/manage/Add/Add.jsx +7 -4
- package/src/components/manage/BlockChooser/BlockChooser.jsx +9 -1
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +5 -0
- package/src/components/manage/Blocks/Block/Edit.jsx +24 -8
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +17 -1
- package/src/components/manage/Blocks/Block/Order/Item.jsx +8 -2
- package/src/components/manage/Blocks/Block/Order/Order.jsx +2 -0
- package/src/components/manage/Blocks/Container/Data.jsx +10 -2
- package/src/components/manage/Blocks/Grid/View.jsx +3 -0
- package/src/components/manage/Blocks/Image/ImageSidebar.jsx +10 -2
- package/src/components/manage/Blocks/LeadImage/Edit.jsx +74 -126
- package/src/components/manage/Blocks/Listing/ListingData.jsx +10 -2
- package/src/components/manage/Blocks/Maps/MapsSidebar.jsx +3 -1
- package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +2 -0
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +18 -2
- package/src/components/manage/Blocks/Search/components/SortOn.jsx +82 -55
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +1 -1
- package/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +107 -176
- package/src/components/manage/Blocks/Teaser/Data.jsx +10 -2
- package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +15 -8
- package/src/components/manage/Blocks/ToC/Edit.jsx +36 -28
- package/src/components/manage/Blocks/Video/Edit.jsx +105 -172
- package/src/components/manage/Blocks/Video/Edit.stories.jsx +57 -0
- package/src/components/manage/Blocks/Video/VideoSidebar.jsx +3 -1
- package/src/components/manage/Contents/Contents.jsx +4 -1
- package/src/components/manage/Contents/ContentsBreadcrumbs.stories.jsx +46 -0
- package/src/components/manage/Contents/ContentsPropertiesModal.jsx +85 -52
- package/src/components/manage/Contents/ContentsUploadModal.jsx +230 -323
- package/src/components/manage/Contents/ContentsUploadModal.stories.jsx +56 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +323 -441
- package/src/components/manage/Controlpanels/Aliases.jsx +452 -580
- package/src/components/manage/Controlpanels/Aliases.stories.jsx +74 -0
- package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -0
- package/src/components/manage/Controlpanels/Controlpanel.jsx +41 -2
- package/src/components/manage/Controlpanels/Controlpanel.test.jsx +55 -24
- package/src/components/manage/Controlpanels/DatabaseInformation.jsx +162 -229
- package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +74 -122
- package/src/components/manage/Controlpanels/UndoControlpanel.jsx +3 -3
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +28 -12
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +12 -4
- package/src/components/manage/Display/Display.jsx +92 -148
- package/src/components/manage/Display/Display.stories.jsx +46 -0
- package/src/components/manage/Edit/Edit.jsx +2 -4
- package/src/components/manage/Form/Form.jsx +85 -20
- package/src/components/manage/Form/InlineForm.jsx +2 -4
- package/src/components/manage/Form/ModalForm.jsx +1 -1
- package/src/components/manage/History/History.jsx +1 -1
- package/src/components/manage/Pluggable/Pluggable.test.js +1 -1
- package/src/components/manage/Preferences/ChangePassword.jsx +94 -172
- package/src/components/manage/Preferences/ChangePassword.stories.jsx +41 -0
- package/src/components/manage/Preferences/PersonalInformation.jsx +50 -115
- package/src/components/manage/Preferences/PersonalPreferences.jsx +46 -100
- package/src/components/manage/Preferences/PersonalPreferences.stories.jsx +48 -0
- package/src/components/manage/Toolbar/More.jsx +308 -399
- package/src/components/manage/Toolbar/Toolbar.jsx +1 -1
- package/src/components/manage/Widgets/ArrayWidget.jsx +2 -2
- package/src/components/manage/Widgets/DatetimeWidget.jsx +121 -175
- package/src/components/manage/Widgets/ImageWidget.jsx +6 -5
- package/src/components/manage/Widgets/RecurrenceWidget/EndField.jsx +7 -1
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +80 -31
- package/src/components/manage/Widgets/ReferenceWidget.jsx +134 -210
- package/src/components/theme/Register/Register.jsx +70 -142
- package/src/components/theme/Register/Register.stories.jsx +49 -0
- package/src/components/theme/Search/Search.jsx +13 -5
- package/src/components/theme/Tags/Tags.jsx +19 -10
- package/src/components/theme/Tags/Tags.test.jsx +9 -11
- package/src/components/theme/View/AlbumView.jsx +122 -167
- package/src/components/theme/View/LinkView.jsx +4 -0
- package/src/components/theme/View/LinkView.test.jsx +2 -0
- package/src/components/theme/View/View.jsx +0 -13
- package/src/components/theme/View/View.test.jsx +0 -3
- package/src/config/ControlPanels.js +49 -43
- package/src/config/Widgets.jsx +1 -1
- package/src/config/config.test.js +1 -0
- package/src/config/index.js +23 -2
- package/src/config/slots.js +12 -0
- package/src/config/validation.ts +155 -0
- package/src/helpers/Blocks/Blocks.js +12 -7
- package/src/helpers/Blocks/Blocks.test.js +15 -0
- package/src/helpers/Blocks/cloneBlocks.ts +1 -1
- package/src/helpers/Extensions/withBlockExtensions.jsx +1 -1
- package/src/helpers/FormValidation/FormValidation.jsx +128 -172
- package/src/helpers/FormValidation/FormValidation.test.js +836 -8
- package/src/helpers/FormValidation/validators.ts +203 -0
- package/src/helpers/MessageLabels/MessageLabels.js +28 -0
- package/src/helpers/Url/Url.test.js +19 -6
- package/src/helpers/Url/urlRegex.js +1 -1
- package/src/helpers/User/User.js +1 -1
- package/src/helpers/index.js +2 -0
- package/src/hooks/client/useClient.js +1 -1
- package/src/middleware/api.js +4 -2
- package/src/middleware/index.js +1 -0
- package/src/middleware/userSessionReset.js +46 -0
- package/src/store.js +2 -0
- package/test-setup-config.jsx +10 -0
- package/theme/themes/default/modules/embed.variables +1 -1
- package/theme/themes/pastanaga/collections/form.overrides +34 -0
- package/theme/themes/pastanaga/extras/blocks.less +6 -0
- package/theme/themes/pastanaga/extras/sidebar.less +4 -0
- package/theme/themes/pastanaga/extras/toolbar.less +10 -3
- package/tsconfig.declarations.json +3 -2
- package/types/components/index.d.ts +0 -1
- package/types/components/manage/Actions/Actions.stories.d.ts +8 -0
- package/types/components/manage/Blocks/Block/Order/Order.d.ts +2 -1
- package/types/components/manage/Blocks/LeadImage/Edit.d.ts +14 -5
- package/types/components/manage/Blocks/Search/widgets/SelectMetadataField.d.ts +0 -5
- package/types/components/manage/Blocks/ToC/Edit.d.ts +1 -6
- package/types/components/manage/Blocks/Video/Edit.d.ts +1 -1
- package/types/components/manage/Blocks/Video/Edit.stories.d.ts +8 -0
- package/types/components/manage/Contents/ContentsBreadcrumbs.stories.d.ts +8 -0
- package/types/components/manage/Contents/ContentsUploadModal.d.ts +14 -2
- package/types/components/manage/Contents/ContentsUploadModal.stories.d.ts +8 -0
- package/types/components/manage/Contents/index.d.ts +1 -1
- package/types/components/manage/Controlpanels/AddonsControlpanel.d.ts +2 -2
- package/types/components/manage/Controlpanels/Aliases.d.ts +2 -2
- package/types/components/manage/Controlpanels/Aliases.stories.d.ts +8 -0
- package/types/components/manage/Controlpanels/DatabaseInformation.d.ts +2 -2
- package/types/components/manage/Controlpanels/Groups/RenderGroups.d.ts +10 -5
- package/types/components/manage/Controlpanels/index.d.ts +4 -4
- package/types/components/manage/Display/Display.stories.d.ts +8 -0
- package/types/components/manage/Preferences/ChangePassword.d.ts +2 -2
- package/types/components/manage/Preferences/ChangePassword.stories.d.ts +8 -0
- package/types/components/manage/Preferences/PersonalInformation.d.ts +7 -2
- package/types/components/manage/Preferences/PersonalPreferences.d.ts +5 -1
- package/types/components/manage/Preferences/PersonalPreferences.stories.d.ts +8 -0
- package/types/components/manage/Toolbar/More.d.ts +8 -5
- package/types/components/manage/Widgets/DatetimeWidget.d.ts +0 -85
- package/types/components/manage/Widgets/DatetimeWidget.stories.d.ts +0 -1
- package/types/components/manage/Widgets/ReferenceWidget.d.ts +27 -2
- package/types/components/manage/Widgets/index.d.ts +1 -1
- package/types/components/theme/Register/Register.d.ts +2 -2
- package/types/components/theme/Register/Register.stories.d.ts +9 -0
- package/types/components/theme/Tags/Tags.d.ts +15 -7
- package/types/components/theme/View/AlbumView.d.ts +3 -17
- package/types/config/ControlPanels.d.ts +8 -0
- package/types/config/RichTextEditor/ToHTML.d.ts +1 -1
- package/types/config/Widgets.d.ts +3 -3
- package/types/config/slots.d.ts +21 -0
- package/types/config/validation.d.ts +3 -0
- package/types/helpers/Blocks/Blocks.d.ts +6 -0
- package/types/helpers/Extensions/withBlockExtensions.d.ts +1 -1
- package/types/helpers/FormValidation/FormValidation.d.ts +2 -0
- package/types/helpers/FormValidation/validators.d.ts +29 -0
- package/types/helpers/MessageLabels/MessageLabels.d.ts +36 -0
- package/types/helpers/User/User.d.ts +1 -1
- package/types/helpers/index.d.ts +2 -2
- package/types/middleware/index.d.ts +1 -0
- package/types/middleware/userSessionReset.d.ts +5 -0
- package/src/components/theme/SocialSharing/SocialSharing.jsx +0 -48
- package/src/components/theme/SocialSharing/SocialSharing.test.jsx +0 -14
|
@@ -71,6 +71,7 @@ class Search extends Component {
|
|
|
71
71
|
|
|
72
72
|
constructor(props) {
|
|
73
73
|
super(props);
|
|
74
|
+
this.defaultPageSize = config.settings.defaultPageSize;
|
|
74
75
|
this.state = { currentPage: 1, isClient: false, active: 'relevance' };
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -109,19 +110,24 @@ class Search extends Component {
|
|
|
109
110
|
const options = qs.parse(this.props.history.location.search);
|
|
110
111
|
this.setState({ currentPage: 1 });
|
|
111
112
|
options['use_site_search_settings'] = 1;
|
|
112
|
-
this.props.searchContent('',
|
|
113
|
+
this.props.searchContent('', {
|
|
114
|
+
b_size: this.defaultPageSize,
|
|
115
|
+
...options,
|
|
116
|
+
});
|
|
113
117
|
};
|
|
114
118
|
|
|
115
119
|
handleQueryPaginationChange = (e, { activePage }) => {
|
|
116
|
-
const { settings } = config;
|
|
117
120
|
window.scrollTo(0, 0);
|
|
118
121
|
let options = qs.parse(this.props.history.location.search);
|
|
119
122
|
options['use_site_search_settings'] = 1;
|
|
120
123
|
|
|
121
124
|
this.setState({ currentPage: activePage }, () => {
|
|
122
125
|
this.props.searchContent('', {
|
|
126
|
+
b_size: this.defaultPageSize,
|
|
123
127
|
...options,
|
|
124
|
-
b_start:
|
|
128
|
+
b_start:
|
|
129
|
+
(this.state.currentPage - 1) *
|
|
130
|
+
(options.b_size || this.defaultPageSize),
|
|
125
131
|
});
|
|
126
132
|
});
|
|
127
133
|
};
|
|
@@ -149,7 +155,8 @@ class Search extends Component {
|
|
|
149
155
|
* @returns {string} Markup for the component.
|
|
150
156
|
*/
|
|
151
157
|
render() {
|
|
152
|
-
const
|
|
158
|
+
const options = qs.parse(this.props.history.location.search);
|
|
159
|
+
|
|
153
160
|
return (
|
|
154
161
|
<Container id="page-search">
|
|
155
162
|
<Helmet title={this.props.intl.formatMessage(messages.Search)} />
|
|
@@ -282,7 +289,8 @@ class Search extends Component {
|
|
|
282
289
|
<Pagination
|
|
283
290
|
activePage={this.state.currentPage}
|
|
284
291
|
totalPages={Math.ceil(
|
|
285
|
-
this.props.search.items_total /
|
|
292
|
+
this.props.search.items_total /
|
|
293
|
+
(options.b_size || this.defaultPageSize),
|
|
286
294
|
)}
|
|
287
295
|
onPageChange={this.handleQueryPaginationChange}
|
|
288
296
|
firstItem={null}
|
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
* @module components/theme/Tags/Tags
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from 'react';
|
|
7
6
|
import { Link } from 'react-router-dom';
|
|
8
7
|
import PropTypes from 'prop-types';
|
|
9
8
|
import { Container } from 'semantic-ui-react';
|
|
9
|
+
import config from '@plone/registry';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Tags component
|
|
12
|
+
* Tags component.
|
|
13
13
|
* @function Tags
|
|
14
|
-
* @param {
|
|
15
|
-
* @
|
|
14
|
+
* @param {Object} props Component properties.
|
|
15
|
+
* @param {Object} props.content Content object that may contain subjects.
|
|
16
|
+
* @param {Array} [props.content.subjects] Optional array of tags (subjects).
|
|
17
|
+
* @returns {JSX.Element|null} Markup of the component or null if no tags are available.
|
|
16
18
|
*/
|
|
17
|
-
const Tags = ({
|
|
18
|
-
|
|
19
|
+
const Tags = ({ content }) => {
|
|
20
|
+
const tags = content?.subjects || [];
|
|
21
|
+
|
|
22
|
+
if (!config.settings.showTags || !tags.length) return null;
|
|
23
|
+
|
|
24
|
+
return (
|
|
19
25
|
<Container className="tags">
|
|
20
26
|
{tags.map((tag) => (
|
|
21
27
|
<Link className="ui label" to={`/search?Subject=${tag}`} key={tag}>
|
|
@@ -23,9 +29,8 @@ const Tags = ({ tags }) =>
|
|
|
23
29
|
</Link>
|
|
24
30
|
))}
|
|
25
31
|
</Container>
|
|
26
|
-
) : (
|
|
27
|
-
<span />
|
|
28
32
|
);
|
|
33
|
+
};
|
|
29
34
|
|
|
30
35
|
/**
|
|
31
36
|
* Property types.
|
|
@@ -33,7 +38,9 @@ const Tags = ({ tags }) =>
|
|
|
33
38
|
* @static
|
|
34
39
|
*/
|
|
35
40
|
Tags.propTypes = {
|
|
36
|
-
|
|
41
|
+
content: PropTypes.shape({
|
|
42
|
+
subjects: PropTypes.arrayOf(PropTypes.string),
|
|
43
|
+
}),
|
|
37
44
|
};
|
|
38
45
|
|
|
39
46
|
/**
|
|
@@ -42,7 +49,9 @@ Tags.propTypes = {
|
|
|
42
49
|
* @static
|
|
43
50
|
*/
|
|
44
51
|
Tags.defaultProps = {
|
|
45
|
-
|
|
52
|
+
content: {
|
|
53
|
+
subjects: [],
|
|
54
|
+
},
|
|
46
55
|
};
|
|
47
56
|
|
|
48
57
|
export default Tags;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import renderer from 'react-test-renderer';
|
|
3
2
|
import configureStore from 'redux-mock-store';
|
|
4
3
|
import { Provider } from 'react-intl-redux';
|
|
@@ -9,17 +8,22 @@ import Tags from './Tags';
|
|
|
9
8
|
const mockStore = configureStore();
|
|
10
9
|
|
|
11
10
|
describe('Tags', () => {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
let store;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
store = mockStore({
|
|
14
15
|
intl: {
|
|
15
16
|
locale: 'en',
|
|
16
17
|
messages: {},
|
|
17
18
|
},
|
|
18
19
|
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders without tags', () => {
|
|
19
23
|
const component = renderer.create(
|
|
20
24
|
<Provider store={store}>
|
|
21
25
|
<MemoryRouter>
|
|
22
|
-
<Tags />
|
|
26
|
+
<Tags content={{ subjects: [] }} />
|
|
23
27
|
</MemoryRouter>
|
|
24
28
|
</Provider>,
|
|
25
29
|
);
|
|
@@ -28,16 +32,10 @@ describe('Tags', () => {
|
|
|
28
32
|
});
|
|
29
33
|
|
|
30
34
|
it('renders with tags', () => {
|
|
31
|
-
const store = mockStore({
|
|
32
|
-
intl: {
|
|
33
|
-
locale: 'en',
|
|
34
|
-
messages: {},
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
35
|
const component = renderer.create(
|
|
38
36
|
<Provider store={store}>
|
|
39
37
|
<MemoryRouter>
|
|
40
|
-
<Tags
|
|
38
|
+
<Tags content={{ subjects: ['Tag 1', 'Tag 2'] }} />
|
|
41
39
|
</MemoryRouter>
|
|
42
40
|
</Provider>,
|
|
43
41
|
);
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Album view component.
|
|
3
|
-
* @module components/theme/View/AlbumView
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React from 'react';
|
|
1
|
+
import { Fragment, useState } from 'react';
|
|
7
2
|
import PropTypes from 'prop-types';
|
|
8
3
|
import {
|
|
9
4
|
Container as SemanticContainer,
|
|
@@ -18,178 +13,138 @@ import openSVG from '@plone/volto/icons/open.svg';
|
|
|
18
13
|
import aheadSVG from '@plone/volto/icons/ahead.svg';
|
|
19
14
|
import backSVG from '@plone/volto/icons/back.svg';
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* @function AlbumView
|
|
24
|
-
* @param {Object} content Content object.
|
|
25
|
-
* @returns {string} Markup of the component.
|
|
26
|
-
*/
|
|
27
|
-
class AlbumView extends React.Component {
|
|
28
|
-
constructor(props) {
|
|
29
|
-
super(props);
|
|
30
|
-
|
|
31
|
-
this.state = {
|
|
32
|
-
openIndex: undefined,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
this.closeModal = this.closeModal.bind(this);
|
|
36
|
-
this.nextImage = this.nextImage.bind(this);
|
|
37
|
-
this.prevImage = this.prevImage.bind(this);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
closeModal() {
|
|
41
|
-
this.setState({
|
|
42
|
-
openIndex: -1,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
nextImage() {
|
|
47
|
-
const openIndex =
|
|
48
|
-
(this.state.openIndex + 1) % this.props.content.items.length;
|
|
49
|
-
this.setState({
|
|
50
|
-
openIndex,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
prevImage() {
|
|
55
|
-
const openIndex =
|
|
56
|
-
(this.state.openIndex - 1) % this.props.content.items.length;
|
|
57
|
-
this.setState({
|
|
58
|
-
openIndex,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
16
|
+
const AlbumView = ({ content }) => {
|
|
17
|
+
const [openIndex, setOpenIndex] = useState(undefined);
|
|
61
18
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
66
|
-
const PreviewImage = config.getComponent({
|
|
67
|
-
name: 'PreviewImage',
|
|
68
|
-
}).component;
|
|
19
|
+
const closeModal = () => {
|
|
20
|
+
setOpenIndex(-1);
|
|
21
|
+
};
|
|
69
22
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
23
|
+
const nextImage = () => {
|
|
24
|
+
let OpenIndex = (openIndex + 1) % content.items.length;
|
|
25
|
+
setOpenIndex(OpenIndex);
|
|
26
|
+
};
|
|
27
|
+
const prevImage = () => {
|
|
28
|
+
const OpenIndex = (openIndex - 1) % content.items.length;
|
|
29
|
+
setOpenIndex(OpenIndex);
|
|
30
|
+
};
|
|
31
|
+
const Container =
|
|
32
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
33
|
+
const PreviewImage = config.getComponent({ name: 'PreviewImage' }).component;
|
|
34
|
+
return (
|
|
35
|
+
<Container className="view-wrapper">
|
|
36
|
+
<article id="content">
|
|
37
|
+
<header>
|
|
38
|
+
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
39
|
+
{content.description && (
|
|
40
|
+
<p className="documentDescription">{content.description}</p>
|
|
41
|
+
)}
|
|
42
|
+
</header>
|
|
43
|
+
<section id="content-core">
|
|
44
|
+
<Grid doubling stackable columns={4}>
|
|
45
|
+
{content.items &&
|
|
46
|
+
content.items.map((item, index) => (
|
|
47
|
+
<Fragment key={item.url}>
|
|
48
|
+
{item.image_field && (
|
|
49
|
+
<Modal
|
|
50
|
+
className="gallery"
|
|
51
|
+
onClose={closeModal}
|
|
52
|
+
open={openIndex === index}
|
|
53
|
+
trigger={
|
|
54
|
+
<Grid.Column>
|
|
55
|
+
<Segment className="imageborder">
|
|
56
|
+
<PreviewImage
|
|
57
|
+
item={item}
|
|
58
|
+
alt={item.image_caption || item.title}
|
|
59
|
+
onClick={() => {
|
|
60
|
+
setOpenIndex(index);
|
|
61
|
+
}}
|
|
62
|
+
className="ui middle aligned image"
|
|
63
|
+
responsive={true}
|
|
64
|
+
loading="lazy"
|
|
65
|
+
title={item.title}
|
|
66
|
+
/>
|
|
67
|
+
</Segment>
|
|
68
|
+
</Grid.Column>
|
|
69
|
+
}
|
|
70
|
+
closeIcon
|
|
71
|
+
>
|
|
72
|
+
<Modal.Header>
|
|
73
|
+
<Grid>
|
|
74
|
+
<Grid.Row>
|
|
75
|
+
<GridColumn width={10}>{item.title}</GridColumn>
|
|
76
|
+
<GridColumn width={2} textAlign="right">
|
|
77
|
+
<UniversalLink
|
|
78
|
+
href={item.url}
|
|
79
|
+
title={item['@type']}
|
|
80
|
+
onClick={closeModal}
|
|
81
|
+
>
|
|
82
|
+
<Icon size="30px" fitted name={openSVG} />
|
|
83
|
+
</UniversalLink>
|
|
84
|
+
</GridColumn>
|
|
85
|
+
</Grid.Row>
|
|
86
|
+
</Grid>
|
|
87
|
+
</Modal.Header>
|
|
88
|
+
<Grid centered verticalAlign="middle">
|
|
89
|
+
<Grid.Row>
|
|
90
|
+
<Grid.Column width={2} textAlign="center">
|
|
91
|
+
<Button
|
|
92
|
+
className="gallery noborder"
|
|
93
|
+
onClick={prevImage}
|
|
94
|
+
style={{ margin: 0 }}
|
|
95
|
+
>
|
|
96
|
+
<Icon
|
|
97
|
+
name={backSVG}
|
|
98
|
+
className="circled"
|
|
99
|
+
size="30px"
|
|
100
|
+
style={{ margin: 0 }}
|
|
101
|
+
/>
|
|
102
|
+
</Button>
|
|
103
|
+
</Grid.Column>
|
|
104
|
+
<Grid.Column width={8}>
|
|
105
|
+
<Modal.Content image>
|
|
92
106
|
<PreviewImage
|
|
93
107
|
item={item}
|
|
94
|
-
alt={item.image_caption
|
|
108
|
+
alt={item.image_caption}
|
|
95
109
|
onClick={() => {
|
|
96
|
-
|
|
97
|
-
openIndex: index,
|
|
98
|
-
});
|
|
110
|
+
setOpenIndex(index);
|
|
99
111
|
}}
|
|
100
|
-
className="ui
|
|
112
|
+
className="ui image"
|
|
101
113
|
responsive={true}
|
|
102
|
-
loading="lazy"
|
|
103
|
-
title={item.title}
|
|
104
114
|
/>
|
|
105
|
-
|
|
115
|
+
|
|
116
|
+
<Modal.Description>
|
|
117
|
+
<p>{item.description}</p>
|
|
118
|
+
</Modal.Description>
|
|
119
|
+
</Modal.Content>
|
|
106
120
|
</Grid.Column>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
title={item['@type']}
|
|
118
|
-
onClick={this.closeModal}
|
|
119
|
-
>
|
|
120
|
-
<Icon size="30px" fitted name={openSVG} />
|
|
121
|
-
</UniversalLink>
|
|
122
|
-
</GridColumn>
|
|
123
|
-
</Grid.Row>
|
|
124
|
-
</Grid>
|
|
125
|
-
</Modal.Header>
|
|
126
|
-
<Grid centered verticalAlign="middle">
|
|
127
|
-
<Grid.Row>
|
|
128
|
-
<Grid.Column width={2} textAlign="center">
|
|
129
|
-
<Button
|
|
130
|
-
className="gallery noborder"
|
|
131
|
-
onClick={this.nextImage}
|
|
121
|
+
<Grid.Column width={2} textAlign="center">
|
|
122
|
+
<Button
|
|
123
|
+
onClick={nextImage}
|
|
124
|
+
className="gallery noborder"
|
|
125
|
+
style={{ margin: 0 }}
|
|
126
|
+
>
|
|
127
|
+
<Icon
|
|
128
|
+
name={aheadSVG}
|
|
129
|
+
className="circled"
|
|
130
|
+
size="30px"
|
|
132
131
|
style={{ margin: 0 }}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.setState({
|
|
149
|
-
openIndex: index,
|
|
150
|
-
});
|
|
151
|
-
}}
|
|
152
|
-
className="ui image"
|
|
153
|
-
responsive={true}
|
|
154
|
-
/>
|
|
155
|
-
<Modal.Description>
|
|
156
|
-
<p>{item.description}</p>
|
|
157
|
-
</Modal.Description>
|
|
158
|
-
</Modal.Content>
|
|
159
|
-
</Grid.Column>
|
|
160
|
-
<Grid.Column width={2} textAlign="center">
|
|
161
|
-
<Button
|
|
162
|
-
onClick={this.nextImage}
|
|
163
|
-
className="gallery noborder"
|
|
164
|
-
style={{ margin: 0 }}
|
|
165
|
-
>
|
|
166
|
-
<Icon
|
|
167
|
-
name={aheadSVG}
|
|
168
|
-
className="circled"
|
|
169
|
-
size="30px"
|
|
170
|
-
style={{ margin: 0 }}
|
|
171
|
-
/>
|
|
172
|
-
</Button>
|
|
173
|
-
</Grid.Column>
|
|
174
|
-
</Grid.Row>
|
|
175
|
-
</Grid>
|
|
176
|
-
</Modal>
|
|
177
|
-
)}
|
|
178
|
-
</React.Fragment>
|
|
179
|
-
))}
|
|
180
|
-
</Grid>
|
|
181
|
-
</section>
|
|
182
|
-
</article>
|
|
183
|
-
</Container>
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
132
|
+
/>
|
|
133
|
+
</Button>
|
|
134
|
+
</Grid.Column>
|
|
135
|
+
</Grid.Row>
|
|
136
|
+
</Grid>
|
|
137
|
+
</Modal>
|
|
138
|
+
)}
|
|
139
|
+
</Fragment>
|
|
140
|
+
))}
|
|
141
|
+
</Grid>
|
|
142
|
+
</section>
|
|
143
|
+
</article>
|
|
144
|
+
</Container>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
187
147
|
|
|
188
|
-
/**
|
|
189
|
-
* Property types.
|
|
190
|
-
* @property {Object} propTypes Property types.
|
|
191
|
-
* @static
|
|
192
|
-
*/
|
|
193
148
|
AlbumView.propTypes = {
|
|
194
149
|
/**
|
|
195
150
|
* Content of the object
|
|
@@ -4,6 +4,7 @@ import { useHistory } from 'react-router-dom';
|
|
|
4
4
|
import { isInternalURL, flattenToAppURL } from '@plone/volto/helpers';
|
|
5
5
|
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
6
6
|
import { UniversalLink } from '@plone/volto/components';
|
|
7
|
+
import { Redirect } from 'react-router-dom';
|
|
7
8
|
import { FormattedMessage } from 'react-intl';
|
|
8
9
|
import config from '@plone/volto/registry';
|
|
9
10
|
|
|
@@ -19,6 +20,9 @@ const LinkView = ({ token, content }) => {
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
}, [content, history, token]);
|
|
23
|
+
if (__SERVER__ && !token && content.remoteUrl) {
|
|
24
|
+
return <Redirect to={content.remoteUrl} />;
|
|
25
|
+
}
|
|
22
26
|
const { title, description, remoteUrl } = content;
|
|
23
27
|
const { openExternalLinkInNewTab } = config.settings;
|
|
24
28
|
const Container =
|
|
@@ -15,7 +15,6 @@ import qs from 'query-string';
|
|
|
15
15
|
import {
|
|
16
16
|
ContentMetadataTags,
|
|
17
17
|
Comments,
|
|
18
|
-
Tags,
|
|
19
18
|
Toolbar,
|
|
20
19
|
} from '@plone/volto/components';
|
|
21
20
|
import { listActions, getContent } from '@plone/volto/actions';
|
|
@@ -256,18 +255,6 @@ class View extends Component {
|
|
|
256
255
|
history={this.props.history}
|
|
257
256
|
/>
|
|
258
257
|
<SlotRenderer name="belowContent" content={this.props.content} />
|
|
259
|
-
{config.settings.showTags &&
|
|
260
|
-
this.props.content.subjects &&
|
|
261
|
-
this.props.content.subjects.length > 0 && (
|
|
262
|
-
<Tags tags={this.props.content.subjects} />
|
|
263
|
-
)}
|
|
264
|
-
{/* Add opt-in social sharing if required, disabled by default */}
|
|
265
|
-
{/* In the future this might be parameterized from the app config */}
|
|
266
|
-
{/* <SocialSharing
|
|
267
|
-
url={typeof window === 'undefined' ? '' : window.location.href}
|
|
268
|
-
title={this.props.content.title}
|
|
269
|
-
description={this.props.content.description || ''}
|
|
270
|
-
/> */}
|
|
271
258
|
{this.props.content.allow_discussion && (
|
|
272
259
|
<Comments pathname={this.props.pathname} />
|
|
273
260
|
)}
|
|
@@ -30,9 +30,6 @@ jest.mock('../../manage/Toolbar/Toolbar', () =>
|
|
|
30
30
|
jest.fn(() => <div id="Portal" />),
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
-
jest.mock('../SocialSharing/SocialSharing', () =>
|
|
34
|
-
jest.fn(() => <div id="SocialSharing" />),
|
|
35
|
-
);
|
|
36
33
|
jest.mock('../Comments/Comments', () => jest.fn(() => <div id="Comments" />));
|
|
37
34
|
jest.mock('../Tags/Tags', () => jest.fn(() => <div id="Tags" />));
|
|
38
35
|
jest.mock('../SlotRenderer/SlotRenderer', () =>
|
|
@@ -19,6 +19,7 @@ import rulesSVG from '@plone/volto/icons/content-existing.svg';
|
|
|
19
19
|
import undoControlPanelSVG from '@plone/volto/icons/undo-control-panel.svg';
|
|
20
20
|
import linkSVG from '@plone/volto/icons/link.svg';
|
|
21
21
|
import relationsSVG from '@plone/volto/icons/ahead.svg';
|
|
22
|
+
import config from '@plone/volto/registry';
|
|
22
23
|
|
|
23
24
|
export const controlPanelsIcons = {
|
|
24
25
|
default: settingsSVG,
|
|
@@ -53,62 +54,67 @@ export const filterControlPanels = (controlpanels = []) => {
|
|
|
53
54
|
);
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
export const unwantedControlPanelsFields = {
|
|
58
|
+
language: ['display_flags', 'always_show_selector'],
|
|
59
|
+
search: ['enable_livesearch'],
|
|
60
|
+
site: [
|
|
61
|
+
'display_publication_date_in_byline',
|
|
62
|
+
'icon_visibility',
|
|
63
|
+
'thumb_visibility',
|
|
64
|
+
'no_thumbs_portlet',
|
|
65
|
+
'no_thumbs_lists',
|
|
66
|
+
'no_thumbs_summary',
|
|
67
|
+
'no_thumbs_tables',
|
|
68
|
+
'thumb_scale_portlet',
|
|
69
|
+
'thumb_scale_listing',
|
|
70
|
+
'thumb_scale_table',
|
|
71
|
+
'thumb_scale_summary',
|
|
72
|
+
'toolbar_position',
|
|
73
|
+
'toolbar_logo',
|
|
74
|
+
'default_page',
|
|
75
|
+
'site_favicon',
|
|
76
|
+
'site_favicon_mimetype',
|
|
77
|
+
'exposeDCMetaTags',
|
|
78
|
+
'enable_sitemap',
|
|
79
|
+
'robots_txt',
|
|
80
|
+
'webstats_js',
|
|
81
|
+
],
|
|
82
|
+
editing: ['available_editors', 'default_editor', 'ext_editor'],
|
|
83
|
+
imaging: [
|
|
84
|
+
'highpixeldensity_scales',
|
|
85
|
+
'quality_2x',
|
|
86
|
+
'quality_3x',
|
|
87
|
+
'picture_variants',
|
|
88
|
+
'image_captioning',
|
|
89
|
+
],
|
|
90
|
+
navigation: [
|
|
91
|
+
'generate_tabs',
|
|
92
|
+
'navigation_depth',
|
|
93
|
+
'nonfolderish_tabs',
|
|
94
|
+
'sort_tabs_on',
|
|
95
|
+
'sort_tabs_reversed',
|
|
96
|
+
'sitemap_depth',
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
|
|
56
100
|
// Filters props.controlpanel.schema to only valid/relevant fields
|
|
57
101
|
export const filterControlPanelsSchema = (controlpanel) => {
|
|
58
102
|
const panelType = controlpanel['@id'].split('/').pop();
|
|
59
103
|
|
|
60
|
-
const
|
|
61
|
-
language: ['display_flags', 'always_show_selector'],
|
|
62
|
-
search: ['enable_livesearch'],
|
|
63
|
-
site: [
|
|
64
|
-
'display_publication_date_in_byline',
|
|
65
|
-
'icon_visibility',
|
|
66
|
-
'thumb_visibility',
|
|
67
|
-
'no_thumbs_portlet',
|
|
68
|
-
'no_thumbs_lists',
|
|
69
|
-
'no_thumbs_summary',
|
|
70
|
-
'no_thumbs_tables',
|
|
71
|
-
'thumb_scale_portlet',
|
|
72
|
-
'thumb_scale_listing',
|
|
73
|
-
'thumb_scale_table',
|
|
74
|
-
'thumb_scale_summary',
|
|
75
|
-
'toolbar_position',
|
|
76
|
-
'toolbar_logo',
|
|
77
|
-
'default_page',
|
|
78
|
-
'site_favicon',
|
|
79
|
-
'site_favicon_mimetype',
|
|
80
|
-
'exposeDCMetaTags',
|
|
81
|
-
'enable_sitemap',
|
|
82
|
-
'robots_txt',
|
|
83
|
-
'webstats_js',
|
|
84
|
-
],
|
|
85
|
-
editing: ['available_editors', 'default_editor', 'ext_editor'],
|
|
86
|
-
imaging: [
|
|
87
|
-
'highpixeldensity_scales',
|
|
88
|
-
'quality_2x',
|
|
89
|
-
'quality_3x',
|
|
90
|
-
'picture_variants',
|
|
91
|
-
'image_captioning',
|
|
92
|
-
],
|
|
93
|
-
navigation: [
|
|
94
|
-
'generate_tabs',
|
|
95
|
-
'navigation_depth',
|
|
96
|
-
'sort_tabs_on',
|
|
97
|
-
'sort_tabs_reversed',
|
|
98
|
-
'sitemap_depth',
|
|
99
|
-
],
|
|
100
|
-
};
|
|
104
|
+
const { unwantedControlPanelsFields } = config.settings;
|
|
101
105
|
|
|
102
106
|
// Creates modified version of properties object
|
|
103
107
|
const newPropertiesObj = Object.fromEntries(
|
|
104
108
|
Object.entries(controlpanel.schema.properties).filter(
|
|
105
|
-
([key,
|
|
109
|
+
([key, _val]) =>
|
|
110
|
+
!(unwantedControlPanelsFields[panelType] || []).includes(key),
|
|
106
111
|
),
|
|
107
112
|
);
|
|
108
113
|
// Filters props.controlpanel.schema.fieldsets.fields to only valid/relevant fields
|
|
109
114
|
const filterFields = (fields) => {
|
|
110
115
|
return fields.filter(
|
|
111
|
-
(field) =>
|
|
116
|
+
(field) =>
|
|
117
|
+
!(unwantedControlPanelsFields[panelType] || []).includes(field),
|
|
112
118
|
);
|
|
113
119
|
};
|
|
114
120
|
// Creates modified version of fieldsets array
|