@plone/volto 19.0.0-alpha.1 → 19.0.0-alpha.3

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 (152) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +0 -2
  3. package/cypress/downloads/downloads.html +0 -0
  4. package/locales/af.json +1 -0
  5. package/locales/ar.json +1 -0
  6. package/locales/bg.json +1 -0
  7. package/locales/bn.json +1 -0
  8. package/locales/ca/LC_MESSAGES/volto.po +54 -9
  9. package/locales/ca.json +1 -1
  10. package/locales/cs.json +1 -0
  11. package/locales/cy.json +1 -0
  12. package/locales/da.json +1 -0
  13. package/locales/de/LC_MESSAGES/volto.po +59 -14
  14. package/locales/de.json +1 -1
  15. package/locales/el.json +1 -0
  16. package/locales/en/LC_MESSAGES/volto.po +55 -10
  17. package/locales/en.json +1 -1
  18. package/locales/en_AU.json +1 -0
  19. package/locales/en_GB.json +1 -0
  20. package/locales/eo.json +1 -0
  21. package/locales/es/LC_MESSAGES/volto.po +55 -10
  22. package/locales/es.json +1 -1
  23. package/locales/et.json +1 -0
  24. package/locales/eu/LC_MESSAGES/volto.po +54 -9
  25. package/locales/eu.json +1 -1
  26. package/locales/fa.json +1 -0
  27. package/locales/fi/LC_MESSAGES/volto.po +54 -9
  28. package/locales/fi.json +1 -1
  29. package/locales/fr/LC_MESSAGES/volto.po +55 -10
  30. package/locales/fr.json +1 -1
  31. package/locales/fu.json +1 -0
  32. package/locales/gl.json +1 -0
  33. package/locales/he.json +1 -0
  34. package/locales/hi/LC_MESSAGES/volto.po +58 -13
  35. package/locales/hi.json +1 -1
  36. package/locales/hr.json +1 -0
  37. package/locales/hu.json +1 -0
  38. package/locales/hy.json +1 -0
  39. package/locales/id.json +1 -0
  40. package/locales/it/LC_MESSAGES/volto.po +58 -13
  41. package/locales/it.json +1 -1
  42. package/locales/ja/LC_MESSAGES/volto.po +54 -9
  43. package/locales/ja.json +1 -1
  44. package/locales/ka.json +1 -0
  45. package/locales/kn.json +1 -0
  46. package/locales/ko.json +1 -0
  47. package/locales/lt.json +1 -0
  48. package/locales/lv.json +1 -0
  49. package/locales/mi.json +1 -0
  50. package/locales/mk.json +1 -0
  51. package/locales/my.json +1 -0
  52. package/locales/nb_NO.json +1 -0
  53. package/locales/nl/LC_MESSAGES/volto.po +58 -13
  54. package/locales/nl.json +1 -1
  55. package/locales/nn.json +1 -0
  56. package/locales/pl.json +1 -0
  57. package/locales/pt/LC_MESSAGES/volto.po +54 -9
  58. package/locales/pt.json +1 -1
  59. package/locales/pt_BR/LC_MESSAGES/volto.po +66 -21
  60. package/locales/pt_BR.json +1 -1
  61. package/locales/rm.json +1 -0
  62. package/locales/ro/LC_MESSAGES/volto.po +58 -13
  63. package/locales/ro.json +1 -1
  64. package/locales/ru/LC_MESSAGES/volto.po +58 -13
  65. package/locales/ru.json +1 -1
  66. package/locales/sk.json +1 -0
  67. package/locales/sl.json +1 -0
  68. package/locales/sm.json +1 -0
  69. package/locales/sq.json +1 -0
  70. package/locales/sr.json +1 -0
  71. package/locales/sr@cyrl.json +1 -0
  72. package/locales/sr@latn.json +1 -0
  73. package/locales/sv.json +1 -1
  74. package/locales/ta.json +1 -0
  75. package/locales/te.json +1 -0
  76. package/locales/th.json +1 -0
  77. package/locales/to.json +1 -0
  78. package/locales/tr.json +1 -0
  79. package/locales/uk.json +1 -0
  80. package/locales/vi.json +1 -0
  81. package/locales/volto.pot +55 -10
  82. package/locales/zh_CN/LC_MESSAGES/volto.po +54 -9
  83. package/locales/zh_CN.json +1 -1
  84. package/locales/zh_Hant.json +1 -0
  85. package/locales/zh_Hant_HK.json +1 -0
  86. package/package.json +7 -7
  87. package/src/actions/content/content.js +0 -1
  88. package/src/actions/controlpanels/controlpanels.js +13 -7
  89. package/src/actions/controlpanels/controlpanels.test.js +11 -5
  90. package/src/actions/users/users.js +2 -2
  91. package/src/components/manage/Add/Add.jsx +5 -6
  92. package/src/components/manage/Blocks/Block/Edit.jsx +1 -0
  93. package/src/components/manage/Blocks/Teaser/schema.js +8 -3
  94. package/src/components/manage/Blocks/Title/Edit.jsx +8 -2
  95. package/src/components/manage/Contents/Contents.jsx +3 -0
  96. package/src/components/manage/Contents/Contents.test.jsx +7 -0
  97. package/src/components/manage/Contents/ContentsBreadcrumbs.Multilingual.test.jsx +18 -5
  98. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +20 -26
  99. package/src/components/manage/Contents/ContentsBreadcrumbs.test.jsx +14 -0
  100. package/src/components/manage/Contents/ContentsDeleteModal.jsx +258 -206
  101. package/src/components/manage/Contents/ContentsDeleteModal.stories.jsx +26 -8
  102. package/src/components/manage/Contents/ContentsItem.jsx +9 -1
  103. package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
  104. package/src/components/manage/Edit/Edit.jsx +2 -3
  105. package/src/components/manage/Form/Form.jsx +32 -0
  106. package/src/components/manage/Form/Form.test.jsx +22 -18
  107. package/src/components/manage/Multilingual/CompareLanguages.jsx +2 -5
  108. package/src/components/manage/Multilingual/ManageTranslations.jsx +4 -2
  109. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +5 -1
  110. package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
  111. package/src/components/manage/Toolbar/More.jsx +4 -1
  112. package/src/components/manage/Toolbar/More.test.jsx +3 -0
  113. package/src/components/manage/Toolbar/Toolbar.jsx +3 -4
  114. package/src/components/manage/Toolbar/Types.jsx +7 -7
  115. package/src/components/manage/Widgets/SelectWidget.jsx +3 -1
  116. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -3
  117. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +0 -4
  118. package/src/components/theme/App/App.jsx +3 -1
  119. package/src/components/theme/App/App.test.jsx +1 -0
  120. package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
  121. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +9 -7
  122. package/src/components/theme/LanguageSelector/LanguageSelector.test.jsx +6 -6
  123. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +0 -5
  124. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +8 -12
  125. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +3 -5
  126. package/src/components/theme/Navigation/NavItem.jsx +1 -5
  127. package/src/components/theme/Navigation/Navigation.Multilingual.test.jsx +0 -5
  128. package/src/components/theme/NotFound/NotFound.jsx +5 -2
  129. package/src/components/theme/NotFound/NotFound.test.jsx +3 -0
  130. package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
  131. package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
  132. package/src/components/theme/View/FileView.jsx +9 -1
  133. package/src/config/index.js +5 -14
  134. package/src/helpers/Html/Html.jsx +0 -3
  135. package/src/helpers/LanguageMap/LanguageMap.js +115 -8
  136. package/src/helpers/Utils/withSaveAsDraft.jsx +241 -0
  137. package/src/middleware/Api.test.js +4 -0
  138. package/src/middleware/api.js +74 -25
  139. package/src/routes.js +1 -1
  140. package/src/server.jsx +5 -6
  141. package/src/start-client.jsx +0 -4
  142. package/test-setup-config.jsx +0 -2
  143. package/theme/themes/pastanaga/collections/table.overrides +9 -0
  144. package/theme/themes/pastanaga/extras/blocks.less +7 -0
  145. package/theme/themes/pastanaga/extras/contents.less +5 -5
  146. package/theme/themes/pastanaga/extras/main.less +15 -0
  147. package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
  148. package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
  149. package/types/helpers/LanguageMap/LanguageMap.d.ts +428 -4
  150. package/types/helpers/Utils/withSaveAsDraft.d.ts +1 -0
  151. package/types/middleware/api.d.ts +6 -9
  152. package/src/actions/content/content.multilingual.test.js +0 -17
