@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.
Files changed (190) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +451 -19
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +12 -15
  5. package/addon-registry.js +34 -0
  6. package/create-theme-addons-loader.js +79 -0
  7. package/cypress/support/commands.js +25 -0
  8. package/locales/ca/LC_MESSAGES/volto.po +187 -6
  9. package/locales/ca.json +1 -1
  10. package/locales/de/LC_MESSAGES/volto.po +206 -25
  11. package/locales/de.json +1 -1
  12. package/locales/en/LC_MESSAGES/volto.po +186 -5
  13. package/locales/en.json +1 -1
  14. package/locales/es/LC_MESSAGES/volto.po +187 -6
  15. package/locales/es.json +1 -1
  16. package/locales/eu/LC_MESSAGES/volto.po +187 -6
  17. package/locales/eu.json +1 -1
  18. package/locales/fi/LC_MESSAGES/volto.po +4792 -0
  19. package/locales/fi.json +1 -1
  20. package/locales/fr/LC_MESSAGES/volto.po +187 -6
  21. package/locales/fr.json +1 -1
  22. package/locales/it/LC_MESSAGES/volto.po +187 -6
  23. package/locales/it.json +1 -1
  24. package/locales/ja/LC_MESSAGES/volto.po +187 -6
  25. package/locales/ja.json +1 -1
  26. package/locales/nl/LC_MESSAGES/volto.po +842 -649
  27. package/locales/nl.json +1 -1
  28. package/locales/pt/LC_MESSAGES/volto.po +187 -6
  29. package/locales/pt.json +1 -1
  30. package/locales/pt_BR/LC_MESSAGES/volto.po +195 -14
  31. package/locales/pt_BR.json +1 -1
  32. package/locales/ro/LC_MESSAGES/volto.po +187 -6
  33. package/locales/ro.json +1 -1
  34. package/locales/volto.pot +187 -6
  35. package/locales/zh_CN/LC_MESSAGES/volto.po +187 -6
  36. package/locales/zh_CN.json +1 -1
  37. package/package-why.json +0 -1
  38. package/package.json +9 -8
  39. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
  40. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
  41. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
  42. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
  43. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
  44. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
  45. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
  46. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
  47. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
  48. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
  49. package/packages/volto-slate/package.json +1 -1
  50. package/packages/volto-slate/src/blocks/Table/TableBlockView.jsx +4 -4
  51. package/packages/volto-slate/src/blocks/Table/index.js +2 -0
  52. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
  53. package/packages/volto-slate/src/editor/deserialize.js +0 -1
  54. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  55. package/razzle.config.js +28 -0
  56. package/src/actions/index.js +6 -0
  57. package/src/actions/language/language.js +9 -8
  58. package/src/actions/querystringsearch/querystringsearch.js +20 -14
  59. package/src/actions/relations/rebuild.js +25 -0
  60. package/src/actions/relations/relations.js +86 -0
  61. package/src/actions/relations/relations.test.js +15 -0
  62. package/src/components/index.js +1 -0
  63. package/src/components/manage/Add/Add.jsx +2 -2
  64. package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
  65. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
  66. package/src/components/manage/BlockChooser/BlockChooserButton.jsx +63 -29
  67. package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +0 -1
  68. package/src/components/manage/Blocks/Listing/Edit.jsx +0 -19
  69. package/src/components/manage/Blocks/Listing/ListingBody.jsx +77 -61
  70. package/src/components/manage/Blocks/Listing/View.jsx +0 -4
  71. package/src/components/manage/Blocks/Listing/getAsyncData.js +10 -2
  72. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +18 -13
  73. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
  74. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
  75. package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
  76. package/src/components/manage/Blocks/Search/components/Facets.jsx +58 -2
  77. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +24 -11
  78. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  79. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  80. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  81. package/src/components/manage/Blocks/Search/schema.js +16 -1
  82. package/src/components/manage/Blocks/ToC/Edit.jsx +1 -0
  83. package/src/components/manage/Contents/Contents.jsx +69 -33
  84. package/src/components/manage/Contents/ContentsItem.jsx +6 -0
  85. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
  86. package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
  87. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
  88. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
  89. package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
  90. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
  91. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
  92. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
  93. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
  94. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
  95. package/src/components/manage/DragDropList/DragDropList.jsx +63 -42
  96. package/src/components/manage/Form/BlocksToolbar.jsx +5 -1
  97. package/src/components/manage/Form/Form.jsx +11 -5
  98. package/src/components/manage/Form/InlineForm.jsx +39 -9
  99. package/src/components/manage/Form/InlineFormState.js +8 -0
  100. package/src/components/manage/History/History.jsx +35 -18
  101. package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
  102. package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
  103. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  104. package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
  105. package/src/components/manage/Toast/Toast.jsx +1 -1
  106. package/src/components/manage/Toolbar/Types.jsx +2 -2
  107. package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
  108. package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
  109. package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
  110. package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
  111. package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
  112. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +7 -2
  113. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
  114. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  115. package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
  116. package/src/components/theme/Footer/Footer.jsx +2 -13
  117. package/src/components/theme/Header/Header.jsx +37 -63
  118. package/src/components/theme/Header/Header.test.jsx +18 -0
  119. package/src/components/theme/Icon/Icon.jsx +2 -2
  120. package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
  121. package/src/components/theme/Login/Login.jsx +1 -0
  122. package/src/components/theme/Logo/Logo.jsx +2 -1
  123. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
  124. package/src/components/theme/Navigation/NavItem.jsx +4 -2
  125. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  126. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
  127. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
  128. package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
  129. package/src/components/theme/View/DefaultView.jsx +1 -1
  130. package/src/components/theme/View/EventDatesInfo.jsx +2 -1
  131. package/src/components/theme/View/EventView.jsx +1 -1
  132. package/src/components/theme/View/NewsItemView.jsx +1 -1
  133. package/src/components/theme/View/RenderBlocks.jsx +7 -1
  134. package/src/components/theme/Widgets/DateWidget.jsx +2 -1
  135. package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
  136. package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
  137. package/src/config/ControlPanels.js +2 -0
  138. package/src/config/Widgets.jsx +1 -0
  139. package/src/config/index.js +3 -0
  140. package/src/config/server.js +19 -0
  141. package/src/constants/ActionTypes.js +4 -0
  142. package/src/constants/Languages.js +8 -4
  143. package/src/express-middleware/devproxy.js +4 -2
  144. package/src/express-middleware/sitemap.js +36 -4
  145. package/src/express-middleware/static.js +32 -0
  146. package/src/helpers/Api/Api.js +1 -1
  147. package/src/helpers/FormValidation/FormValidation.js +11 -2
  148. package/src/helpers/FormValidation/FormValidation.test.js +73 -0
  149. package/src/helpers/Html/Html.jsx +3 -1
  150. package/src/helpers/Html/Html.test.jsx +5 -0
  151. package/src/helpers/MessageLabels/MessageLabels.js +72 -0
  152. package/src/helpers/Robots/Robots.js +24 -6
  153. package/src/helpers/Sitemap/Sitemap.js +44 -2
  154. package/src/helpers/Url/Url.js +27 -6
  155. package/src/helpers/Url/Url.test.js +26 -0
  156. package/src/helpers/Utils/Utils.js +38 -13
  157. package/src/helpers/Utils/Utils.test.js +4 -4
  158. package/src/helpers/index.js +7 -2
  159. package/src/hooks/userSession/useToken.js +5 -0
  160. package/src/middleware/Api.test.js +54 -0
  161. package/src/middleware/api.js +8 -4
  162. package/src/reducers/actions/actions.js +1 -1
  163. package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
  164. package/src/reducers/index.js +2 -0
  165. package/src/reducers/navigation/navigation.js +1 -1
  166. package/src/reducers/relations/relations.js +173 -0
  167. package/src/reducers/types/types.js +1 -1
  168. package/src/routes.js +5 -0
  169. package/src/server.jsx +29 -30
  170. package/src/start-server.js +4 -2
  171. package/test-setup-config.js +1 -0
  172. package/theme/themes/pastanaga/extras/blocks.less +0 -9
  173. package/theme/themes/pastanaga/extras/contents.less +1 -0
  174. package/theme/themes/pastanaga/extras/main.less +80 -1
  175. package/theme/themes/pastanaga/extras/search.less +6 -0
  176. package/theme/themes/pastanaga/extras/sidebar.less +4 -0
  177. package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
  178. package/.changelog.draft +0 -22
  179. package/.editorconfig +0 -36
  180. package/.storybook/main.js +0 -127
  181. package/.storybook/manager.js +0 -15
  182. package/.storybook/preview.js +0 -21
  183. package/.storybook/static/previewImage.svg +0 -48
  184. package/.yarnrc.yml +0 -5
  185. package/jsdoc.json +0 -16
  186. package/netlify.toml +0 -5
  187. package/pyvenv.cfg +0 -3
  188. package/share/man/man1/ttx.1 +0 -225
  189. package/src/components/theme/Header/Header.md +0 -27
  190. package/towncrier.toml +0 -33
