@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
@@ -1,28 +1,24 @@
1
1
  import React from 'react';
2
2
  import { Redirect } from 'react-router-dom';
3
- import { useDispatch } from 'react-redux';
3
+ import { useDispatch, useSelector } from 'react-redux';
4
4
  import { useCookies } from 'react-cookie';
5
- import config from '@plone/volto/registry';
6
5
  import { changeLanguage } from '@plone/volto/actions/language/language';
7
6
  import { toGettextLang } from '@plone/volto/helpers/Utils/Utils';
8
7
 
9
8
  const MultilingualRedirector = (props) => {
10
- const { settings } = config;
11
9
  const { pathname, children } = props;
12
10
  const [cookies] = useCookies();
13
- const currentLanguage = cookies['I18N_LANGUAGE'] || settings.defaultLanguage;
14
- const redirectToLanguage = settings.supportedLanguages.includes(
15
- currentLanguage,
16
- )
17
- ? currentLanguage
18
- : settings.defaultLanguage;
11
+ const site = useSelector((state) => state.site.data);
12
+ const isMultilingual = site.features?.multilingual;
13
+ const redirectToLanguage =
14
+ cookies['I18N_LANGUAGE'] || site['plone.default_language'];
19
15
  const dispatch = useDispatch();
20
16
 
21
17
  React.useEffect(() => {
22
18
  // ToDo: Add means to support language negotiation (with config)
23
19
  // const detectedLang = (navigator.language || navigator.userLanguage).substring(0, 2);
24
20
  let mounted = true;
25
- if (settings.isMultilingual && pathname === '/') {
21
+ if (isMultilingual && pathname === '/') {
26
22
  const langFileName = toGettextLang(redirectToLanguage);
27
23
  import(
28
24
  /* @vite-ignore */ '@root/../locales/' + langFileName + '.json'
@@ -35,9 +31,9 @@ const MultilingualRedirector = (props) => {
35
31
  return () => {
36
32
  mounted = false;
37
33
  };
38
- }, [pathname, dispatch, redirectToLanguage, settings.isMultilingual]);
34
+ }, [pathname, dispatch, redirectToLanguage, isMultilingual]);
39
35
 
40
- return pathname === '/' && settings.isMultilingual ? (
36
+ return pathname === '/' && isMultilingual ? (
41
37
  <Redirect to={`/${redirectToLanguage}`} />
42
38
  ) : (
43
39
  <>{children}</>
@@ -3,19 +3,17 @@ 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 MultilingualRedirector from './MultilingualRedirector';
9
8
 
10
- beforeAll(() => {
11
- config.settings.isMultilingual = true;
12
- });
13
-
14
9
  const mockStore = configureStore();
15
10
 
16
11
  describe('MultilingualRedirector', () => {
17
12
  it('renders a MultilingualRedirector component', () => {
18
13
  const store = mockStore({
14
+ site: {
15
+ data: {},
16
+ },
19
17
  intl: {
20
18
  locale: 'en',
21
19
  messages: {},
@@ -15,11 +15,7 @@ const NavItem = ({ item, lang }) => {
15
15
  key={item.url}
16
16
  className="item"
17
17
  activeClassName="active"
18
- exact={
19
- settings.isMultilingual
20
- ? item.url === `/${toBackendLang(lang)}`
21
- : item.url === ''
22
- }
18
+ exact={item.url === '' || item.url === `/${toBackendLang(lang)}`}
23
19
  >
24
20
  {item.title}
25
21
  </NavLink>
@@ -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 Navigation from './Navigation';
9
8
 
10
- beforeAll(() => {
11
- config.settings.isMultilingual = true;
12
- });
13
-
14
9
  const mockStore = configureStore();
15
10
 
16
11
  describe('Navigation Multilingual', () => {
@@ -19,15 +19,18 @@ import config from '@plone/volto/registry';
19
19
  const NotFound = () => {
20
20
  const dispatch = useDispatch();
21
21
  const lang = useSelector((state) => state.intl.locale);
22
+ const isMultilingual = useSelector(
23
+ (state) => state.site.data.features?.multilingual,
24
+ );
22
25
 
23
26
  useEffect(() => {
24
27
  dispatch(
25
28
  getNavigation(
26
- config.settings.isMultilingual ? `/${toBackendLang(lang)}` : '/',
29
+ isMultilingual ? `/${toBackendLang(lang)}` : '/',
27
30
  config.settings.navDepth,
28
31
  ),
29
32
  );
30
- }, [dispatch, lang]);
33
+ }, [dispatch, lang, isMultilingual]);
31
34
 
32
35
  return (
33
36
  <Container className="view-wrapper">
@@ -13,6 +13,9 @@ const mockStore = configureStore();
13
13
  describe('NotFound', () => {
14
14
  it('renders a not found component', () => {
15
15
  const store = mockStore({
16
+ site: {
17
+ data: {},
18
+ },
16
19
  intl: {
17
20
  locale: 'en',
18
21
  messages: {},
@@ -36,14 +36,14 @@ function Sitemap(props) {
36
36
  location: { pathname },
37
37
  lang,
38
38
  getNavigation,
39
+ isMultilingual,
39
40
  } = props;
40
41
 
41
42
  useEffect(() => {
42
- const { settings } = config;
43
- const language = settings.isMultilingual ? `${toBackendLang(lang)}` : null;
43
+ const language = isMultilingual ? `${toBackendLang(lang)}` : null;
44
44
  const path = getSitemapPath(pathname, language);
45
45
  getNavigation(path, 4);
46
- }, [pathname, lang, getNavigation]);
46
+ }, [pathname, lang, getNavigation, isMultilingual]);
47
47
 
48
48
  const renderItems = (items) => {
49
49
  return (
@@ -100,6 +100,7 @@ export default compose(
100
100
  (state) => ({
101
101
  items: state.navigation.items,
102
102
  lang: state.intl.locale,
103
+ isMultilingual: state.site.data.features?.multilingual,
103
104
  }),
104
105
  { getNavigation },
105
106
  ),
@@ -108,10 +109,10 @@ export default compose(
108
109
  key: 'navigation',
109
110
  promise: ({ location, store: { dispatch, getState } }) => {
110
111
  if (!__SERVER__) return;
111
- const { settings } = config;
112
+ const state = getState();
112
113
  const path = getSitemapPath(
113
114
  location.pathname,
114
- settings.isMultilingual
115
+ state.site.data.features?.multilingual
115
116
  ? toBackendLang(getState().intl.locale)
116
117
  : null,
117
118
  );
@@ -58,7 +58,6 @@ describe('Sitemap', () => {
58
58
 
59
59
  describe('Sitemap in a multilingual site', () => {
60
60
  beforeEach(() => {
61
- config.settings.isMultilingual = true;
62
61
  config.settings.supportedLanguages = ['en', 'es'];
63
62
  });
64
63
  it('renders a sitemap component', () => {
@@ -7,6 +7,7 @@ import React from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import { Container as SemanticContainer } from 'semantic-ui-react';
9
9
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
10
+ import { FormattedMessage } from 'react-intl';
10
11
  import config from '@plone/volto/registry';
11
12
 
12
13
  /**
@@ -30,7 +31,14 @@ const FileView = ({ content }) => {
30
31
  )}
31
32
  {content.file?.download && (
32
33
  <a href={flattenToAppURL(content.file.download)}>
33
- {content.file.filename}
34
+ {content.file.filename ? (
35
+ content.file.filename
36
+ ) : (
37
+ <FormattedMessage
38
+ id="Download file"
39
+ defaultMessage="Download file"
40
+ />
41
+ )}
34
42
  </a>
35
43
  )}
36
44
  </Container>
@@ -25,6 +25,8 @@ import { installDefaultBlocks } from './Blocks';
25
25
  import { getSiteAsyncPropExtender } from '@plone/volto/helpers/Site';
26
26
  import { registerValidators } from './validation';
27
27
 
28
+ import languages from '@plone/volto/constants/Languages.cjs';
29
+
28
30
  const host = process.env.HOST || 'localhost';
29
31
  const port = process.env.PORT || '3000';
30
32
 
@@ -111,9 +113,7 @@ let config = {
111
113
  openExternalLinkInNewTab: false,
112
114
  notSupportedBrowsers: ['ie'],
113
115
  defaultPageSize: 25,
114
- isMultilingual: false,
115
- supportedLanguages: ['en'],
116
- defaultLanguage: process.env.SITE_DEFAULT_LANGUAGE || 'en',
116
+ supportedLanguages: Object.keys(languages),
117
117
  navDepth: 1,
118
118
  expressMiddleware: serverConfig.expressMiddleware, // BBB
119
119
  defaultBlockType: 'slate',
@@ -198,7 +198,8 @@ config.settings.apiExpanders = [
198
198
  ...config.settings.apiExpanders,
199
199
  {
200
200
  match: '',
201
- GET_CONTENT: ['breadcrumbs', 'actions', 'types', 'navroot'],
201
+ GET_CONTENT: ['breadcrumbs', 'actions', 'types', 'navroot', 'translations'],
202
+ // Note: translations is removed in the API middleware if the site is not multilingual.
202
203
  },
203
204
  {
204
205
  match: '',
@@ -232,16 +233,6 @@ Object.entries(slots).forEach(([slotName, components]) => {
232
233
  });
233
234
  });
234
235
 
235
- // Make sure that process.env.SITE_DEFAULT_LANGUAGE is set in availableLanguages
236
- if (
237
- process.env.SITE_DEFAULT_LANGUAGE &&
238
- !config.settings.supportedLanguages.includes(
239
- process.env.SITE_DEFAULT_LANGUAGE,
240
- )
241
- ) {
242
- config.settings.supportedLanguages.push(process.env.SITE_DEFAULT_LANGUAGE);
243
- }
244
-
245
236
  registerValidators(ConfigRegistry);
246
237
  installDefaultComponents(ConfigRegistry);
247
238
  installDefaultWidgets(ConfigRegistry);
@@ -122,9 +122,6 @@ class Html extends Component {
122
122
  ...(publicURL && {
123
123
  publicURL,
124
124
  }),
125
- ...(process.env.SITE_DEFAULT_LANGUAGE && {
126
- defaultLanguage: process.env.SITE_DEFAULT_LANGUAGE,
127
- }),
128
125
  })};`,
129
126
  }}
130
127
  />