@@ -12,6 +12,8 @@ import {
12
12
  SYSTEM_INFORMATION,
13
13
  DATABASE_INFORMATION,
14
14
  } from '@plone/volto/constants/ActionTypes';
15
+ import { getSite } from '@plone/volto/actions/site/site';
16
+
15
17
  /**
16
18
  * Get controlpanel function.
17
19
  * @function getControlpanel
@@ -86,13 +88,17 @@ export function listControlpanels() {
86
88
  * @returns {Object} Update controlpanel action.
87
89
  */
88
90
  export function updateControlpanel(url, data) {
89
- return {
90
- type: UPDATE_CONTROLPANEL,
91
- request: {
92
- op: 'patch',
93
- path: url,
94
- data,
95
- },
91
+ return (dispatch) => {
92
+ dispatch({
93
+ type: UPDATE_CONTROLPANEL,
94
+ request: {
95
+ op: 'patch',
96
+ path: url,
97
+ data,
98
+ },
99
+ }).then(() => {
100
+ dispatch(getSite());
101
+ });
96
102
  };
97
103
  }
98
104
 
@@ -35,12 +35,18 @@ describe('Controlpanels action', () => {
35
35
  it('should create an action to update a controlpanel', () => {
36
36
  const url = 'http://localhost';
37
37
  const data = 'Hello World!';
38
- const action = updateControlpanel(url, data);
39
38
 
40
- expect(action.type).toEqual(UPDATE_CONTROLPANEL);
41
- expect(action.request.op).toEqual('patch');
42
- expect(action.request.path).toEqual(url);
43
- expect(action.request.data).toEqual(data);
39
+ const dispatch = vi.fn().mockResolvedValue();
40
+ updateControlpanel(url, data)(dispatch);
41
+
42
+ expect(dispatch).toHaveBeenCalledWith({
43
+ type: UPDATE_CONTROLPANEL,
44
+ request: {
45
+ op: 'patch',
46
+ path: url,
47
+ data,
48
+ },
49
+ });
44
50
  });
45
51
  });
46
52
  });