@@ -1,53 +1,67 @@
1
- /**
2
- * Home container.
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
- <Container className="view-wrapper">
19
- <h1>
20
- <FormattedMessage
21
- id="This page does not seem to exist…"
22
- defaultMessage="This page does not seem to exist…"
23
- />
24
- </h1>
25
- <p className="description">
26
- <FormattedMessage
27
- 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."
28
- 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."
29
- />
30
- </p>
31
- <p>
32
- <FormattedMessage
33
- id="If you are certain you have the correct web address but are encountering an error, please contact the {site_admin}."
34
- defaultMessage="If you are certain you have the correct web address but are encountering an error, please contact the {site_admin}."
35
- values={{
36
- site_admin: (
37
- <Link to="/contact-form">
38
- <FormattedMessage
39
- id="Site Administration"
40
- defaultMessage="Site Administration"
41
- />
42
- </Link>
43
- ),
44
- }}
45
- />
46
- </p>
47
- <p>
48
- <FormattedMessage id="Thank you." defaultMessage="Thank you." />
49
- </p>
50
- </Container>
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 username is',
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 5 characters.',
54
- defaultMessage: 'Enter your new password. Minimum 5 characters.',
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 || this.props.error}
244
+ error={this.state.error || errmsg}
242
245
  schema={{
243
246
  fieldsets: [
244
247
  {
@@ -32,7 +32,7 @@ const messages = defineMessages({
32
32
  },
33
33
  usernameTitle: {
34
34
  id: 'label_my_username_is',
35
- defaultMessage: 'My username is',
35
+ defaultMessage: 'My user name is',
36
36
  },
37
37
  emailTitle: {
38
38
  id: 'label_my_email_is',
@@ -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 __SERVER__ && dispatch(getNavigation(`${lang}`, 4));
111
+ return (
112
+ __SERVER__ && dispatch(getNavigation(`${toBackendLang(lang)}`, 4))
113
+ );
112
114
  } else {
113
115
  return __SERVER__ && dispatch(getNavigation('', 4));
114
116
  }
@@ -87,7 +87,7 @@ const DefaultView = (props) => {
87
87
  return f !== 'title' ? (
88
88
  <Grid celled="internally" key={key}>
89
89
  <Grid.Row>
90
- <Label>{field.title}:</Label>
90
+ <Label title={field.id}>{field.title}:</Label>
91
91
  </Grid.Row>
92
92
  <Grid.Row>
93
93
  <Segment basic>
@@ -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 viewwrapper event-view">
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 viewwrapper event-view">
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 key={block} {...props} id={block} data={blockData}>
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
- <li key={key}>
10
- <RelationWidget
11
- value={item}
12
- className={className}
13
- key={item.token || item.title || item}
14
- >
15
- {children}
16
- </RelationWidget>
17
- </li>
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) => {
@@ -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,
@@ -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: {
@@ -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
- en: 'English',
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
- es: 'Spanish',
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/http/${apiPathURL.hostname}:${apiPathURL.port}${instancePath}/++api++/VirtualHostRoot`;
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
- ...(config.settings?.proxyRewriteTarget?.startsWith('https') && {
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 { generateSitemap } from '@plone/volto/helpers/Sitemap/Sitemap';
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
- generateSitemap(req).then((sitemap) => {
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('Content-Encoding', 'gzip');
9
- res.set('Content-Disposition', 'attachment; filename="sitemap.xml.gz"');
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
+ }
@@ -89,7 +89,7 @@ class Api {
89
89
  checkUrl &&
90
90
  request.url &&
91
91
  request.xhr &&
92
- stripQuerystring(request.url) !==
92
+ encodeURI(stripQuerystring(request.url)) !==
93
93
  stripQuerystring(request.xhr.responseURL)
94
94
  ) {
95
95
  if (request.xhr.responseURL?.length === 0) {
@@ -65,7 +65,16 @@ const widgetValidation = {
65
65
  },
66
66
  url: {
67
67
  isValidURL: (urlValue, urlObj, intlFunc) => {
68
- const urlRegex = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([_.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm;
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]