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

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 (154) hide show
  1. package/.eslintrc +26 -3
  2. package/.yarn/install-state.gz +0 -0
  3. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +541 -0
  4. package/.yarn/releases/yarn-3.6.3.cjs +874 -0
  5. package/CHANGELOG.md +60 -0
  6. package/addon-registry.js +10 -1
  7. package/create-addons-loader.js +1 -1
  8. package/locales/ca/LC_MESSAGES/volto.po +57 -31
  9. package/locales/ca.json +1 -1
  10. package/locales/de/LC_MESSAGES/volto.po +58 -32
  11. package/locales/de.json +1 -1
  12. package/locales/en/LC_MESSAGES/volto.po +57 -31
  13. package/locales/en.json +1 -1
  14. package/locales/es/LC_MESSAGES/volto.po +65 -39
  15. package/locales/es.json +1 -1
  16. package/locales/eu/LC_MESSAGES/volto.po +57 -31
  17. package/locales/eu.json +1 -1
  18. package/locales/fi/LC_MESSAGES/volto.po +57 -31
  19. package/locales/fi.json +1 -1
  20. package/locales/fr/LC_MESSAGES/volto.po +57 -31
  21. package/locales/fr.json +1 -1
  22. package/locales/it/LC_MESSAGES/volto.po +57 -31
  23. package/locales/it.json +1 -1
  24. package/locales/ja/LC_MESSAGES/volto.po +57 -31
  25. package/locales/ja.json +1 -1
  26. package/locales/nl/LC_MESSAGES/volto.po +57 -31
  27. package/locales/nl.json +1 -1
  28. package/locales/pt/LC_MESSAGES/volto.po +57 -31
  29. package/locales/pt.json +1 -1
  30. package/locales/pt_BR/LC_MESSAGES/volto.po +57 -31
  31. package/locales/pt_BR.json +1 -1
  32. package/locales/ro/LC_MESSAGES/volto.po +57 -31
  33. package/locales/ro.json +1 -1
  34. package/locales/volto.pot +62 -32
  35. package/locales/zh_CN/LC_MESSAGES/volto.po +57 -31
  36. package/locales/zh_CN.json +1 -1
  37. package/package.json +35 -26
  38. package/packages/volto-slate/package.json +1 -1
  39. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +2 -1
  40. package/packages/volto-slate/src/blocks/Text/index.js +0 -5
  41. package/packages/volto-slate/src/editor/plugins/Link/render.jsx +5 -6
  42. package/packages/volto-slate/src/editor/render.jsx +11 -1
  43. package/razzle.config.js +4 -6
  44. package/src/components/index.js +194 -194
  45. package/src/components/manage/Add/Add.jsx +7 -8
  46. package/src/components/manage/Blocks/Block/Settings.test.jsx +17 -15
  47. package/src/components/manage/Blocks/HTML/Edit.jsx +8 -8
  48. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +30 -25
  49. package/src/components/manage/Blocks/Listing/ListingBody.jsx +6 -4
  50. package/src/components/manage/Blocks/Maps/Edit.test.jsx +1 -2
  51. package/src/components/manage/Blocks/Maps/View.test.jsx +1 -2
  52. package/src/components/manage/Blocks/Search/components/Facets.jsx +2 -3
  53. package/src/components/manage/Blocks/Search/components/FilterList.jsx +4 -6
  54. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +2 -9
  55. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +3 -0
  56. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +8 -6
  57. package/src/components/manage/Blocks/Search/schema.js +13 -13
  58. package/src/components/manage/Blocks/Table/Cell.jsx +2 -3
  59. package/src/components/manage/Blocks/Text/Edit.jsx +2 -3
  60. package/src/components/manage/Blocks/Title/View.jsx +4 -37
  61. package/src/components/manage/Blocks/ToC/View.jsx +1 -0
  62. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +3 -2
  63. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +3 -2
  64. package/src/components/manage/Contents/Contents.jsx +252 -114
  65. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +90 -154
  66. package/src/components/manage/Contents/ContentsRenameModal.jsx +88 -139
  67. package/src/components/manage/Contents/ContentsRenameModal.stories.jsx +61 -0
  68. package/src/components/manage/Contents/ContentsTagsModal.jsx +83 -130
  69. package/src/components/manage/Contents/ContentsTagsModal.stories.jsx +68 -0
  70. package/src/components/manage/Contents/ContentsUploadModal.jsx +1 -2
  71. package/src/components/manage/Contents/ContentsWorkflowModal.jsx +87 -154
  72. package/src/components/manage/Controlpanels/Aliases.jsx +4 -12
  73. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +2 -9
  74. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +6 -9
  75. package/src/components/manage/Form/BlockDataForm.test.jsx +17 -15
  76. package/src/components/manage/Form/Form.jsx +2 -3
  77. package/src/components/manage/Form/InlineForm.test.jsx +16 -14
  78. package/src/components/manage/LockingToastsFactory/LockingToastsFactory.jsx +1 -2
  79. package/src/components/manage/Sharing/Sharing.jsx +7 -0
  80. package/src/components/manage/Sidebar/Sidebar.jsx +139 -220
  81. package/src/components/manage/Toolbar/More.jsx +12 -12
  82. package/src/components/manage/Toolbar/PersonalTools.jsx +97 -155
  83. package/src/components/manage/Toolbar/Toolbar.jsx +2 -2
  84. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +2 -1
  85. package/src/components/manage/Widgets/AlignWidget.jsx +2 -4
  86. package/src/components/manage/Widgets/ColorPickerWidget.test.jsx +9 -7
  87. package/src/components/manage/Widgets/DatetimeWidget.jsx +2 -8
  88. package/src/components/manage/Widgets/IdWidget.jsx +1 -2
  89. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +2 -9
  90. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +2 -9
  91. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +4 -4
  92. package/src/components/manage/Widgets/SchemaWidget.jsx +6 -9
  93. package/src/components/manage/Widgets/WysiwygWidget.jsx +2 -9
  94. package/src/components/theme/Comments/Comments.jsx +3 -10
  95. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +4 -0
  96. package/src/components/theme/Login/Login.jsx +1 -2
  97. package/src/components/theme/PasswordReset/PasswordReset.jsx +1 -2
  98. package/src/components/theme/PreviewImage/PreviewImage.jsx +10 -5
  99. package/src/components/theme/PreviewImage/PreviewImage.test.js +17 -0
  100. package/src/components/theme/Register/Register.jsx +2 -4
  101. package/src/components/theme/TsTest/TsTest.test.tsx +11 -0
  102. package/src/components/theme/TsTest/TsTest.tsx +15 -0
  103. package/src/components/theme/View/AlbumView.jsx +3 -2
  104. package/src/components/theme/Widgets/ImageWidget.stories.jsx +1 -2
  105. package/src/config/Loadables.jsx +1 -1
  106. package/src/config/RichTextEditor/Blocks.jsx +2 -3
  107. package/src/config/RichTextEditor/Plugins.jsx +2 -3
  108. package/src/config/RichTextEditor/ToHTML.jsx +12 -10
  109. package/src/config/RichTextEditor/index.js +2 -3
  110. package/src/config/Views.jsx +5 -5
  111. package/src/express-middleware/ok.js +1 -1
  112. package/src/helpers/Blocks/Blocks.js +4 -6
  113. package/src/helpers/Blocks/Blocks.test.js +35 -35
  114. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +48 -50
  115. package/src/helpers/FormValidation/FormValidation.js +7 -6
  116. package/src/helpers/Html/Html.jsx +2 -8
  117. package/src/helpers/Loadable/__mocks__/Loadable.js +18 -18
  118. package/src/helpers/MessageLabels/MessageLabels.js +2 -3
  119. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +2 -3
  120. package/src/helpers/Utils/Utils.js +10 -0
  121. package/src/helpers/Utils/Utils.test.js +13 -0
  122. package/src/helpers/index.js +1 -0
  123. package/src/hooks/index.js +1 -1
  124. package/src/middleware/api.js +194 -190
  125. package/src/middleware/blacklistRoutes.js +25 -22
  126. package/src/middleware/storeProtectLoadUtils.js +61 -62
  127. package/src/middleware/storeProtectLoadUtils.test.js +47 -43
  128. package/src/reducers/content/content.test.js +4 -4
  129. package/src/reducers/navigation/navigation.js +5 -5
  130. package/src/reducers/navigation/navigation.test.js +30 -0
  131. package/src/registry.js +2 -2
  132. package/src/storybook.jsx +24 -38
  133. package/theme/themes/pastanaga/collections/menu.overrides +3 -2
  134. package/theme/themes/pastanaga/elements/container.overrides +5 -2
  135. package/theme/themes/pastanaga/elements/input.overrides +1 -1
  136. package/theme/themes/pastanaga/elements/step.overrides +2 -1
  137. package/theme/themes/pastanaga/extras/blocks.less +20 -14
  138. package/theme/themes/pastanaga/extras/color-picker-widget.less +1 -1
  139. package/theme/themes/pastanaga/extras/contents.less +5 -1
  140. package/theme/themes/pastanaga/extras/draftjs.less +4 -4
  141. package/theme/themes/pastanaga/extras/grid.less +5 -4
  142. package/theme/themes/pastanaga/extras/main.less +6 -6
  143. package/theme/themes/pastanaga/extras/react-dates-overrides.less +4 -2
  144. package/theme/themes/pastanaga/extras/search.less +2 -2
  145. package/theme/themes/pastanaga/extras/sidebar.less +5 -4
  146. package/theme/themes/pastanaga/extras/time-picker-overrides.less +5 -3
  147. package/theme/themes/pastanaga/extras/toolbar.less +6 -2
  148. package/theme/themes/pastanaga/extras/userscontrolpanel.less +17 -9
  149. package/theme/themes/pastanaga/extras/widgets.less +1 -1
  150. package/theme/themes/pastanaga/modules/rating.overrides +2 -1
  151. package/theme/themes/pastanaga-cms-ui/elements/container.overrides +2 -1
  152. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.elements.container.less +6 -2
  153. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.site.less +2 -2
  154. package/tsconfig.json +33 -0