@@ -3,7 +3,7 @@
3
3
  * @module actions/users/users
4
4
  */
5
5
 
6
- import { stringify } from 'query-string';
6
+ import qs from 'query-string';
7
7
 
8
8
  import {
9
9
  CREATE_USER,
@@ -92,7 +92,7 @@ export function listUsers(options = {}) {
92
92
 
93
93
  let filterarg =
94
94
  groups_filter.length > 0
95
- ? stringify(
95
+ ? qs.stringify(
96
96
  { 'groups-filter': groups_filter },
97
97
  { arrayFormat: 'colon-list-separator' },
98
98
  )
@@ -223,11 +223,10 @@ class Add extends Component {
223
223
  ? keys(this.props.schema.definitions)
224
224
  : null,
225
225
  '@type': this.props.type,
226
- ...(config.settings.isMultilingual &&
227
- this.props.location?.state?.translationOf && {
228
- translation_of: this.props.location.state.translationOf,
229
- language: this.props.location.state.language,
230
- }),
226
+ ...(this.props.location?.state?.translationOf && {
227
+ translation_of: this.props.location.state.translationOf,
228
+ language: this.props.location.state.language,
229
+ }),
231
230
  });
232
231
  }
233
232
 
@@ -348,7 +347,7 @@ class Add extends Component {
348
347
  <div id="page-add">
349
348
  <Helmet
350
349
  title={this.props.intl.formatMessage(messages.add, {
351
- type: this.props.type,
350
+ type: this.props?.schema?.title || this.props.type,
352
351
  })}
353
352
  />
354
353
  <Form
@@ -187,6 +187,7 @@ export class Edit extends Component {
187
187
  selected: this.props.selected || this.props.multiSelected,
188
188
  multiSelected: this.props.multiSelected,
189
189
  hovered: this.props.hovered === this.props.id,
190
+ error: !!this.props.blocksErrors?.[this.props.id],
190
191
  })}
