@plone/volto 17.0.0-alpha.25 → 17.0.0-alpha.26

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 (95) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +52 -5
  3. package/README.md +8 -7
  4. package/cypress/support/commands.js +12 -9
  5. package/cypress.config.js +1 -0
  6. package/locales/ca/LC_MESSAGES/volto.po +36 -15
  7. package/locales/ca.json +1 -1
  8. package/locales/de/LC_MESSAGES/volto.po +36 -15
  9. package/locales/de.json +1 -1
  10. package/locales/en/LC_MESSAGES/volto.po +35 -14
  11. package/locales/en.json +1 -1
  12. package/locales/es/LC_MESSAGES/volto.po +65 -44
  13. package/locales/es.json +1 -1
  14. package/locales/eu/LC_MESSAGES/volto.po +35 -14
  15. package/locales/eu.json +1 -1
  16. package/locales/fi/LC_MESSAGES/volto.po +35 -14
  17. package/locales/fi.json +1 -1
  18. package/locales/fr/LC_MESSAGES/volto.po +36 -15
  19. package/locales/fr.json +1 -1
  20. package/locales/it/LC_MESSAGES/volto.po +35 -14
  21. package/locales/it.json +1 -1
  22. package/locales/ja/LC_MESSAGES/volto.po +35 -14
  23. package/locales/ja.json +1 -1
  24. package/locales/nl/LC_MESSAGES/volto.po +36 -15
  25. package/locales/nl.json +1 -1
  26. package/locales/pt/LC_MESSAGES/volto.po +36 -15
  27. package/locales/pt.json +1 -1
  28. package/locales/pt_BR/LC_MESSAGES/volto.po +35 -14
  29. package/locales/pt_BR.json +1 -1
  30. package/locales/ro/LC_MESSAGES/volto.po +36 -15
  31. package/locales/ro.json +1 -1
  32. package/locales/volto.pot +35 -14
  33. package/locales/zh_CN/LC_MESSAGES/volto.po +36 -15
  34. package/locales/zh_CN.json +1 -1
  35. package/package.json +4 -4
  36. package/packages/volto-slate/package.json +1 -1
  37. package/packages/volto-slate/src/editor/render.jsx +2 -3
  38. package/src/actions/index.js +3 -0
  39. package/src/actions/navroot/navroot.js +16 -0
  40. package/src/actions/navroot/navroot.test.js +15 -0
  41. package/src/actions/site/site.js +16 -0
  42. package/src/actions/site/site.test.js +15 -0
  43. package/src/actions/userSession/userSession.js +17 -1
  44. package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
  45. package/src/components/manage/Blocks/Block/Settings.test.jsx +90 -0
  46. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +1 -1
  47. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +42 -25
  48. package/src/components/manage/Blocks/ToC/View.jsx +75 -13
  49. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +2 -12
  50. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
  51. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +1 -1
  52. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
  53. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +95 -5
  54. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +116 -103
  55. package/src/components/manage/Form/BlockDataForm.jsx +3 -2
  56. package/src/components/manage/Form/BlockDataForm.test.jsx +34 -2
  57. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +4 -1
  58. package/src/components/manage/Messages/Messages.jsx +32 -99
  59. package/src/components/manage/Messages/Messages.test.jsx +0 -1
  60. package/src/components/manage/Sharing/Sharing.jsx +39 -16
  61. package/src/components/manage/UniversalLink/UniversalLink.jsx +4 -6
  62. package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
  63. package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
  64. package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
  65. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
  66. package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
  67. package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
  68. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +37 -3
  69. package/src/components/theme/Login/Login.jsx +159 -241
  70. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
  71. package/src/components/theme/Logo/Logo.jsx +35 -29
  72. package/src/components/theme/Logo/Logo.test.jsx +135 -1
  73. package/src/components/theme/Logout/Logout.jsx +1 -1
  74. package/src/components/theme/Navigation/Navigation.jsx +86 -171
  75. package/src/components/theme/SearchWidget/SearchWidget.jsx +15 -3
  76. package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
  77. package/src/components/theme/View/View.jsx +2 -0
  78. package/src/config/ControlPanels.js +0 -1
  79. package/src/config/Widgets.jsx +2 -0
  80. package/src/config/index.js +15 -3
  81. package/src/constants/ActionTypes.js +3 -0
  82. package/src/express-middleware/images.js +1 -0
  83. package/src/helpers/MessageLabels/MessageLabels.js +26 -4
  84. package/src/helpers/Site/index.js +21 -0
  85. package/src/helpers/index.js +1 -0
  86. package/src/reducers/index.js +4 -0
  87. package/src/reducers/navroot/navroot.js +79 -0
  88. package/src/reducers/navroot/navroot.test.js +110 -0
  89. package/src/reducers/site/site.js +51 -0
  90. package/src/reducers/site/site.test.js +67 -0
  91. package/src/reducers/userSession/userSession.js +15 -1
  92. package/test-setup-config.js +1 -0
  93. package/theme/themes/pastanaga/elements/input.overrides +5 -1
  94. package/theme/themes/pastanaga/extras/login.less +3 -0
  95. package/webpack-plugins/webpack-less-plugin.js +19 -0
