@plone/volto 17.0.0-alpha.0 → 17.0.0-alpha.10
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/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +451 -19
- package/CONTRIBUTING.md +1 -1
- package/README.md +12 -15
- package/addon-registry.js +34 -0
- package/create-theme-addons-loader.js +79 -0
- package/cypress/support/commands.js +25 -0
- package/locales/ca/LC_MESSAGES/volto.po +187 -6
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +206 -25
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +186 -5
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +187 -6
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +187 -6
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +4792 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +187 -6
- package/locales/fr.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +187 -6
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +187 -6
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +842 -649
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +187 -6
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +195 -14
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +187 -6
- package/locales/ro.json +1 -1
- package/locales/volto.pot +187 -6
- package/locales/zh_CN/LC_MESSAGES/volto.po +187 -6
- package/locales/zh_CN.json +1 -1
- package/package-why.json +0 -1
- package/package.json +9 -8
- package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
- package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
- package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
- package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
- package/packages/volto-slate/package.json +1 -1
- package/packages/volto-slate/src/blocks/Table/TableBlockView.jsx +4 -4
- package/packages/volto-slate/src/blocks/Table/index.js +2 -0
- package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
- package/packages/volto-slate/src/editor/deserialize.js +0 -1
- package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
- package/razzle.config.js +28 -0
- package/src/actions/index.js +6 -0
- package/src/actions/language/language.js +9 -8
- package/src/actions/querystringsearch/querystringsearch.js +20 -14
- package/src/actions/relations/rebuild.js +25 -0
- package/src/actions/relations/relations.js +86 -0
- package/src/actions/relations/relations.test.js +15 -0
- package/src/components/index.js +1 -0
- package/src/components/manage/Add/Add.jsx +2 -2
- package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
- package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
- package/src/components/manage/BlockChooser/BlockChooserButton.jsx +63 -29
- package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +0 -1
- package/src/components/manage/Blocks/Listing/Edit.jsx +0 -19
- package/src/components/manage/Blocks/Listing/ListingBody.jsx +77 -61
- package/src/components/manage/Blocks/Listing/View.jsx +0 -4
- package/src/components/manage/Blocks/Listing/getAsyncData.js +10 -2
- package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +18 -13
- package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
- package/src/components/manage/Blocks/Search/components/Facets.jsx +58 -2
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +24 -11
- package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
- package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
- package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
- package/src/components/manage/Blocks/Search/schema.js +16 -1
- package/src/components/manage/Blocks/ToC/Edit.jsx +1 -0
- package/src/components/manage/Contents/Contents.jsx +69 -33
- package/src/components/manage/Contents/ContentsItem.jsx +6 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
- package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
- package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
- package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
- package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
- package/src/components/manage/DragDropList/DragDropList.jsx +63 -42
- package/src/components/manage/Form/BlocksToolbar.jsx +5 -1
- package/src/components/manage/Form/Form.jsx +11 -5
- package/src/components/manage/Form/InlineForm.jsx +39 -9
- package/src/components/manage/Form/InlineFormState.js +8 -0
- package/src/components/manage/History/History.jsx +35 -18
- package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
- package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
- package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
- package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
- package/src/components/manage/Toast/Toast.jsx +1 -1
- package/src/components/manage/Toolbar/Types.jsx +2 -2
- package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
- package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
- package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +7 -2
- package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
- package/src/components/manage/Widgets/SelectUtils.js +1 -1
- package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
- package/src/components/theme/Footer/Footer.jsx +2 -13
- package/src/components/theme/Header/Header.jsx +37 -63
- package/src/components/theme/Header/Header.test.jsx +18 -0
- package/src/components/theme/Icon/Icon.jsx +2 -2
- package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
- package/src/components/theme/Login/Login.jsx +1 -0
- package/src/components/theme/Logo/Logo.jsx +2 -1
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
- package/src/components/theme/Navigation/NavItem.jsx +4 -2
- package/src/components/theme/NotFound/NotFound.jsx +55 -41
- package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
- package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
- package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
- package/src/components/theme/View/DefaultView.jsx +1 -1
- package/src/components/theme/View/EventDatesInfo.jsx +2 -1
- package/src/components/theme/View/EventView.jsx +1 -1
- package/src/components/theme/View/NewsItemView.jsx +1 -1
- package/src/components/theme/View/RenderBlocks.jsx +7 -1
- package/src/components/theme/Widgets/DateWidget.jsx +2 -1
- package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
- package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
- package/src/config/ControlPanels.js +2 -0
- package/src/config/Widgets.jsx +1 -0
- package/src/config/index.js +3 -0
- package/src/config/server.js +19 -0
- package/src/constants/ActionTypes.js +4 -0
- package/src/constants/Languages.js +8 -4
- package/src/express-middleware/devproxy.js +4 -2
- package/src/express-middleware/sitemap.js +36 -4
- package/src/express-middleware/static.js +32 -0
- package/src/helpers/Api/Api.js +1 -1
- package/src/helpers/FormValidation/FormValidation.js +11 -2
- package/src/helpers/FormValidation/FormValidation.test.js +73 -0
- package/src/helpers/Html/Html.jsx +3 -1
- package/src/helpers/Html/Html.test.jsx +5 -0
- package/src/helpers/MessageLabels/MessageLabels.js +72 -0
- package/src/helpers/Robots/Robots.js +24 -6
- package/src/helpers/Sitemap/Sitemap.js +44 -2
- package/src/helpers/Url/Url.js +27 -6
- package/src/helpers/Url/Url.test.js +26 -0
- package/src/helpers/Utils/Utils.js +38 -13
- package/src/helpers/Utils/Utils.test.js +4 -4
- package/src/helpers/index.js +7 -2
- package/src/hooks/userSession/useToken.js +5 -0
- package/src/middleware/Api.test.js +54 -0
- package/src/middleware/api.js +8 -4
- package/src/reducers/actions/actions.js +1 -1
- package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
- package/src/reducers/index.js +2 -0
- package/src/reducers/navigation/navigation.js +1 -1
- package/src/reducers/relations/relations.js +173 -0
- package/src/reducers/types/types.js +1 -1
- package/src/routes.js +5 -0
- package/src/server.jsx +29 -30
- package/src/start-server.js +4 -2
- package/test-setup-config.js +1 -0
- package/theme/themes/pastanaga/extras/blocks.less +0 -9
- package/theme/themes/pastanaga/extras/contents.less +1 -0
- package/theme/themes/pastanaga/extras/main.less +80 -1
- package/theme/themes/pastanaga/extras/search.less +6 -0
- package/theme/themes/pastanaga/extras/sidebar.less +4 -0
- package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
- package/.changelog.draft +0 -22
- package/.editorconfig +0 -36
- package/.storybook/main.js +0 -127
- package/.storybook/manager.js +0 -15
- package/.storybook/preview.js +0 -21
- package/.storybook/static/previewImage.svg +0 -48
- package/.yarnrc.yml +0 -5
- package/jsdoc.json +0 -16
- package/netlify.toml +0 -5
- package/pyvenv.cfg +0 -3
- package/share/man/man1/ttx.1 +0 -225
- package/src/components/theme/Header/Header.md +0 -27
- package/towncrier.toml +0 -33
|
@@ -1,53 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @module components/theme/NotFound/NotFound
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React from 'react';
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { BodyClass, toBackendLang } from '@plone/volto/helpers';
|
|
7
3
|
import { FormattedMessage } from 'react-intl';
|
|
8
4
|
import { Link } from 'react-router-dom';
|
|
9
5
|
import { Container } from 'semantic-ui-react';
|
|
10
6
|
import { withServerErrorCode } from '@plone/volto/helpers/Utils/Utils';
|
|
7
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
8
|
+
import { getNavigation } from '@plone/volto/actions';
|
|
9
|
+
import config from '@plone/volto/registry';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Not found function.
|
|
14
13
|
* @function NotFound
|
|
15
14
|
* @returns {string} Markup of the not found page.
|
|
16
15
|
*/
|
|
17
|
-
const NotFound = () =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
16
|
+
const NotFound = () => {
|
|
17
|
+
const dispatch = useDispatch();
|
|
18
|
+
const lang = useSelector((state) => state.intl.locale);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
dispatch(
|
|
22
|
+
getNavigation(
|
|
23
|
+
config.settings.isMultilingual ? `/${toBackendLang(lang)}` : '/',
|
|
24
|
+
config.settings.navDepth,
|
|
25
|
+
),
|
|
26
|
+
);
|
|
27
|
+
}, [dispatch, lang]);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Container className="view-wrapper">
|
|
31
|
+
<BodyClass className="page-not-found" />
|
|
32
|
+
<h1>
|
|
33
|
+
<FormattedMessage
|
|
34
|
+
id="This page does not seem to exist…"
|
|
35
|
+
defaultMessage="This page does not seem to exist…"
|
|
36
|
+
/>
|
|
37
|
+
</h1>
|
|
38
|
+
<p className="description">
|
|
39
|
+
<FormattedMessage
|
|
40
|
+
id="We apologize for the inconvenience, but the page you were trying to access is not at this address. You can use the links below to help you find what you are looking for."
|
|
41
|
+
defaultMessage="We apologize for the inconvenience, but the page you were trying to access is not at this address. You can use the links below to help you find what you are looking for."
|
|
42
|
+
/>
|
|
43
|
+
</p>
|
|
44
|
+
<p>
|
|
45
|
+
<FormattedMessage
|
|
46
|
+
id="If you are certain you have the correct web address but are encountering an error, please contact the {site_admin}."
|
|
47
|
+
defaultMessage="If you are certain you have the correct web address but are encountering an error, please contact the {site_admin}."
|
|
48
|
+
values={{
|
|
49
|
+
site_admin: (
|
|
50
|
+
<Link to="/contact-form">
|
|
51
|
+
<FormattedMessage
|
|
52
|
+
id="Site Administration"
|
|
53
|
+
defaultMessage="Site Administration"
|
|
54
|
+
/>
|
|
55
|
+
</Link>
|
|
56
|
+
),
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
</p>
|
|
60
|
+
<p>
|
|
61
|
+
<FormattedMessage id="Thank you." defaultMessage="Thank you." />
|
|
62
|
+
</p>
|
|
63
|
+
</Container>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
52
66
|
|
|
53
67
|
export default withServerErrorCode(404)(NotFound);
|
|
@@ -31,7 +31,7 @@ const messages = defineMessages({
|
|
|
31
31
|
},
|
|
32
32
|
usernameTitle: {
|
|
33
33
|
id: 'My username is',
|
|
34
|
-
defaultMessage: 'My
|
|
34
|
+
defaultMessage: 'My user name is',
|
|
35
35
|
},
|
|
36
36
|
emailTitle: {
|
|
37
37
|
id: 'My email is',
|
|
@@ -50,8 +50,8 @@ const messages = defineMessages({
|
|
|
50
50
|
defaultMessage: 'New password',
|
|
51
51
|
},
|
|
52
52
|
passwordDescription: {
|
|
53
|
-
id: 'Enter your new password. Minimum
|
|
54
|
-
defaultMessage: 'Enter your new password. Minimum
|
|
53
|
+
id: 'Enter your new password. Minimum 8 characters.',
|
|
54
|
+
defaultMessage: 'Enter your new password. Minimum 8 characters.',
|
|
55
55
|
},
|
|
56
56
|
passwordRepeatTitle: {
|
|
57
57
|
id: 'Confirm password',
|
|
@@ -227,6 +227,9 @@ class PasswordReset extends Component {
|
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
if (this.props.token) {
|
|
230
|
+
const errmsg = this.props.error
|
|
231
|
+
? this.props.error.response.body.error
|
|
232
|
+
: null;
|
|
230
233
|
return (
|
|
231
234
|
<div id="page-password-reset">
|
|
232
235
|
<Helmet
|
|
@@ -238,7 +241,7 @@ class PasswordReset extends Component {
|
|
|
238
241
|
description={this.props.intl.formatMessage(messages.description)}
|
|
239
242
|
onSubmit={this.onSubmit}
|
|
240
243
|
onCancel={this.onCancel}
|
|
241
|
-
error={this.state.error ||
|
|
244
|
+
error={this.state.error || errmsg}
|
|
242
245
|
schema={{
|
|
243
246
|
fieldsets: [
|
|
244
247
|
{
|
|
@@ -10,7 +10,7 @@ import { connect } from 'react-redux';
|
|
|
10
10
|
import { asyncConnect } from '@plone/volto/helpers';
|
|
11
11
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
12
12
|
import { Container } from 'semantic-ui-react';
|
|
13
|
-
import { Helmet } from '@plone/volto/helpers';
|
|
13
|
+
import { Helmet, toBackendLang } from '@plone/volto/helpers';
|
|
14
14
|
import { Link } from 'react-router-dom';
|
|
15
15
|
import config from '@plone/volto/registry';
|
|
16
16
|
|
|
@@ -40,7 +40,7 @@ class Sitemap extends Component {
|
|
|
40
40
|
componentDidMount() {
|
|
41
41
|
const { settings } = config;
|
|
42
42
|
if (settings.isMultilingual) {
|
|
43
|
-
this.props.getNavigation(`${this.props.lang}`, 4);
|
|
43
|
+
this.props.getNavigation(`${toBackendLang(this.props.lang)}`, 4);
|
|
44
44
|
} else {
|
|
45
45
|
this.props.getNavigation('', 4);
|
|
46
46
|
}
|
|
@@ -108,7 +108,9 @@ export default compose(
|
|
|
108
108
|
const { settings } = config;
|
|
109
109
|
const lang = getState().intl.locale;
|
|
110
110
|
if (settings.isMultilingual) {
|
|
111
|
-
return
|
|
111
|
+
return (
|
|
112
|
+
__SERVER__ && dispatch(getNavigation(`${toBackendLang(lang)}`, 4))
|
|
113
|
+
);
|
|
112
114
|
} else {
|
|
113
115
|
return __SERVER__ && dispatch(getNavigation('', 4));
|
|
114
116
|
}
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { List } from 'semantic-ui-react';
|
|
4
4
|
import cx from 'classnames';
|
|
5
5
|
|
|
6
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
6
7
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
7
8
|
import { useSelector } from 'react-redux';
|
|
8
9
|
|
|
@@ -28,7 +29,7 @@ const When_ = ({ start, end, whole_day, open_end, moment: momentlib }) => {
|
|
|
28
29
|
const lang = useSelector((state) => state.intl.locale);
|
|
29
30
|
|
|
30
31
|
const moment = momentlib.default;
|
|
31
|
-
moment.locale(lang);
|
|
32
|
+
moment.locale(toBackendLang(lang));
|
|
32
33
|
|
|
33
34
|
const datesInfo = datesForDisplay(start, end, moment);
|
|
34
35
|
if (!datesInfo) {
|
|
@@ -43,7 +43,7 @@ const EventView = (props) => {
|
|
|
43
43
|
const { content } = props;
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
|
-
<div id="page-document" className="ui container
|
|
46
|
+
<div id="page-document" className="ui container view-wrapper event-view">
|
|
47
47
|
<Grid>
|
|
48
48
|
<Grid.Column width={7} className="mobile hidden">
|
|
49
49
|
{hasBlocksData(content) ? (
|
|
@@ -21,7 +21,7 @@ import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
|
|
|
21
21
|
*/
|
|
22
22
|
const NewsItemView = ({ content }) =>
|
|
23
23
|
hasBlocksData(content) ? (
|
|
24
|
-
<div id="page-document" className="ui container
|
|
24
|
+
<div id="page-document" className="ui container view-wrapper newsitem-view">
|
|
25
25
|
<RenderBlocks content={content} />
|
|
26
26
|
</div>
|
|
27
27
|
) : (
|
|
@@ -44,7 +44,13 @@ const RenderBlocks = (props) => {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
return Block ? (
|
|
47
|
-
<StyleWrapper
|
|
47
|
+
<StyleWrapper
|
|
48
|
+
key={block}
|
|
49
|
+
{...props}
|
|
50
|
+
id={block}
|
|
51
|
+
block={block}
|
|
52
|
+
data={blockData}
|
|
53
|
+
>
|
|
48
54
|
<Block
|
|
49
55
|
id={block}
|
|
50
56
|
metadata={metadata}
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
import { useSelector } from 'react-redux';
|
|
5
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
5
6
|
|
|
6
7
|
const DateWidget = ({ value, children, className, format = 'll' }) => {
|
|
7
8
|
const lang = useSelector((state) => state.intl.locale);
|
|
8
|
-
moment.locale(lang);
|
|
9
|
+
moment.locale(toBackendLang(lang));
|
|
9
10
|
return value ? (
|
|
10
11
|
<span className={cx(className, 'date', 'widget')}>
|
|
11
12
|
{children
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
import { useSelector } from 'react-redux';
|
|
5
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
5
6
|
|
|
6
7
|
const DatetimeWidget = ({ value, children, className, format = 'lll' }) => {
|
|
7
8
|
const lang = useSelector((state) => state.intl.locale);
|
|
8
|
-
moment.locale(lang);
|
|
9
|
+
moment.locale(toBackendLang(lang));
|
|
9
10
|
return value ? (
|
|
10
11
|
<span className={cx(className, 'datetime', 'widget')}>
|
|
11
12
|
{children
|
|
@@ -5,17 +5,19 @@ import RelationWidget from './RelationWidget';
|
|
|
5
5
|
const RelationsWidget = ({ value, children, className }) =>
|
|
6
6
|
value ? (
|
|
7
7
|
<ul className={cx(className, 'relations', 'widget')}>
|
|
8
|
-
{value.map((item, key) =>
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
{value.map((item, key) => {
|
|
9
|
+
return item ? (
|
|
10
|
+
<li key={key}>
|
|
11
|
+
<RelationWidget
|
|
12
|
+
value={item || `relation target not found '${key}'`}
|
|
13
|
+
className={className}
|
|
14
|
+
key={item.token || item.title || item}
|
|
15
|
+
>
|
|
16
|
+
{children}
|
|
17
|
+
</RelationWidget>
|
|
18
|
+
</li>
|
|
19
|
+
) : null;
|
|
20
|
+
})}
|
|
19
21
|
</ul>
|
|
20
22
|
) : (
|
|
21
23
|
''
|
|
@@ -18,6 +18,7 @@ import settingsSVG from '@plone/volto/icons/settings.svg';
|
|
|
18
18
|
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
|
+
import relationsSVG from '@plone/volto/icons/ahead.svg';
|
|
21
22
|
|
|
22
23
|
export const controlPanelsIcons = {
|
|
23
24
|
default: settingsSVG,
|
|
@@ -40,6 +41,7 @@ export const controlPanelsIcons = {
|
|
|
40
41
|
rules: rulesSVG,
|
|
41
42
|
undo: undoControlPanelSVG,
|
|
42
43
|
aliases: linkSVG,
|
|
44
|
+
relations: relationsSVG,
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
export const filterControlPanels = (controlpanels) => {
|
package/src/config/Widgets.jsx
CHANGED
|
@@ -98,6 +98,7 @@ export const widgetMapping = {
|
|
|
98
98
|
select_querystring_field: SelectMetadataWidget,
|
|
99
99
|
autocomplete: SelectAutoComplete,
|
|
100
100
|
color_picker: ColorPickerWidget,
|
|
101
|
+
select: SelectWidget,
|
|
101
102
|
},
|
|
102
103
|
vocabulary: {
|
|
103
104
|
'plone.app.vocabularies.Catalog': ObjectBrowserWidget,
|
package/src/config/index.js
CHANGED
|
@@ -89,6 +89,7 @@ let config = {
|
|
|
89
89
|
// https://6.docs.plone.org/volto/deploying/seamless-mode.html
|
|
90
90
|
devProxyToApiPath:
|
|
91
91
|
process.env.RAZZLE_DEV_PROXY_API_PATH ||
|
|
92
|
+
process.env.RAZZLE_INTERNAL_API_PATH ||
|
|
92
93
|
process.env.RAZZLE_API_PATH ||
|
|
93
94
|
'http://localhost:8080/Plone', // Set it to '' for disabling the proxy
|
|
94
95
|
// proxyRewriteTarget Set it for set a custom target for the proxy or overide the internal VHM rewrite
|
|
@@ -179,6 +180,8 @@ let config = {
|
|
|
179
180
|
styleClassNameConverters,
|
|
180
181
|
hashLinkSmoothScroll: false,
|
|
181
182
|
styleClassNameExtenders,
|
|
183
|
+
querystringSearchGet: false,
|
|
184
|
+
blockSettingsTabFieldsetsInitialStateOpen: true,
|
|
182
185
|
},
|
|
183
186
|
experimental: {
|
|
184
187
|
addBlockButton: {
|
package/src/config/server.js
CHANGED
|
@@ -2,6 +2,7 @@ import imagesMiddleware from '@plone/volto/express-middleware/images';
|
|
|
2
2
|
import filesMiddleware from '@plone/volto/express-middleware/files';
|
|
3
3
|
import robotstxtMiddleware from '@plone/volto/express-middleware/robotstxt';
|
|
4
4
|
import sitemapMiddleware from '@plone/volto/express-middleware/sitemap';
|
|
5
|
+
import staticsMiddleware from '@plone/volto/express-middleware/static';
|
|
5
6
|
import devProxyMiddleware from '@plone/volto/express-middleware/devproxy';
|
|
6
7
|
|
|
7
8
|
const settings = {
|
|
@@ -11,10 +12,28 @@ const settings = {
|
|
|
11
12
|
imagesMiddleware(),
|
|
12
13
|
robotstxtMiddleware(),
|
|
13
14
|
sitemapMiddleware(),
|
|
15
|
+
staticsMiddleware(),
|
|
14
16
|
],
|
|
15
17
|
criticalCssPath: 'public/critical.css',
|
|
16
18
|
readCriticalCss: null, // so it will be defaultReadCriticalCss
|
|
17
19
|
extractScripts: { errorPages: false },
|
|
20
|
+
staticFiles: [
|
|
21
|
+
{
|
|
22
|
+
id: 'root_static',
|
|
23
|
+
match: /^\/static\/.*/,
|
|
24
|
+
headers: {
|
|
25
|
+
// stable resources never change. 31536000 seconds == 365 days
|
|
26
|
+
'Cache-Control': 'public, max-age=31536000',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'all',
|
|
31
|
+
match: /.*/,
|
|
32
|
+
headers: {
|
|
33
|
+
'Cache-Control': 'public, max-age=60',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
18
37
|
};
|
|
19
38
|
|
|
20
39
|
export default settings;
|
|
@@ -36,6 +36,10 @@ export const GET_NAVIGATION = 'GET_NAVIGATION';
|
|
|
36
36
|
export const GET_PRINCIPALS = 'GET_PRINCIPALS';
|
|
37
37
|
export const GET_QUERYSTRING = 'GET_QUERYSTRING';
|
|
38
38
|
export const GET_QUERYSTRING_RESULTS = 'GET_QUERYSTRING_RESULTS';
|
|
39
|
+
export const CREATE_RELATIONS = 'CREATE_RELATIONS';
|
|
40
|
+
export const DELETE_RELATIONS = 'DELETE_RELATIONS';
|
|
41
|
+
export const LIST_RELATIONS = 'LIST_RELATIONS';
|
|
42
|
+
export const REBUILD_RELATIONS = 'REBUILD_RELATIONS';
|
|
39
43
|
export const GET_SCHEMA = 'GET_SCHEMA';
|
|
40
44
|
export const POST_SCHEMA = 'POST_SCHEMA';
|
|
41
45
|
export const PUT_SCHEMA = 'PUT_SCHEMA';
|
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
7
|
-
|
|
7
|
+
ca: 'Català',
|
|
8
8
|
de: 'Deutsch',
|
|
9
|
+
en: 'English',
|
|
10
|
+
es: 'Español',
|
|
11
|
+
eu: 'Euskara',
|
|
12
|
+
fi: 'Suomi',
|
|
13
|
+
fr: 'Français',
|
|
14
|
+
it: 'Italiano',
|
|
9
15
|
nl: 'Nederlands',
|
|
10
16
|
ro: 'Română',
|
|
11
17
|
ja: '日本語',
|
|
12
18
|
pt: 'Português',
|
|
13
19
|
pt_BR: 'Português (Brasil)',
|
|
14
|
-
|
|
15
|
-
it: 'Italian',
|
|
16
|
-
eu: 'Euskara',
|
|
20
|
+
zh_CN: '中文',
|
|
17
21
|
};
|
|
@@ -75,12 +75,14 @@ export default function () {
|
|
|
75
75
|
const { apiPathURL, instancePath } = getEnv();
|
|
76
76
|
const target =
|
|
77
77
|
config.settings.proxyRewriteTarget ||
|
|
78
|
-
`/VirtualHostBase
|
|
78
|
+
`/VirtualHostBase/${apiPathURL.protocol.slice(0, -1)}/${
|
|
79
|
+
apiPathURL.hostname
|
|
80
|
+
}:${apiPathURL.port}${instancePath}/++api++/VirtualHostRoot`;
|
|
79
81
|
|
|
80
82
|
return `${target}${path.replace('/++api++', '')}`;
|
|
81
83
|
},
|
|
82
84
|
logLevel: process.env.DEBUG_HPM ? 'debug' : 'silent',
|
|
83
|
-
...(
|
|
85
|
+
...(process.env.RAZZLE_DEV_PROXY_INSECURE && {
|
|
84
86
|
changeOrigin: true,
|
|
85
87
|
secure: false,
|
|
86
88
|
}),
|
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
generateSitemap,
|
|
4
|
+
generateSitemapIndex,
|
|
5
|
+
SITEMAP_BATCH_SIZE,
|
|
6
|
+
} from '@plone/volto/helpers/Sitemap/Sitemap';
|
|
3
7
|
|
|
4
8
|
export const sitemap = function (req, res, next) {
|
|
5
|
-
|
|
9
|
+
let start = 0;
|
|
10
|
+
let size = undefined;
|
|
11
|
+
const { batch: batchStr } = req.params;
|
|
12
|
+
if (batchStr !== undefined) {
|
|
13
|
+
const batch = parseInt(batchStr);
|
|
14
|
+
if (isNaN(batch) || batch === 0 || '' + batch !== batchStr) {
|
|
15
|
+
res.status(404);
|
|
16
|
+
// Some data, such as the internal API address, may be sensitive to be published
|
|
17
|
+
res.send(
|
|
18
|
+
`Invalid sitemap name, use sitemap.xml.gz, or batched sitemapN.xml.gz where N is a positive integer.`,
|
|
19
|
+
);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
start = SITEMAP_BATCH_SIZE * (batch - 1);
|
|
23
|
+
size = SITEMAP_BATCH_SIZE;
|
|
24
|
+
}
|
|
25
|
+
generateSitemap(req, start, size).then((sitemap) => {
|
|
6
26
|
if (Buffer.isBuffer(sitemap)) {
|
|
7
27
|
res.set('Content-Type', 'application/x-gzip');
|
|
8
|
-
res.set(
|
|
9
|
-
|
|
28
|
+
res.set(
|
|
29
|
+
'Content-Disposition',
|
|
30
|
+
`attachment; filename="sitemap${batchStr || ''}.xml.gz"`,
|
|
31
|
+
);
|
|
10
32
|
res.send(sitemap);
|
|
11
33
|
} else {
|
|
12
34
|
// {"errno":-111, "code":"ECONNREFUSED", "host": ...}
|
|
@@ -17,10 +39,20 @@ export const sitemap = function (req, res, next) {
|
|
|
17
39
|
});
|
|
18
40
|
};
|
|
19
41
|
|
|
42
|
+
export const sitemapIndex = function (req, res, next) {
|
|
43
|
+
generateSitemapIndex(req).then((sitemapIndex) => {
|
|
44
|
+
res.set('Content-Type', 'application/xml');
|
|
45
|
+
res.set('Content-Disposition', 'attachment; filename="sitemap-index.xml"');
|
|
46
|
+
res.send(sitemapIndex);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
20
50
|
export default function () {
|
|
21
51
|
const middleware = express.Router();
|
|
22
52
|
|
|
23
53
|
middleware.all('**/sitemap.xml.gz', sitemap);
|
|
54
|
+
middleware.all('**/sitemap:batch.xml.gz', sitemap);
|
|
55
|
+
middleware.all('**/sitemap-index.xml', sitemapIndex);
|
|
24
56
|
middleware.id = 'sitemap.xml.gz';
|
|
25
57
|
return middleware;
|
|
26
58
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import config from '@plone/volto/registry';
|
|
4
|
+
|
|
5
|
+
const staticMiddleware = express.static(
|
|
6
|
+
process.env.BUILD_DIR
|
|
7
|
+
? path.join(process.env.BUILD_DIR, 'public')
|
|
8
|
+
: process.env.RAZZLE_PUBLIC_DIR,
|
|
9
|
+
{
|
|
10
|
+
setHeaders: function (res, path) {
|
|
11
|
+
const pathLib = require('path');
|
|
12
|
+
const base = pathLib.resolve(process.env.RAZZLE_PUBLIC_DIR);
|
|
13
|
+
const relpath = path.substr(base.length);
|
|
14
|
+
config.settings.serverConfig.staticFiles.some((elem) => {
|
|
15
|
+
if (relpath.match(elem.match)) {
|
|
16
|
+
for (const name in elem.headers) {
|
|
17
|
+
res.setHeader(name, elem.headers[name] || 'undefined');
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export default function () {
|
|
28
|
+
const middleware = express.Router();
|
|
29
|
+
middleware.all('*', staticMiddleware);
|
|
30
|
+
middleware.id = 'staticResourcesProcessor';
|
|
31
|
+
return middleware;
|
|
32
|
+
}
|
package/src/helpers/Api/Api.js
CHANGED
|
@@ -65,7 +65,16 @@ const widgetValidation = {
|
|
|
65
65
|
},
|
|
66
66
|
url: {
|
|
67
67
|
isValidURL: (urlValue, urlObj, intlFunc) => {
|
|
68
|
-
|
|
68
|
+
var urlRegex = new RegExp(
|
|
69
|
+
'^(https?:\\/\\/)?' + // validate protocol
|
|
70
|
+
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
|
|
71
|
+
'((\\d{1,3}\\.){3}\\d{1,3}))|' + // validate OR ip (v4) address
|
|
72
|
+
'(localhost)' + // validate OR localhost address
|
|
73
|
+
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path
|
|
74
|
+
'(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
|
|
75
|
+
'(\\#[-a-z\\d_]*)?$', // validate fragment locator
|
|
76
|
+
'i',
|
|
77
|
+
);
|
|
69
78
|
const isValid = urlRegex.test(urlValue);
|
|
70
79
|
return !isValid ? intlFunc(messages.isValidURL) : null;
|
|
71
80
|
},
|
|
@@ -194,7 +203,7 @@ const validateRequiredFields = (
|
|
|
194
203
|
const type = schema.properties[requiredField]?.type;
|
|
195
204
|
const widget = schema.properties[requiredField]?.widget;
|
|
196
205
|
|
|
197
|
-
let isEmpty = !formData[requiredField];
|
|
206
|
+
let isEmpty = !formData[requiredField] && formData[requiredField] !== 0;
|
|
198
207
|
if (!isEmpty) {
|
|
199
208
|
if (type === 'array') {
|
|
200
209
|
isEmpty = formData[requiredField]
|