191
192
  style={{ outline: 'none' }}
192
193
  ref={this.blockNode}
@@ -22,9 +22,13 @@ const messages = defineMessages({
22
22
  id: 'Description',
23
23
  defaultMessage: 'Description',
24
24
  },
25
- head_title: {
25
+ kicker: {
26
26
  id: 'head_title',
27
- defaultMessage: 'Head title',
27
+ defaultMessage: 'Kicker',
28
+ },
29
+ kicker_description: {
30
+ id: 'The kicker is a line of text shown above the title.',
31
+ defaultMessage: 'The kicker is a line of text shown above the title.',
28
32
  },
29
33
  teaser: {
30
34
  id: 'Teaser',
@@ -88,7 +92,8 @@ export const TeaserSchema = ({ data, intl }) => {
88
92
  title: intl.formatMessage(messages.title),
89
93
  },
90
94
  head_title: {
91
- title: intl.formatMessage(messages.head_title),
95
+ title: intl.formatMessage(messages.kicker),
96
+ description: intl.formatMessage(messages.kicker_description),
92
97
  },
93
98
  description: {
94
99
  title: intl.formatMessage(messages.description),
@@ -77,8 +77,14 @@ export const TitleBlockEdit = (props) => {
77
77
  ReactEditor.focus(editor);
78
78
  } else {
79
79
  // nothing is selected, move focus to end
80
- ReactEditor.focus(editor);
81
- Transforms.select(editor, Editor.end(editor, []));
80
+ // make sure that the editor is focused
81
+ setTimeout(() => {
82
+ const focused = ReactEditor.focus(editor);
83
+ if (!focused) {
84
+ ReactEditor.focus(editor);
85
+ Transforms.select(editor, Editor.end(editor, []));
86
+ }
87
+ }, 0);
82
88
  }
83
89
  }
84
90
  }, [prevSelected, selected, editor]);
@@ -1161,6 +1161,9 @@ class Contents extends Component {
1161
1161
  onOk={this.onDeleteOk}
1162
1162
  items={this.state.items}
1163
1163
  itemsToDelete={this.state.itemsToDelete}
1164
+ hasMultiplePages={
1165
+ Math.ceil(this.props.total / this.state.pageSize) > 1
1166
+ }
1164
1167
  />
1165
1168
  <ContentsUploadModal
1166
1169
  open={this.state.showUpload}
@@ -105,6 +105,13 @@ describe('Contents', () => {
105
105
  Type: 'Type',
106
106
  },
107
107
  },
108
+ navroot: {
109
+ data: {
110
+ navroot: {
111
+ '@type': 'Plone Site',
112
+ },
113
+ },
114
+ },
108
115
  });