@@ -138,3 +138,6 @@ export const REMOVE_ALIASES = 'REMOVE_ALIASES';
138
138
  export const GET_USERSCHEMA = 'GET_USERSCHEMA';
139
139
  export const GET_UPGRADE = 'GET_UPGRADE';
140
140
  export const POST_UPGRADE = 'POST_UPGRADE';
141
+ export const RESET_LOGIN_REQUEST = 'RESET_LOGIN_REQUEST';
142
+ export const GET_SITE = 'GET_SITE';
143
+ export const GET_NAVROOT = 'GET_NAVROOT';
@@ -28,6 +28,7 @@ export default function imagesMiddleware() {
28
28
 
29
29
  middleware.all(['**/@@images/*'], imageMiddlewareFn);
30
30
  middleware.all(['/@portrait/*'], imageMiddlewareFn);
31
+ middleware.all(['/@@site-logo/*'], imageMiddlewareFn);
31
32
  middleware.id = 'imageResourcesProcessor';
32
33
  return middleware;
33
34
  }
@@ -172,6 +172,28 @@ export const messages = defineMessages({
172
172
  id: 'Roles',
173
173
  defaultMessage: 'Roles',
174
174
  },
175
+ addUserFormPasswordAndSendPasswordTogetherNotAllowed: {
176
+ id:
177
+ 'It is not allowed to define both the password and to request sending the password reset message by e-mail. You need to select one of them.',
178
+ defaultMessage:
179
+ 'It is not allowed to define both the password and to request sending the password reset message by e-mail. You need to select one of them.',
180
+ },
181
+ userSearchNoResults: {
182
+ id: 'There are no users with the searched criteria',
183
+ defaultMessage: 'There are no users with the searched criteria',
184
+ },
185
+ groupSearchNoResults: {
186
+ id: 'There are no groups with the searched criteria',
187
+ defaultMessage: 'There are no groups with the searched criteria',
188
+ },
189
+ updateUserFormTitle: {
190
+ id: 'Update User',
191
+ defaultMessage: 'Update User',
192
+ },
193
+ updateUserSuccess: {
194
+ id: 'User updated successfuly',
195
+ defaultMessage: 'User updated successfuly',
196
+ },
175
197
  updateRoles: {
176
198
  id: 'User roles updated',
177
199
  defaultMessage: 'User roles updated',
@@ -234,19 +256,19 @@ export const messages = defineMessages({
234
256
  },
235
257
  copyBlocks: {
236
258
  id: 'Copy blocks',
237
- defaultMesages: 'Copy blocks',
259
+ defaultMessage: 'Copy blocks',
238
260
  },
239
261
  cutBlocks: {
240
262
  id: 'Cut blocks',
241
- defaultMesages: 'Cut blocks',
263
+ defaultMessage: 'Cut blocks',
242
264
  },
243
265
  pasteBlocks: {
244
266
  id: 'Paste blocks',
245
- defaultMesages: 'Paste blocks',
267
+ defaultMessage: 'Paste blocks',
246
268
  },
247
269
  deleteBlocks: {
248
270
  id: 'Delete blocks',
249
- defaultMesages: 'Delete blocks',
271
+ defaultMessage: 'Delete blocks',
250
272
  },
251
273
  showAllUserButton: {
252
274
  id: 'Show All',
@@ -0,0 +1,21 @@
1
+ import { GET_SITE } from '@plone/volto/constants/ActionTypes';
2
+ import { getSite } from '@plone/volto/actions';
3
+
4
+ const getSiteAsyncPropExtender = {
5
+ path: '/',
6
+ extend: (dispatchActions) => {
7
+ if (
8
+ dispatchActions.filter((asyncAction) => asyncAction.key === GET_SITE)
9
+ .length === 0
10
+ ) {
11
+ dispatchActions.push({
12
+ key: GET_SITE,
13
+ promise: ({ location, store: { dispatch } }) =>
14
+ __SERVER__ && dispatch(getSite()),
15
+ });
16
+ }
17
+ return dispatchActions;
18
+ },
19
+ };
20
+
21
+ export { getSiteAsyncPropExtender };
@@ -121,3 +121,4 @@ export {
121
121
  getCurrentStateMapping,
122
122
  getWorkflowOptions,
123
123
  } from './Workflows/Workflows';
124
+ export { getSiteAsyncPropExtender } from './Site';
@@ -50,6 +50,8 @@ import workingCopy from './workingcopy/workingcopy';
50
50
  import transactions from './transactions/transactions';
51
51
  import upgrade from './upgrade/upgrade';
52
52
  import userschema from './userschema/userschema';
53
+ import site from './site/site';
54
+ import navroot from './navroot/navroot';
53
55
 
54
56
  /**
55
57
  * Root reducer.
@@ -105,6 +107,8 @@ const reducers = {
105
107
  workingCopy,
106
108
  transactions,
107
109
  userschema,
110
+ site,
111
+ navroot,
108
112
  };
109
113
 
110
114
  export default reducers;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Navroot reducer.
3
+ * @module reducers/navroot/navroot
4
+ */
5
+ import {
6
+ flattenToAppURL,
7
+ getBaseUrl,
8
+ hasApiExpander,
9
+ } from '@plone/volto/helpers';
10
+
11
+ import { GET_NAVROOT, GET_CONTENT } from '@plone/volto/constants/ActionTypes';
12
+
13
+ const initialState = {
14
+ error: null,
15
+ loaded: false,
16
+ loading: false,
17
+ data: {},
18
+ };
19
+
20
+ /**
21
+ * navroot reducer.
22
+ * @function navroot
23
+ * @param {Object} state Current state.
24
+ * @param {Object} action Action to be handled.
25
+ * @returns {Object} New state.
26
+ */
27
+ export default function navroot(state = initialState, action = {}) {
28
+ let hasExpander;
29
+ switch (action.type) {
30
+ case `${GET_NAVROOT}_PENDING`:
31
+ return {
32
+ ...state,
33
+ error: null,
34
+ loaded: false,
35
+ loading: true,
36
+ data: {},
37
+ };
38
+ case `${GET_CONTENT}_SUCCESS`:
39
+ hasExpander = hasApiExpander(
40
+ 'navroot',
41
+ getBaseUrl(flattenToAppURL(action.result['@id'])),
42
+ );
43
+ if (hasExpander && !action.subrequest) {
44
+ return {
45
+ ...state,
46
+ error: null,
47
+ data: action.result['@components'].navroot,
48
+ loaded: true,
49
+ loading: false,
50
+ };
51
+ }
52
+ return state;
53
+ case `${GET_NAVROOT}_SUCCESS`:
54
+ hasExpander = hasApiExpander(
55
+ 'navroot',
56
+ getBaseUrl(flattenToAppURL(action.result['@id'])),
57
+ );
58
+ if (!hasExpander) {
59
+ return {
60
+ ...state,
61
+ error: null,
62
+ loaded: true,
63
+ loading: false,
64
+ data: action.result,
65
+ };
66
+ }
67
+ return state;
68
+ case `${GET_NAVROOT}_FAIL`:
69
+ return {
70
+ ...state,
71
+ error: action.result,
72
+ loaded: false,
73
+ loading: false,
74
+ data: {},
75
+ };
76
+ default:
77
+ return state;
78
+ }
79
+ }
@@ -0,0 +1,110 @@
1
+ import { GET_CONTENT, GET_NAVROOT } from '@plone/volto/constants/ActionTypes';
2
+ import config from '@plone/volto/registry';
3
+ import navroot from './navroot';
4
+
5
+ const { settings } = config;
6
+
7
+ describe('Navroot reducer', () => {
8
+ it('should return the initial state', () => {
9
+ expect(navroot()).toEqual({
10
+ error: null,
11
+ data: {},
12
+ loaded: false,
13
+ loading: false,
14
+ });
15
+ });
16
+
17
+ it('should handle GET_NAVROOT_PENDING', () => {
18
+ expect(
19
+ navroot(undefined, {
20
+ type: `${GET_NAVROOT}_PENDING`,
21
+ }),
22
+ ).toEqual({
23
+ error: null,
24
+ data: {},
25
+ loaded: false,
26
+ loading: true,
27
+ });
28
+ });
29
+
30
+ it('should handle GET_NAVROOT_SUCCESS', () => {
31
+ expect(
32
+ navroot(undefined, {
33
+ type: `${GET_NAVROOT}_SUCCESS`,
34
+ result: {
35
+ title: 'Welcome to Plone!',
36
+ description:
37
+ 'Congratulations! You have successfully installed Plone.',
38
+ '@id': `${settings.apiPath}/front-page`,
39
+ },
40
+ }),
41
+ ).toEqual({
42
+ error: null,
43
+ data: {
44
+ '@id': `${settings.apiPath}/front-page`,
45
+ title: 'Welcome to Plone!',
46
+ description: 'Congratulations! You have successfully installed Plone.',
47
+ },
48
+
49
+ loaded: true,
50
+ loading: false,
51
+ });
52
+ });
53
+
54
+ it('should handle GET_NAVROOT_FAIL', () => {
55
+ expect(
56
+ navroot(undefined, {
57
+ type: `${GET_NAVROOT}_FAIL`,
58
+ error: 'failed',
59
+ }),
60
+ ).toEqual({
61
+ error: undefined,
62
+ data: {},
63
+ loaded: false,
64
+ loading: false,
65
+ });
66
+ });
67
+ });
68
+
69
+ describe('Navroot reducer (NAVROOT)GET_CONTENT', () => {
70
+ beforeEach(() => {
71
+ config.settings.apiExpanders = [
72
+ {
73
+ match: '',
74
+ GET_CONTENT: ['navroot'],
75
+ },
76
+ ];
77
+ });
78
+
79
+ it('should handle (NAVROOT)GET_CONTENT_SUCCESS', () => {
80
+ expect(
81
+ navroot(undefined, {
82
+ type: `${GET_CONTENT}_SUCCESS`,
83
+ result: {
84
+ '@components': {
85
+ navroot: {
86
+ navroot: {
87
+ title: 'Welcome to Plone!',
88
+ description:
89
+ 'Congratulations! You have successfully installed Plone.',
90
+ '@id': `${settings.apiPath}/front-page`,
91
+ },
92
+ },
93
+ },
94
+ },
95
+ }),
96
+ ).toEqual({
97
+ error: null,
98
+ data: {
99
+ navroot: {
100
+ '@id': `${settings.apiPath}/front-page`,
101
+ title: 'Welcome to Plone!',
102
+ description:
103
+ 'Congratulations! You have successfully installed Plone.',
104
+ },
105
+ },
106
+ loaded: true,
107
+ loading: false,
108
+ });
109
+ });
110
+ });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Site reducer.
3
+ * @module reducers/site/site
4
+ */
5
+
6
+ import { GET_SITE } from '@plone/volto/constants/ActionTypes';
7
+
8
+ const initialState = {
9
+ error: null,
10
+ loaded: false,
11
+ loading: false,
12
+ data: {},
13
+ };
14
+
15
+ /**
16
+ * Site reducer.
17
+ * @function site
18
+ * @param {Object} state Current state.
19
+ * @param {Object} action Action to be handled.
20
+ * @returns {Object} New state.
21
+ */
22
+ export default function site(state = initialState, action = {}) {
23
+ switch (action.type) {
24
+ case `${GET_SITE}_PENDING`:
25
+ return {
26
+ ...state,
27
+ error: null,
28
+ loaded: false,
29
+ loading: true,
30
+ data: {},
31
+ };
32
+ case `${GET_SITE}_SUCCESS`:
33
+ return {
34
+ ...state,
35
+ error: null,
36
+ loaded: true,
37
+ loading: false,
38
+ data: action.result,
39
+ };
40
+ case `${GET_SITE}_FAIL`:
41
+ return {
42
+ ...state,
43
+ error: action.result,
44
+ loaded: false,
45
+ loading: false,
46
+ data: {},
47
+ };
48
+ default:
49
+ return state;
50
+ }
51
+ }
@@ -0,0 +1,67 @@
1
+ import { GET_SITE } from '@plone/volto/constants/ActionTypes';
2
+ import config from '@plone/volto/registry';
3
+ import site from './site';
4
+
5
+ const { settings } = config;
6
+
7
+ describe('Site reducer', () => {
8
+ it('should return the initial state', () => {
9
+ expect(site()).toEqual({
10
+ error: null,
11
+ data: {},
12
+ loaded: false,
13
+ loading: false,
14
+ });
15
+ });
16
+
17
+ it('should handle GET_SITE_PENDING', () => {
18
+ expect(
19
+ site(undefined, {
20
+ type: `${GET_SITE}_PENDING`,
21
+ }),
22
+ ).toEqual({
23
+ error: null,
24
+ data: {},
25
+ loaded: false,
26
+ loading: true,
27
+ });
28
+ });
29
+
30
+ it('should handle GET_SITE_SUCCESS', () => {
31
+ expect(
32
+ site(undefined, {
33
+ type: `${GET_SITE}_SUCCESS`,
34
+ result: {
35
+ title: 'Welcome to Plone!',
36
+ description:
37
+ 'Congratulations! You have successfully installed Plone.',
38
+ '@id': `${settings.apiPath}/front-page`,
39
+ },
40
+ }),
41
+ ).toEqual({
42
+ error: null,
43
+ data: {
44
+ '@id': `${settings.apiPath}/front-page`,
45
+ title: 'Welcome to Plone!',
46
+ description: 'Congratulations! You have successfully installed Plone.',
47
+ },
48
+
49
+ loaded: true,
50
+ loading: false,
51
+ });
52
+ });
53
+
54
+ it('should handle GET_SITE_FAIL', () => {
55
+ expect(
56
+ site(undefined, {
57
+ type: `${GET_SITE}_FAIL`,
58
+ error: 'failed',
59
+ }),
60
+ ).toEqual({
61
+ error: undefined,
62
+ data: {},
63
+ loaded: false,
64
+ loading: false,
65
+ });
66
+ });
67
+ });
@@ -3,7 +3,12 @@
3
3
  * @module reducers/userSession/userSession
4
4
  */
5
5
 
6
- import { LOGIN, LOGIN_RENEW, LOGOUT } from '@plone/volto/constants/ActionTypes';
6
+ import {
7
+ LOGIN,
8
+ LOGIN_RENEW,
9
+ LOGOUT,
10
+ RESET_LOGIN_REQUEST,
11
+ } from '@plone/volto/constants/ActionTypes';
7
12
 
8
13
  const initialState = {
9
14
  token: null,
@@ -61,6 +66,15 @@ export default function userSession(state = initialState, action = {}) {
61
66
  ...state,
62
67
  token: null,
63
68
  };
69
+ case `${RESET_LOGIN_REQUEST}`:
70
+ return {
71
+ ...state,
72
+ login: {
73
+ loading: false,
74
+ loaded: false,
75
+ error: null,
76
+ },
77
+ };
64
78
  default:
65
79
  return state;
66
80
  }
@@ -54,6 +54,7 @@ const richtextViewSettings = {
54
54
 
55
55
  config.set('settings', {
56
56
  apiPath: 'http://localhost:8080/Plone',
57
+ publicURL: 'http://localhost:3000',
57
58
  defaultLanguage: 'en',
58
59
  supportedLanguages: ['en'],
59
60
  defaultPageSize: 25,
@@ -8,9 +8,13 @@
8
8
 
9
9
  /* This aligns the height of the field name label to the other side in case
10
10
  of an error is present, it overrides a default from SemanticUI grid definitions. */
11
- .ui.grid > .stretched.row > .column > .wrapper {
11
+ .inline.field .ui.grid > .stretched.row > .column > .wrapper {
12
12
  flex-grow: 0;
13
13
  }
14
+ /* Exception - Toolbar */
15
+ #toolbar .inline.field .ui.grid > .stretched.row > .column > .wrapper {
16
+ flex-grow: 1;
17
+ }
14
18
 
15
19
  .inline.field {
16
20
  .wrapper {
@@ -1,4 +1,7 @@
1
1
  #page-login {
2
+ display: flex;
3
+ justify-content: center;
4
+
2
5
  .help {
3
6
  a {
4
7
  &:hover,
@@ -4,6 +4,24 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
4
  const PostCssFlexBugFixes = require('postcss-flexbugs-fixes');
5
5
  const postcssLoadConfig = require('postcss-load-config');
6
6
 
7
+ const interpolateName = require('loader-utils').interpolateName;
8
+
9
+ function normalizePath(file) {
10
+ return path.sep === '\\' ? file.replace(/\\/g, '/') : file;
11
+ }
12
+
13
+ // Custom function to not use 'loaderContext._module.matchResource' in hashing CSS class name.
14
+ function getLocalIdent(loaderContext, localIdentName, localName, options) {
15
+ const relativeResourcePath = normalizePath(
16
+ path.relative(options.context, loaderContext.resourcePath),
17
+ );
18
+
19
+ // eslint-disable-next-line no-param-reassign
20
+ options.content = `${options.hashPrefix}${relativeResourcePath}\x00${localName}`;
21
+
22
+ return interpolateName(loaderContext, localIdentName, options);
23
+ }
24
+
7
25
  const hasPostCssConfig = () => {
8
26
  try {
9
27
  return !!postcssLoadConfig.sync();
@@ -52,6 +70,7 @@ const defaultOptions = {
52
70
  modules: {
53
71
  auto: true,
54
72
  localIdentName: '[name]__[local]___[hash:base64:5]',
73
+ getLocalIdent: getLocalIdent,
55
74
  },
56
75
  },
57
76
  },