@@ -125,58 +125,76 @@ function sendOnSocket(request) {
125
125
  * @param {Object} api Api object.
126
126
  * @returns {Promise} Action promise.
127
127
  */
128
- const apiMiddlewareFactory = (api) => ({ dispatch, getState }) => (next) => (
129
- action,
130
- ) => {
131
- const { settings } = config;
128
+ const apiMiddlewareFactory =
129
+ (api) =>
130
+ ({ dispatch, getState }) =>
131
+ (next) =>
132
+ (action) => {
133
+ const { settings } = config;
132
134
 
133
- const token = getState().userSession.token;
134
- let isAnonymous = true;
135
- if (token) {
136
- const tokenExpiration = jwtDecode(token).exp;
137
- const currentTime = new Date().getTime() / 1000;
138
- isAnonymous = !token || currentTime > tokenExpiration;
139
- }
135
+ const token = getState().userSession.token;
136
+ let isAnonymous = true;
137
+ if (token) {
138
+ const tokenExpiration = jwtDecode(token).exp;
139
+ const currentTime = new Date().getTime() / 1000;
140
+ isAnonymous = !token || currentTime > tokenExpiration;
141
+ }
140
142
 
141
- if (typeof action === 'function') {
142
- return action(dispatch, getState);
143
- }
143
+ if (typeof action === 'function') {
144
+ return action(dispatch, getState);
145
+ }
144
146
 
145
- const { request, type, mode = 'parallel', ...rest } = action;
146
- const { subrequest } = action; // We want subrequest remains in `...rest` above
147
+ const { request, type, mode = 'parallel', ...rest } = action;
148
+ const { subrequest } = action; // We want subrequest remains in `...rest` above
147
149
 
148
- let actionPromise;
150
+ let actionPromise;
149
151
 
150
- if (!request) {
151
- return next(action);
152
- }
152
+ if (!request) {
153
+ return next(action);
154
+ }
153
155
 
154
- next({ ...rest, type: `${type}_PENDING` });
156
+ next({ ...rest, type: `${type}_PENDING` });
155
157
 
156
- if (socket) {
157
- actionPromise = Array.isArray(request)
158
- ? Promise.all(
159
- request.map((item) =>
160
- sendOnSocket({
161
- ...item,
162
- path: addExpandersToPath(item.path, type, isAnonymous),
163
- id: type,
164
- }),
165
- ),
166
- )
167
- : sendOnSocket({
168
- ...request,
169
- path: addExpandersToPath(request.path, type, isAnonymous),
170
- id: type,
171
- });
172
- } else {
173
- actionPromise = Array.isArray(request)
174
- ? mode === 'serial'
175
- ? request.reduce((prevPromise, item) => {
176
- return prevPromise.then((acc) => {
177
- return api[item.op](
178
- addExpandersToPath(item.path, type, isAnonymous),
179
- {
158
+ if (socket) {
159
+ actionPromise = Array.isArray(request)
160
+ ? Promise.all(
161
+ request.map((item) =>
162
+ sendOnSocket({
163
+ ...item,
164
+ path: addExpandersToPath(item.path, type, isAnonymous),
165
+ id: type,
166
+ }),
167
+ ),
168
+ )
169
+ : sendOnSocket({
170
+ ...request,
171
+ path: addExpandersToPath(request.path, type, isAnonymous),
172
+ id: type,
173
+ });
174
+ } else {
175
+ actionPromise = Array.isArray(request)
176
+ ? mode === 'serial'
177
+ ? request.reduce((prevPromise, item) => {
178
+ return prevPromise.then((acc) => {
179
+ return api[item.op](
180
+ addExpandersToPath(item.path, type, isAnonymous),
181
+ {
182
+ data: item.data,
183
+ type: item.type,
184
+ headers: item.headers,
185
+ params: request.params,
186
+ checkUrl: settings.actions_raising_api_errors.includes(
187
+ action.type,
188
+ ),
189
+ },
190
+ ).then((reqres) => {
191
+ return [...acc, reqres];
192
+ });
193
+ });
194
+ }, Promise.resolve([]))
195
+ : Promise.all(
196
+ request.map((item) =>
197
+ api[item.op](addExpandersToPath(item.path, type, isAnonymous), {
180
198
  data: item.data,
181
199
  type: item.type,
182
200
  headers: item.headers,
@@ -184,176 +202,162 @@ const apiMiddlewareFactory = (api) => ({ dispatch, getState }) => (next) => (
184
202
  checkUrl: settings.actions_raising_api_errors.includes(
185
203
  action.type,
186
204
  ),
187
- },
188
- ).then((reqres) => {
189
- return [...acc, reqres];
190
- });
191
- });
192
- }, Promise.resolve([]))
193
- : Promise.all(
194
- request.map((item) =>
195
- api[item.op](addExpandersToPath(item.path, type, isAnonymous), {
196
- data: item.data,
197
- type: item.type,
198
- headers: item.headers,
199
- params: request.params,
200
- checkUrl: settings.actions_raising_api_errors.includes(
201
- action.type,
202
- ),
203
- }),
204
- ),
205
- )
206
- : api[request.op](addExpandersToPath(request.path, type, isAnonymous), {
207
- data: request.data,
208
- type: request.type,
209
- headers: request.headers,
210
- params: request.params,
211
- checkUrl: settings.actions_raising_api_errors.includes(action.type),
212
- });
213
- actionPromise.then(
214
- (result) => {
215
- const { settings } = config;
216
- if (getState().apierror.connectionRefused) {
217
- next({
218
- ...rest,
219
- type: RESET_APIERROR,
205
+ }),
206
+ ),
207
+ )
208
+ : api[request.op](addExpandersToPath(request.path, type, isAnonymous), {
209
+ data: request.data,
210
+ type: request.type,
211
+ headers: request.headers,
212
+ params: request.params,
213
+ checkUrl: settings.actions_raising_api_errors.includes(action.type),
220
214
  });
221
- }
222
- if (type === GET_CONTENT) {
223
- const lang = result?.language?.token;
224
- if (
225
- lang &&
226
- getState().intl.locale !== toReactIntlLang(lang) &&
227
- !subrequest &&
228
- config.settings.supportedLanguages.includes(lang)
229
- ) {
230
- const langFileName = toGettextLang(lang);
231
- import('~/../locales/' + langFileName + '.json').then((locale) => {
232
- dispatch(changeLanguage(lang, locale.default));
215
+ actionPromise.then(
216
+ (result) => {
217
+ const { settings } = config;
218
+ if (getState().apierror.connectionRefused) {
219
+ next({
220
+ ...rest,
221
+ type: RESET_APIERROR,
233
222
  });
234
223
  }
235
- }
236
- if (type === LOGIN && settings.websockets) {
237
- const cookies = new Cookies();
238
- cookies.set(
239
- 'auth_token',
240
- result.token,
241
- getCookieOptions({
242
- expires: new Date(jwtDecode(result.token).exp * 1000),
243
- }),
244
- );
245
- api.get('/@wstoken').then((res) => {
246
- socket = new WebSocket(
247
- `${settings.apiPath.replace('http', 'ws')}/@ws?ws_token=${
248
- res.token
249
- }`,
224
+ if (type === GET_CONTENT) {
225
+ const lang = result?.language?.token;
226
+ if (
227
+ lang &&
228
+ getState().intl.locale !== toReactIntlLang(lang) &&
229
+ !subrequest &&
230
+ config.settings.supportedLanguages.includes(lang)
231
+ ) {
232
+ const langFileName = toGettextLang(lang);
233
+ import('~/../locales/' + langFileName + '.json').then(
234
+ (locale) => {
235
+ dispatch(changeLanguage(lang, locale.default));
236
+ },
237
+ );
238
+ }
239
+ }
240
+ if (type === LOGIN && settings.websockets) {
241
+ const cookies = new Cookies();
242
+ cookies.set(
243
+ 'auth_token',
244
+ result.token,
245
+ getCookieOptions({
246
+ expires: new Date(jwtDecode(result.token).exp * 1000),
247
+ }),
250
248
  );
251
- socket.onmessage = (message) => {
252
- const packet = JSON.parse(message.data);
253
- if (packet.error) {
254
- dispatch({
255
- type: `${packet.id}_FAIL`,
256
- error: packet.error,
257
- });
258
- } else {
259
- dispatch({
260
- type: `${packet.id}_SUCCESS`,
261
- result: JSON.parse(packet.data),
262
- });
263
- }
264
- };
265
- });
266
- }
267
- try {
268
- return next({ ...rest, result, type: `${type}_SUCCESS` });
269
- } catch (error) {
270
- // There was an exception while processing reducers or downstream middleware.
271
- next({
272
- ...rest,
273
- error: { status: 500, error },
274
- type: `${type}_FAIL`,
275
- });
276
- // Rethrow the original exception on the client side only,
277
- // so it doesn't fall through to express on the server.
278
- if (__CLIENT__) throw error;
279
- }
280
- },
281
- (error) => {
282
- // Only SSR can set ECONNREFUSED
283
- if (error.code === 'ECONNREFUSED') {
284
- next({
285
- ...rest,
286
- error,
287
- statusCode: error.code,
288
- connectionRefused: true,
289
- type: SET_APIERROR,
290
- });
291
- }
292
-
293
- // Response error is marked crossDomain if CORS error happen
294
- else if (error.crossDomain) {
295
- next({
296
- ...rest,
297
- error,
298
- statusCode: 'CORSERROR',
299
- connectionRefused: false,
300
- type: SET_APIERROR,
301
- });
302
- }
303
-
304
- // Check for actions who can raise api errors
305
- if (settings.actions_raising_api_errors.includes(action.type)) {
306
- // Gateway timeout
307
- if (error?.response?.statusCode === 504) {
308
- next({
309
- ...rest,
310
- error,
311
- statusCode: error.code,
312
- connectionRefused: true,
313
- type: SET_APIERROR,
249
+ api.get('/@wstoken').then((res) => {
250
+ socket = new WebSocket(
251
+ `${settings.apiPath.replace('http', 'ws')}/@ws?ws_token=${
252
+ res.token
253
+ }`,
254
+ );
255
+ socket.onmessage = (message) => {
256
+ const packet = JSON.parse(message.data);
257
+ if (packet.error) {
258
+ dispatch({
259
+ type: `${packet.id}_FAIL`,
260
+ error: packet.error,
261
+ });
262
+ } else {
263
+ dispatch({
264
+ type: `${packet.id}_SUCCESS`,
265
+ result: JSON.parse(packet.data),
266
+ });
267
+ }
268
+ };
314
269
  });
315
270
  }
316
-
317
- // Redirect
318
- else if (error?.code === 301) {
271
+ try {
272
+ return next({ ...rest, result, type: `${type}_SUCCESS` });
273
+ } catch (error) {
274
+ // There was an exception while processing reducers or downstream middleware.
319
275
  next({
320
276
  ...rest,
321
- error,
322
- statusCode: error.code,
323
- connectionRefused: false,
324
- type: SET_APIERROR,
277
+ error: { status: 500, error },
278
+ type: `${type}_FAIL`,
325
279
  });
280
+ // Rethrow the original exception on the client side only,
281
+ // so it doesn't fall through to express on the server.
282
+ if (__CLIENT__) throw error;
326
283
  }
327
-
328
- // Redirect
329
- else if (error?.code === 408) {
284
+ },
285
+ (error) => {
286
+ // Only SSR can set ECONNREFUSED
287
+ if (error.code === 'ECONNREFUSED') {
330
288
  next({
331
289
  ...rest,
332
290
  error,
333
291
  statusCode: error.code,
334
- connectionRefused: false,
292
+ connectionRefused: true,
335
293
  type: SET_APIERROR,
336
294
  });
337
295
  }
338
296
 
339
- // Unauthorized
340
- else if (error?.response?.statusCode === 401) {
297
+ // Response error is marked crossDomain if CORS error happen
298
+ else if (error.crossDomain) {
341
299
  next({
342
300
  ...rest,
343
301
  error,
344
- statusCode: error.response,
345
- message: error.response.body.message,
302
+ statusCode: 'CORSERROR',
346
303
  connectionRefused: false,
347
304
  type: SET_APIERROR,
348
305
  });
349
306
  }
350
- }
351
- return next({ ...rest, error, type: `${type}_FAIL` });
352
- },
353
- );
354
- }
355
307
 
356
- return actionPromise;
357
- };
308
+ // Check for actions who can raise api errors
309
+ if (settings.actions_raising_api_errors.includes(action.type)) {
310
+ // Gateway timeout
311
+ if (error?.response?.statusCode === 504) {
312
+ next({
313
+ ...rest,
314
+ error,
315
+ statusCode: error.code,
316
+ connectionRefused: true,
317
+ type: SET_APIERROR,
318
+ });
319
+ }
320
+
321
+ // Redirect
322
+ else if (error?.code === 301) {
323
+ next({
324
+ ...rest,
325
+ error,
326
+ statusCode: error.code,
327
+ connectionRefused: false,
328
+ type: SET_APIERROR,
329
+ });
330
+ }
331
+
332
+ // Redirect
333
+ else if (error?.code === 408) {
334
+ next({
335
+ ...rest,
336
+ error,
337
+ statusCode: error.code,
338
+ connectionRefused: false,
339
+ type: SET_APIERROR,
340
+ });
341
+ }
342
+
343
+ // Unauthorized
344
+ else if (error?.response?.statusCode === 401) {
345
+ next({
346
+ ...rest,
347
+ error,
348
+ statusCode: error.response,
349
+ message: error.response.body.message,
350
+ connectionRefused: false,
351
+ type: SET_APIERROR,
352
+ });
353
+ }
354
+ }
355
+ return next({ ...rest, error, type: `${type}_FAIL` });
356
+ },
357
+ );
358
+ }
359
+
360
+ return actionPromise;
361
+ };
358
362
 
359
363
  export default apiMiddlewareFactory;
@@ -1,31 +1,34 @@
1
1
  import config from '@plone/volto/registry';
2
2
  import { matchPath } from 'react-router';
3
3
 
4
- const blacklistRoutes = ({ dispatch, getState }) => (next) => (action) => {
5
- if (typeof action === 'function') {
6
- return next(action);
7
- }
4
+ const blacklistRoutes =
5
+ ({ dispatch, getState }) =>
6
+ (next) =>
7
+ (action) => {
8
+ if (typeof action === 'function') {
9
+ return next(action);
10
+ }
8
11
 
9
- switch (action.type) {
10
- case '@@router/LOCATION_CHANGE':
11
- const { pathname } = action.payload.location;
12
- const { externalRoutes = [] } = config.settings;
12
+ switch (action.type) {
13
+ case '@@router/LOCATION_CHANGE':
14
+ const { pathname } = action.payload.location;
15
+ const { externalRoutes = [] } = config.settings;
13
16
 
14
- const route = externalRoutes.find((route) =>
15
- matchPath(pathname, route.match),
16
- );
17
+ const route = externalRoutes.find((route) =>
18
+ matchPath(pathname, route.match),
19
+ );
17
20
 
18
- if (!route) {
21
+ if (!route) {
22
+ return next(action);
23
+ } else {
24
+ window.location.replace(
25
+ route.url ? route.url(action.payload) : pathname,
26
+ );
27
+ }
28
+ break;
29
+ default:
19
30
  return next(action);
20
- } else {
21
- window.location.replace(
22
- route.url ? route.url(action.payload) : pathname,
23
- );
24
- }
25
- break;
26
- default:
27
- return next(action);
28
- }
29
- };
31
+ }
32
+ };
30
33
 
31
34
  export default blacklistRoutes;
@@ -21,42 +21,43 @@ const RESET_CONTENT = 'RESET_CONTENT';
21
21
  // such a reset when navigating between two content routes.
22
22
  // ---
23
23
 
24
- export const protectLoadStart = ({ dispatch, getState }) => (next) => (
25
- action,
26
- ) => {
27
- if (typeof action === 'function') {
28
- return next(action);
29
- }
30
- switch (action.type) {
31
- case LOCATION_CHANGE:
32
- const { location } = action.payload;
33
- const { pathname: path } = location;
34
- const currentPath = getState().router.location.pathname;
35
- const result = next(action);
36
- if (isCmsUi(path)) {
37
- // Next path: isCmsUI, Non Content. There is no
38
- // loading here, so skip counting altogether.
39
- // Will update the delayed location constantly.
40
- dispatch({
41
- type: PROTECT_SKIPPED,
42
- location,
43
- });
44
- } else {
45
- dispatch({
46
- type: PROTECT_START,
47
- location,
48
- // Only reset before the fetch, if we depart from
49
- // a not isCmsUi, Content pass. However, reset will
50
- // not occur if moving between two content paths,
51
- // only the postponed location will be booked.
52
- resetBeforeFetch: isCmsUi(currentPath),
53
- });
54
- }
55
- return result;
56
- default:
24
+ export const protectLoadStart =
25
+ ({ dispatch, getState }) =>
26
+ (next) =>
27
+ (action) => {
28
+ if (typeof action === 'function') {
57
29
  return next(action);
58
- }
59
- };
30
+ }
31
+ switch (action.type) {
32
+ case LOCATION_CHANGE:
33
+ const { location } = action.payload;
34
+ const { pathname: path } = location;
35
+ const currentPath = getState().router.location.pathname;
36
+ const result = next(action);
37
+ if (isCmsUi(path)) {
38
+ // Next path: isCmsUI, Non Content. There is no
39
+ // loading here, so skip counting altogether.
40
+ // Will update the delayed location constantly.
41
+ dispatch({
42
+ type: PROTECT_SKIPPED,
43
+ location,
44
+ });
45
+ } else {
46
+ dispatch({
47
+ type: PROTECT_START,
48
+ location,
49
+ // Only reset before the fetch, if we depart from
50
+ // a not isCmsUi, Content pass. However, reset will
51
+ // not occur if moving between two content paths,
52
+ // only the postponed location will be booked.
53
+ resetBeforeFetch: isCmsUi(currentPath),
54
+ });
55
+ }
56
+ return result;
57
+ default:
58
+ return next(action);
59
+ }
60
+ };
60
61
 
61
62
  // Note that there is a bit of heuristics here. We assume that every action
62
63
  // like this is beginning/ending an action. If this logic fails then the counting
@@ -70,34 +71,32 @@ const mapActions = {
70
71
  [GET_CONTENT_PENDING]: RESET_CONTENT,
71
72
  };
72
73
 
73
- export const protectLoadEnd = ({ dispatch, getState }) => (next) => (
74
- action,
75
- ) => {
76
- if (typeof action === 'function') {
77
- return next(action);
78
- }
79
- const {
80
- isCounting,
81
- resetBeforeFetch,
82
- requestCount,
83
- } = getState().loadProtector;
84
- if (resetBeforeFetch) {
85
- const type = mapActions[action.type];
86
- if (type) {
87
- dispatch({ type });
74
+ export const protectLoadEnd =
75
+ ({ dispatch, getState }) =>
76
+ (next) =>
77
+ (action) => {
78
+ if (typeof action === 'function') {
79
+ return next(action);
88
80
  }
89
- }
90
- if (isCounting && requestCount === 1 && isResponseAction(action)) {
91
- setTimeout(
92
- () =>
93
- dispatch({
94
- type: PROTECT_END,
95
- }),
96
- 0,
97
- );
98
- }
99
- return next(action);
100
- };
81
+ const { isCounting, resetBeforeFetch, requestCount } =
82
+ getState().loadProtector;
83
+ if (resetBeforeFetch) {
84
+ const type = mapActions[action.type];
85
+ if (type) {
86
+ dispatch({ type });
87
+ }
88
+ }
89
+ if (isCounting && requestCount === 1 && isResponseAction(action)) {
90
+ setTimeout(
91
+ () =>
92
+ dispatch({
93
+ type: PROTECT_END,
94
+ }),
95
+ 0,
96
+ );
97
+ }
98
+ return next(action);
99
+ };
101
100
 
102
101
  export function loadProtector(state = {}, action = {}) {
103
102
  switch (action.type) {