109
116
  const { container } = render(
110
117
  <Provider store={store}>
@@ -3,14 +3,9 @@ import renderer from 'react-test-renderer';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import { MemoryRouter } from 'react-router-dom';
6
- import config from '@plone/volto/registry';
7
6
 
8
7
  import ContentsBreadcrumbs from './ContentsBreadcrumbs';
9
8
 
10
- beforeAll(() => {
11
- config.settings.isMultilingual = true;
12
- });
13
-
14
9
  const mockStore = configureStore();
15
10
 
16
11
  describe('ContentsBreadcrumbs Multilingual', () => {
@@ -24,6 +19,15 @@ describe('ContentsBreadcrumbs Multilingual', () => {
24
19
  locale: 'en',
25
20
  messages: {},
26
21
  },
22
+ navroot: {
23
+ data: {
24
+ navroot: {
25
+ '@type': 'LRF',
26
+ '@id': '/en',
27
+ title: 'English',
28
+ },
29
+ },
30
+ },
27
31
  });
28
32
  const component = renderer.create(
29
33
  <Provider store={store}>
@@ -49,6 +53,15 @@ describe('ContentsBreadcrumbs Multilingual', () => {
49
53
  locale: 'en',
50
54
  messages: {},
51
55
  },
56
+ navroot: {
57
+ data: {
58
+ navroot: {
59
+ '@type': 'LRF',
60
+ '@id': '/en',
61
+ title: 'English',
62
+ },
63
+ },
64
+ },
52
65
  });
53
66
  const component = renderer.create(
54
67
  <Provider store={store}>
@@ -1,13 +1,11 @@
1
1
  import React from 'react';
2
2
  import { Breadcrumb } from 'semantic-ui-react';
3
- import { Link, useLocation } from 'react-router-dom';
3
+ import { Link } from 'react-router-dom';
4
4
  import { defineMessages, useIntl } from 'react-intl';
5
- import langmap from '@plone/volto/helpers/LanguageMap/LanguageMap';
5
+ import { useSelector } from 'react-redux';
6
6
  import ContentsBreadcrumbsRootItem from '@plone/volto/components/manage/Contents/ContentsBreadcrumbsRootItem';
7
7
  import ContentsBreadcrumbsHomeItem from '@plone/volto/components/manage/Contents/ContentsBreadcrumbsHomeItem';
8
8
 
9
- import config from '@plone/volto/registry';
10
-
11
9
  const messages = defineMessages({
12
10
  home: {
13
11
  id: 'Home',
@@ -20,15 +18,22 @@ const messages = defineMessages({
20
18
  });
21
19
 
22
20
  const ContentsBreadcrumbs = (props) => {
23
- const { settings } = config;
24
21
  const { items } = props;
25
22
  const intl = useIntl();
26
- const pathname = useLocation().pathname;
27
- const lang = pathname.split('/')[1];
23
+ const navroot = useSelector((state) => state.navroot.data.navroot);
24
+ const navrootIsPortal = navroot?.['@type'] === 'Plone Site';
28
25
 
29
26
  return (
30
27
  <Breadcrumb>
31
- {settings.isMultilingual && (
28
+ {navrootIsPortal ? (
29
+ <Link
30
+ to="/contents"
31
+ className="section"
32
+ title={intl.formatMessage(messages.home)}
33
+ >
34
+ <ContentsBreadcrumbsHomeItem />
35
+ </Link>
36
+ ) : (
32
37
  <>
33
38
  <Link
34
39
  to="/contents"
@@ -38,26 +43,15 @@ const ContentsBreadcrumbs = (props) => {
38
43
  <ContentsBreadcrumbsRootItem />
39
44
  </Link>
40
45
  <Breadcrumb.Divider />
46
+ <Link
47
+ to={`${navroot['@id']}/contents`}
48
+ className="section"
49
+ title={navroot.title}
50
+ >
51
+ {navroot.title}
52
+ </Link>
41
53
  </>
42
54
  )}
43
- {settings.isMultilingual && pathname?.split('/')?.length > 2 && (
44
- <Link
45
- to={`/${lang}/contents`}
46
- className="section"
47
- title={intl.formatMessage(messages.home)}
48
- >
49
- {langmap?.[lang]?.nativeName ?? lang}
50
- </Link>
51
- )}
52
- {!settings.isMultilingual && (
53
- <Link
54
- to="/contents"
55
- className="section"
56
- title={intl.formatMessage(messages.home)}
57
- >
58
- <ContentsBreadcrumbsHomeItem />
59
- </Link>
60
- )}
61
55
  {items.map((breadcrumb, index, breadcrumbs) => [
62
56
  <Breadcrumb.Divider key={`divider-${breadcrumb.url}`} />,
63
57
  index < breadcrumbs.length - 1 ? (
@@ -19,6 +19,13 @@ describe('ContentsBreadcrumbs', () => {
19
19
  locale: 'en',
20
20
  messages: {},
21
21
  },
22
+ navroot: {
23
+ data: {
24
+ navroot: {
25
+ '@type': 'Plone Site',
26
+ },
27
+ },
28
+ },
22
29
  });
23
30
  const component = renderer.create(
24
31
  <Provider store={store}>
@@ -44,6 +51,13 @@ describe('ContentsBreadcrumbs', () => {
44
51
  locale: 'en',
45
52
  messages: {},
46
53
  },
54
+ navroot: {
55
+ data: {
56
+ navroot: {
57
+ '@type': 'Plone Site',
58
+ },
59
+ },
60
+ },
47
61
  });
48
62
  const component = renderer.create(
49
63
  <Provider store={store}>