@plone/volto 18.32.1 → 18.32.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.
- package/.eslintignore +1 -0
- package/CHANGELOG.md +40 -0
- package/README.md +0 -4
- package/locales/af/LC_MESSAGES/volto.po +20 -0
- package/locales/af.json +1 -1
- package/locales/ar/LC_MESSAGES/volto.po +20 -0
- package/locales/ar.json +1 -1
- package/locales/bg/LC_MESSAGES/volto.po +20 -0
- package/locales/bg.json +1 -1
- package/locales/bn/LC_MESSAGES/volto.po +20 -0
- package/locales/bn.json +1 -1
- package/locales/ca/LC_MESSAGES/volto.po +20 -0
- package/locales/ca.json +1 -1
- package/locales/cs/LC_MESSAGES/volto.po +20 -0
- package/locales/cs.json +1 -1
- package/locales/cy/LC_MESSAGES/volto.po +20 -0
- package/locales/cy.json +1 -1
- package/locales/da/LC_MESSAGES/volto.po +20 -0
- package/locales/da.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +20 -0
- package/locales/de.json +1 -1
- package/locales/el/LC_MESSAGES/volto.po +20 -0
- package/locales/el.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +20 -0
- package/locales/en.json +1 -1
- package/locales/en_AU/LC_MESSAGES/volto.po +20 -0
- package/locales/en_AU.json +1 -1
- package/locales/en_GB/LC_MESSAGES/volto.po +20 -0
- package/locales/en_GB.json +1 -1
- package/locales/eo/LC_MESSAGES/volto.po +20 -0
- package/locales/eo.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +20 -0
- package/locales/es.json +1 -1
- package/locales/et/LC_MESSAGES/volto.po +20 -0
- package/locales/et.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +20 -0
- package/locales/eu.json +1 -1
- package/locales/fa/LC_MESSAGES/volto.po +20 -0
- package/locales/fa.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +20 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +20 -0
- package/locales/fr.json +1 -1
- package/locales/fu/LC_MESSAGES/volto.po +20 -0
- package/locales/fu.json +1 -1
- package/locales/gl/LC_MESSAGES/volto.po +20 -0
- package/locales/gl.json +1 -1
- package/locales/he/LC_MESSAGES/volto.po +20 -0
- package/locales/he.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +20 -0
- package/locales/hi.json +1 -1
- package/locales/hr/LC_MESSAGES/volto.po +20 -0
- package/locales/hr.json +1 -1
- package/locales/hu/LC_MESSAGES/volto.po +20 -0
- package/locales/hu.json +1 -1
- package/locales/hy/LC_MESSAGES/volto.po +20 -0
- package/locales/hy.json +1 -1
- package/locales/id/LC_MESSAGES/volto.po +20 -0
- package/locales/id.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +31 -11
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +20 -0
- package/locales/ja.json +1 -1
- package/locales/ka/LC_MESSAGES/volto.po +20 -0
- package/locales/ka.json +1 -1
- package/locales/kn/LC_MESSAGES/volto.po +20 -0
- package/locales/kn.json +1 -1
- package/locales/ko/LC_MESSAGES/volto.po +20 -0
- package/locales/ko.json +1 -1
- package/locales/lt/LC_MESSAGES/volto.po +20 -0
- package/locales/lt.json +1 -1
- package/locales/lv/LC_MESSAGES/volto.po +20 -0
- package/locales/lv.json +1 -1
- package/locales/mi/LC_MESSAGES/volto.po +20 -0
- package/locales/mi.json +1 -1
- package/locales/mk/LC_MESSAGES/volto.po +20 -0
- package/locales/mk.json +1 -1
- package/locales/my/LC_MESSAGES/volto.po +20 -0
- package/locales/my.json +1 -1
- package/locales/nb_NO/LC_MESSAGES/volto.po +20 -0
- package/locales/nb_NO.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +20 -0
- package/locales/nl.json +1 -1
- package/locales/nn/LC_MESSAGES/volto.po +20 -0
- package/locales/nn.json +1 -1
- package/locales/pl/LC_MESSAGES/volto.po +20 -0
- package/locales/pl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +20 -0
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +20 -0
- package/locales/pt_BR.json +1 -1
- package/locales/rm/LC_MESSAGES/volto.po +20 -0
- package/locales/rm.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +20 -0
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +20 -0
- package/locales/ru.json +1 -1
- package/locales/sk/LC_MESSAGES/volto.po +20 -0
- package/locales/sk.json +1 -1
- package/locales/sl/LC_MESSAGES/volto.po +20 -0
- package/locales/sl.json +1 -1
- package/locales/sm/LC_MESSAGES/volto.po +20 -0
- package/locales/sm.json +1 -1
- package/locales/sq/LC_MESSAGES/volto.po +20 -0
- package/locales/sq.json +1 -1
- package/locales/sr/LC_MESSAGES/volto.po +20 -0
- package/locales/sr.json +1 -1
- package/locales/sr@cyrl/LC_MESSAGES/volto.po +20 -0
- package/locales/sr@cyrl.json +1 -1
- package/locales/sr@latn/LC_MESSAGES/volto.po +20 -0
- package/locales/sr@latn.json +1 -1
- package/locales/sv/LC_MESSAGES/volto.po +20 -0
- package/locales/sv.json +1 -1
- package/locales/ta/LC_MESSAGES/volto.po +20 -0
- package/locales/ta.json +1 -1
- package/locales/te/LC_MESSAGES/volto.po +20 -0
- package/locales/te.json +1 -1
- package/locales/th/LC_MESSAGES/volto.po +20 -0
- package/locales/th.json +1 -1
- package/locales/to/LC_MESSAGES/volto.po +20 -0
- package/locales/to.json +1 -1
- package/locales/tr/LC_MESSAGES/volto.po +20 -0
- package/locales/tr.json +1 -1
- package/locales/uk/LC_MESSAGES/volto.po +20 -0
- package/locales/uk.json +1 -1
- package/locales/vi/LC_MESSAGES/volto.po +20 -0
- package/locales/vi.json +1 -1
- package/locales/volto.pot +21 -1
- package/locales/zh_CN/LC_MESSAGES/volto.po +20 -0
- package/locales/zh_CN.json +1 -1
- package/locales/zh_Hant/LC_MESSAGES/volto.po +20 -0
- package/locales/zh_Hant.json +1 -1
- package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +20 -0
- package/locales/zh_Hant_HK.json +1 -1
- package/package.json +6 -5
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
- package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +2 -9
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +10 -1
- package/src/components/manage/Blocks/Block/Order/Item.jsx +9 -3
- package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
- package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
- package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
- package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -1
- package/src/components/manage/Sharing/Sharing.jsx +10 -12
- package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +5 -1
- package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
- package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
- package/src/components/theme/App/App.jsx +3 -1
- package/src/components/theme/ConnectionRefused/ConnectionRefused.jsx +3 -2
- package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
- package/src/components/theme/View/RenderBlocks.jsx +8 -10
- package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
- package/src/config/index.js +1 -1
- package/src/config/validation.ts +8 -0
- package/src/helpers/Blocks/Blocks.js +109 -24
- package/src/helpers/Blocks/Blocks.test.js +100 -0
- package/src/helpers/FormValidation/FormValidation.test.js +47 -0
- package/src/helpers/FormValidation/validators.ts +37 -4
- package/src/helpers/MessageLabels/MessageLabels.js +5 -0
- package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
- package/types/components/theme/ConnectionRefused/ConnectionRefused.d.ts +2 -2
- package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
- package/types/config/Views.d.ts +1 -1
- package/types/helpers/Blocks/Blocks.d.ts +4 -0
- package/types/helpers/FormValidation/validators.d.ts +18 -1
- package/types/helpers/MessageLabels/MessageLabels.d.ts +100 -94
- package/types/routes.d.ts +7 -5
|
@@ -161,19 +161,12 @@ test('Removes invalid blocks on saving', () => {
|
|
|
161
161
|
</Provider>,
|
|
162
162
|
);
|
|
163
163
|
|
|
164
|
+
expect(onChangeFormData).toHaveBeenCalledTimes(1);
|
|
164
165
|
expect(onChangeFormData).toHaveBeenCalledWith({
|
|
165
166
|
blocks: {
|
|
166
167
|
a: { '@type': 'custom', text: 'a' },
|
|
167
168
|
b: { '@type': 'custom', text: 'b' },
|
|
168
169
|
},
|
|
169
|
-
blocks_layout: { items: ['a', 'b'
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
expect(onChangeFormData).toHaveBeenCalledWith({
|
|
173
|
-
blocks: {
|
|
174
|
-
a: { '@type': 'custom', text: 'a' },
|
|
175
|
-
b: { '@type': 'custom', text: 'b' },
|
|
176
|
-
},
|
|
177
|
-
blocks_layout: { items: ['a', 'b', 'MISSING-YOU-2'] },
|
|
170
|
+
blocks_layout: { items: ['a', 'b'] },
|
|
178
171
|
});
|
|
179
172
|
});
|
|
@@ -25,6 +25,14 @@ const messages = defineMessages({
|
|
|
25
25
|
id: 'delete',
|
|
26
26
|
defaultMessage: 'delete',
|
|
27
27
|
},
|
|
28
|
+
delete_block: {
|
|
29
|
+
id: 'delete_block',
|
|
30
|
+
defaultMessage: 'delete {type} block',
|
|
31
|
+
},
|
|
32
|
+
drag_block: {
|
|
33
|
+
id: 'drag_block',
|
|
34
|
+
defaultMessage: 'drag {type} block',
|
|
35
|
+
},
|
|
28
36
|
});
|
|
29
37
|
|
|
30
38
|
const EditBlockWrapper = (props) => {
|
|
@@ -99,6 +107,7 @@ const EditBlockWrapper = (props) => {
|
|
|
99
107
|
}}
|
|
100
108
|
{...draginfo.dragHandleProps}
|
|
101
109
|
className="drag handle wrapper"
|
|
110
|
+
aria-label={intl.formatMessage(messages.drag_block, { type })}
|
|
102
111
|
>
|
|
103
112
|
<Icon name={dragSVG} size="18px" />
|
|
104
113
|
</div>
|
|
@@ -111,7 +120,7 @@ const EditBlockWrapper = (props) => {
|
|
|
111
120
|
basic
|
|
112
121
|
onClick={() => onDeleteBlock(block, true)}
|
|
113
122
|
className="delete-button"
|
|
114
|
-
aria-label={intl.formatMessage(messages.
|
|
123
|
+
aria-label={intl.formatMessage(messages.delete_block, { type })}
|
|
115
124
|
>
|
|
116
125
|
<Icon name={trashSVG} size="18px" />
|
|
117
126
|
</Button>
|
|
@@ -25,6 +25,7 @@ export const Item = forwardRef(
|
|
|
25
25
|
onRemove,
|
|
26
26
|
onSelectBlock,
|
|
27
27
|
parentId,
|
|
28
|
+
parentType,
|
|
28
29
|
style,
|
|
29
30
|
value,
|
|
30
31
|
wrapperRef,
|
|
@@ -39,6 +40,10 @@ export const Item = forwardRef(
|
|
|
39
40
|
const gridSelected = useSelector((state) => state.form.ui.gridSelected);
|
|
40
41
|
const dispatch = useDispatch();
|
|
41
42
|
|
|
43
|
+
const icon =
|
|
44
|
+
config.blocks.blocksConfig[data?.['@type']]?.icon ||
|
|
45
|
+
config.blocks.blocksConfig.title?.icon;
|
|
46
|
+
|
|
42
47
|
return (
|
|
43
48
|
<li
|
|
44
49
|
className={classNames(
|
|
@@ -102,15 +107,16 @@ export const Item = forwardRef(
|
|
|
102
107
|
errored: errors && Object.keys(errors).length > 0,
|
|
103
108
|
})}
|
|
104
109
|
>
|
|
105
|
-
{
|
|
110
|
+
{icon && (
|
|
106
111
|
<Icon
|
|
107
|
-
name={
|
|
112
|
+
name={icon}
|
|
108
113
|
size="20px"
|
|
109
114
|
style={{ verticalAlign: 'middle' }}
|
|
110
115
|
/>
|
|
111
116
|
)}{' '}
|
|
112
117
|
{data?.plaintext ||
|
|
113
|
-
config.blocks.blocksConfig[data?.['@type']]?.title
|
|
118
|
+
config.blocks.blocksConfig[data?.['@type']]?.title ||
|
|
119
|
+
data?.title}
|
|
114
120
|
</span>
|
|
115
121
|
{!clone && onRemove && (
|
|
116
122
|
<button
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
2
3
|
import { createPortal } from 'react-dom';
|
|
4
|
+
import { toast } from 'react-toastify';
|
|
5
|
+
import Toast from '@plone/volto/components/manage/Toast/Toast';
|
|
3
6
|
import find from 'lodash/find';
|
|
4
|
-
import
|
|
7
|
+
import { messages as defaultMessages } from '@plone/volto/helpers/MessageLabels/MessageLabels';
|
|
5
8
|
|
|
6
9
|
import { flattenTree, getProjection, removeChildrenOf } from './utilities';
|
|
7
10
|
import SortableItem from './SortableItem';
|
|
8
11
|
|
|
9
12
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
10
13
|
|
|
14
|
+
const messages = defineMessages({
|
|
15
|
+
invalidBlockType: {
|
|
16
|
+
id: 'You can not move this type of block to the new location',
|
|
17
|
+
defaultMessage: 'You can not move this type of block to the new location',
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
export function Order({
|
|
12
22
|
items = [],
|
|
13
23
|
onMoveBlock,
|
|
@@ -24,6 +34,7 @@ export function Order({
|
|
|
24
34
|
const [overId, setOverId] = useState(null);
|
|
25
35
|
const [offsetLeft, setOffsetLeft] = useState(0);
|
|
26
36
|
const [currentPosition, setCurrentPosition] = useState(null);
|
|
37
|
+
const intl = useIntl();
|
|
27
38
|
|
|
28
39
|
const {
|
|
29
40
|
DndContext,
|
|
@@ -72,6 +83,7 @@ export function Order({
|
|
|
72
83
|
() => removeChildrenOf(flattenTree(items), activeId ? [activeId] : []),
|
|
73
84
|
[activeId, items],
|
|
74
85
|
);
|
|
86
|
+
|
|
75
87
|
const projected =
|
|
76
88
|
activeId && overId
|
|
77
89
|
? getProjection(
|
|
@@ -135,16 +147,14 @@ export function Order({
|
|
|
135
147
|
onDragCancel={handleDragCancel}
|
|
136
148
|
>
|
|
137
149
|
<SortableContext items={sortedIds} strategy={verticalListSortingStrategy}>
|
|
138
|
-
{flattenedItems.map(({ id, parentId, depth, data }) => (
|
|
150
|
+
{flattenedItems.map(({ id, parentId, parentType, depth, data }) => (
|
|
139
151
|
<SortableItem
|
|
140
152
|
key={id}
|
|
141
153
|
id={id}
|
|
142
154
|
parentId={parentId}
|
|
155
|
+
parentType={parentType}
|
|
143
156
|
data={data}
|
|
144
|
-
depth={
|
|
145
|
-
id === activeId && projected ? projected.depth : depth,
|
|
146
|
-
1,
|
|
147
|
-
])}
|
|
157
|
+
depth={id === activeId && projected ? projected.depth : depth}
|
|
148
158
|
indentationWidth={indentationWidth}
|
|
149
159
|
onRemove={removable ? () => handleRemove(id) : undefined}
|
|
150
160
|
onSelectBlock={onSelectBlock}
|
|
@@ -178,6 +188,7 @@ export function Order({
|
|
|
178
188
|
if (activeItem) {
|
|
179
189
|
setCurrentPosition({
|
|
180
190
|
parentId: activeItem.parentId,
|
|
191
|
+
parentType: activeItem.parentType,
|
|
181
192
|
overId: activeId,
|
|
182
193
|
});
|
|
183
194
|
}
|
|
@@ -195,18 +206,24 @@ export function Order({
|
|
|
195
206
|
|
|
196
207
|
function handleDragEnd({ active, over }) {
|
|
197
208
|
if (projected && over) {
|
|
198
|
-
const { depth, parentId } = projected;
|
|
209
|
+
const { depth, parentId, parentType } = projected;
|
|
199
210
|
const clonedItems = JSON.parse(JSON.stringify(flattenedItems));
|
|
200
211
|
const overIndex = clonedItems.findIndex(({ id }) => id === over.id);
|
|
201
212
|
const activeIndex = clonedItems.findIndex(({ id }) => id === active.id);
|
|
202
213
|
const activeTreeItem = clonedItems[activeIndex];
|
|
203
214
|
const oldParentId = activeTreeItem.parentId;
|
|
215
|
+
const oldParentType = activeTreeItem.parentType;
|
|
204
216
|
|
|
205
|
-
clonedItems[activeIndex] = {
|
|
217
|
+
clonedItems[activeIndex] = {
|
|
218
|
+
...activeTreeItem,
|
|
219
|
+
depth,
|
|
220
|
+
parentId,
|
|
221
|
+
parentType,
|
|
222
|
+
};
|
|
206
223
|
|
|
207
224
|
// Translate position depending on parent
|
|
208
225
|
if (parentId === oldParentId) {
|
|
209
|
-
// Move from and to toplevel or move within the same
|
|
226
|
+
// Move from and to toplevel or move within the same sub block
|
|
210
227
|
|
|
211
228
|
let destIndex = clonedItems[overIndex].index;
|
|
212
229
|
if (clonedItems[overIndex].depth > clonedItems[activeIndex].depth) {
|
|
@@ -226,66 +243,97 @@ export function Order({
|
|
|
226
243
|
},
|
|
227
244
|
});
|
|
228
245
|
} else if (parentId && oldParentId) {
|
|
229
|
-
// Move from one
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
// Move from one subblock to another
|
|
247
|
+
|
|
248
|
+
if (parentType === oldParentType) {
|
|
249
|
+
// Moving within the same type of subblock
|
|
250
|
+
onMoveBlock({
|
|
251
|
+
source: {
|
|
252
|
+
position: clonedItems[activeIndex].index,
|
|
253
|
+
parent: oldParentId,
|
|
254
|
+
id: active.id,
|
|
255
|
+
},
|
|
256
|
+
destination: {
|
|
257
|
+
position:
|
|
258
|
+
overIndex < activeIndex
|
|
259
|
+
? clonedItems[overIndex - 1].parentId
|
|
260
|
+
? clonedItems[overIndex - 1].index + 1
|
|
261
|
+
: clonedItems[overIndex].index
|
|
262
|
+
: overIndex + 1 < clonedItems.length
|
|
263
|
+
? clonedItems[overIndex + 1].index
|
|
264
|
+
: clonedItems[overIndex].index + 1,
|
|
265
|
+
parent: parentId,
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
} else {
|
|
269
|
+
toast.error(
|
|
270
|
+
<Toast
|
|
271
|
+
error
|
|
272
|
+
title={intl.formatMessage(defaultMessages.error)}
|
|
273
|
+
content={intl.formatMessage(messages.invalidBlockType)}
|
|
274
|
+
/>,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
249
277
|
} else if (oldParentId) {
|
|
250
|
-
// Moving to the main container from a
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
?
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
278
|
+
// Moving to the main container from a subblock
|
|
279
|
+
|
|
280
|
+
if (oldParentType === 'gridBlock') {
|
|
281
|
+
onMoveBlock({
|
|
282
|
+
source: {
|
|
283
|
+
position: clonedItems[activeIndex].index,
|
|
284
|
+
parent: oldParentId,
|
|
285
|
+
id: active.id,
|
|
286
|
+
},
|
|
287
|
+
destination: {
|
|
288
|
+
position:
|
|
289
|
+
overIndex > activeIndex
|
|
290
|
+
? overIndex + 1 < clonedItems.length
|
|
291
|
+
? clonedItems[overIndex + 1].index
|
|
292
|
+
: clonedItems[overIndex].index + 1
|
|
293
|
+
: clonedItems[overIndex].index,
|
|
294
|
+
parent: parentId,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
} else {
|
|
298
|
+
toast.error(
|
|
299
|
+
<Toast
|
|
300
|
+
error
|
|
301
|
+
title={intl.formatMessage(defaultMessages.error)}
|
|
302
|
+
content={intl.formatMessage(messages.invalidBlockType)}
|
|
303
|
+
/>,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
268
306
|
} else {
|
|
269
|
-
// Moving from the main container to a
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
? clonedItems[overIndex - 1].
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
307
|
+
// Moving from the main container to a subblock
|
|
308
|
+
|
|
309
|
+
if (parentType === 'gridBlock') {
|
|
310
|
+
onMoveBlock({
|
|
311
|
+
source: {
|
|
312
|
+
position: clonedItems[activeIndex].index,
|
|
313
|
+
parent: oldParentId,
|
|
314
|
+
id: active.id,
|
|
315
|
+
},
|
|
316
|
+
destination: {
|
|
317
|
+
position:
|
|
318
|
+
overIndex < activeIndex
|
|
319
|
+
? clonedItems[overIndex - 1].parentId
|
|
320
|
+
? clonedItems[overIndex - 1].index + 1
|
|
321
|
+
: clonedItems[overIndex].index
|
|
322
|
+
: overIndex + 1 < clonedItems.length
|
|
323
|
+
? clonedItems[overIndex + 1].index
|
|
324
|
+
: clonedItems[overIndex].index + 1,
|
|
325
|
+
parent: parentId,
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
} else {
|
|
329
|
+
toast.error(
|
|
330
|
+
<Toast
|
|
331
|
+
error
|
|
332
|
+
title={intl.formatMessage(defaultMessages.error)}
|
|
333
|
+
content={intl.formatMessage(messages.invalidBlockType)}
|
|
334
|
+
/>,
|
|
335
|
+
);
|
|
336
|
+
}
|
|
289
337
|
}
|
|
290
338
|
}
|
|
291
339
|
|
|
@@ -321,6 +369,7 @@ export function Order({
|
|
|
321
369
|
} else {
|
|
322
370
|
setCurrentPosition({
|
|
323
371
|
parentId: projected.parentId,
|
|
372
|
+
parentType: projected.parentType,
|
|
324
373
|
overId,
|
|
325
374
|
});
|
|
326
375
|
}
|
|
@@ -34,27 +34,44 @@ export function getProjection(
|
|
|
34
34
|
depth = minDepth;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
return { depth, maxDepth, minDepth,
|
|
37
|
+
return { depth, maxDepth, minDepth, ...getParent() };
|
|
38
38
|
|
|
39
|
-
function
|
|
39
|
+
function getParent() {
|
|
40
40
|
if (depth === 0 || !previousItem) {
|
|
41
|
-
return
|
|
41
|
+
return {
|
|
42
|
+
parentId: null,
|
|
43
|
+
parentType: null,
|
|
44
|
+
};
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
if (depth <= previousItem.depth) {
|
|
45
|
-
return
|
|
48
|
+
return {
|
|
49
|
+
parentId: previousItem.parentId,
|
|
50
|
+
parentType: previousItem.parentType,
|
|
51
|
+
};
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
if (depth > previousItem.depth) {
|
|
49
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
parentId: previousItem.id,
|
|
57
|
+
parentType: previousItem.data?.['@type'] || null,
|
|
58
|
+
};
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
const newParent = newItems
|
|
53
62
|
.slice(0, overItemIndex)
|
|
54
63
|
.reverse()
|
|
55
|
-
.find((item) => item.depth === depth)
|
|
56
|
-
|
|
57
|
-
return newParent
|
|
64
|
+
.find((item) => item.depth === depth);
|
|
65
|
+
|
|
66
|
+
return newParent
|
|
67
|
+
? {
|
|
68
|
+
parentId: newParent.parentId,
|
|
69
|
+
parentType: newParent.parentType,
|
|
70
|
+
}
|
|
71
|
+
: {
|
|
72
|
+
parentId: null,
|
|
73
|
+
parentType: null,
|
|
74
|
+
};
|
|
58
75
|
}
|
|
59
76
|
}
|
|
60
77
|
|
|
@@ -79,12 +96,12 @@ function getMinDepth({ nextItem }) {
|
|
|
79
96
|
return 0;
|
|
80
97
|
}
|
|
81
98
|
|
|
82
|
-
function flatten(items = [], parentId = null, depth = 0) {
|
|
99
|
+
function flatten(items = [], parentId = null, parentType = null, depth = 0) {
|
|
83
100
|
return items.reduce((acc, item, index) => {
|
|
84
101
|
return [
|
|
85
102
|
...acc,
|
|
86
|
-
{ ...item, parentId, depth, index },
|
|
87
|
-
...flatten(item.children, item.id, depth + 1),
|
|
103
|
+
{ ...item, parentId, parentType, depth, index },
|
|
104
|
+
...flatten(item.children, item.id, item.data?.['@type'], depth + 1),
|
|
88
105
|
];
|
|
89
106
|
}, []);
|
|
90
107
|
}
|
|
@@ -169,7 +169,7 @@ class ContentTypeSchema extends Component {
|
|
|
169
169
|
error
|
|
170
170
|
title={this.props.intl.formatMessage(messages.error)}
|
|
171
171
|
content={JSON.stringify(
|
|
172
|
-
nextProps.schemaRequest.put.error.response.body ||
|
|
172
|
+
nextProps.schemaRequest.put.error.response.body?.message ||
|
|
173
173
|
nextProps.schemaRequest.put.error.response.text,
|
|
174
174
|
)}
|
|
175
175
|
/>,
|
|
@@ -485,11 +485,19 @@ class SharingComponent extends Component {
|
|
|
485
485
|
/>
|
|
486
486
|
</p>
|
|
487
487
|
</Segment>
|
|
488
|
-
<Segment className="actions" attached clearing>
|
|
488
|
+
<Segment className="right aligned actions" attached clearing>
|
|
489
|
+
<Button
|
|
490
|
+
basic
|
|
491
|
+
secondary
|
|
492
|
+
aria-label={this.props.intl.formatMessage(messages.cancel)}
|
|
493
|
+
title={this.props.intl.formatMessage(messages.cancel)}
|
|
494
|
+
onClick={this.onCancel}
|
|
495
|
+
>
|
|
496
|
+
<Icon className="circled" name={clearSVG} size="30px" />
|
|
497
|
+
</Button>
|
|
489
498
|
<Button
|
|
490
499
|
basic
|
|
491
500
|
primary
|
|
492
|
-
floated="right"
|
|
493
501
|
type="submit"
|
|
494
502
|
aria-label={this.props.intl.formatMessage(messages.save)}
|
|
495
503
|
title={this.props.intl.formatMessage(messages.save)}
|
|
@@ -498,16 +506,6 @@ class SharingComponent extends Component {
|
|
|
498
506
|
>
|
|
499
507
|
<Icon className="circled" name={aheadSVG} size="30px" />
|
|
500
508
|
</Button>
|
|
501
|
-
<Button
|
|
502
|
-
basic
|
|
503
|
-
secondary
|
|
504
|
-
aria-label={this.props.intl.formatMessage(messages.cancel)}
|
|
505
|
-
title={this.props.intl.formatMessage(messages.cancel)}
|
|
506
|
-
floated="right"
|
|
507
|
-
onClick={this.onCancel}
|
|
508
|
-
>
|
|
509
|
-
<Icon className="circled" name={clearSVG} size="30px" />
|
|
510
|
-
</Button>
|
|
511
509
|
</Segment>
|
|
512
510
|
</Form>
|
|
513
511
|
</Plug>
|
|
@@ -144,10 +144,14 @@ class ObjectBrowserBody extends Component {
|
|
|
144
144
|
showSearchInput: false,
|
|
145
145
|
// In image mode, the searchable types default to the image types which
|
|
146
146
|
// can be overridden with the property if specified.
|
|
147
|
+
// If selectableTypes are passed, the searchableTypes are the selectableTypes
|
|
147
148
|
searchableTypes:
|
|
148
149
|
this.props.mode === 'image'
|
|
149
150
|
? this.props.searchableTypes || config.settings.imageObjects
|
|
150
|
-
:
|
|
151
|
+
: [
|
|
152
|
+
...(this.props.searchableTypes ?? []),
|
|
153
|
+
...(this.props.selectableTypes ?? []),
|
|
154
|
+
],
|
|
151
155
|
view: this.props.mode === 'image' ? 'icons' : 'list',
|
|
152
156
|
};
|
|
153
157
|
this.searchInputRef = React.createRef();
|
|
@@ -89,6 +89,22 @@ describe('UniversalLink', () => {
|
|
|
89
89
|
);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
+
it('check UniversalLink append http when user has not entered the protocol', () => {
|
|
93
|
+
const { getByTitle } = render(
|
|
94
|
+
<Provider store={store}>
|
|
95
|
+
<MemoryRouter>
|
|
96
|
+
<UniversalLink href="www.github.com" title="Volto GitHub repository">
|
|
97
|
+
<h1>Title</h1>
|
|
98
|
+
</UniversalLink>
|
|
99
|
+
</MemoryRouter>
|
|
100
|
+
</Provider>,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(getByTitle('Volto GitHub repository').getAttribute('href')).toBe(
|
|
104
|
+
'http://www.github.com',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
92
108
|
it('check UniversalLink set target attribute for ext links', () => {
|
|
93
109
|
const { getByTitle } = render(
|
|
94
110
|
<Provider store={store}>
|
|
@@ -174,7 +174,9 @@ export class App extends Component {
|
|
|
174
174
|
<main ref={this.mainRef}>
|
|
175
175
|
<OutdatedBrowser />
|
|
176
176
|
{this.props.connectionRefused ? (
|
|
177
|
-
<ConnectionRefusedView
|
|
177
|
+
<ConnectionRefusedView
|
|
178
|
+
staticContext={this.props.staticContext}
|
|
179
|
+
/>
|
|
178
180
|
) : this.state.hasError ? (
|
|
179
181
|
<Error
|
|
180
182
|
message={this.state.error.message}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Connection refused error page.
|
|
3
3
|
* @module components/theme/ConnectionRefused/ConnectionRefused
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -7,6 +7,7 @@ import React from 'react';
|
|
|
7
7
|
import { FormattedMessage } from 'react-intl';
|
|
8
8
|
import { Container } from 'semantic-ui-react';
|
|
9
9
|
import config from '@plone/volto/registry';
|
|
10
|
+
import { withServerErrorCode } from '@plone/volto/helpers/Utils/Utils';
|
|
10
11
|
|
|
11
12
|
const ConnectionRefused = () => (
|
|
12
13
|
<Container
|
|
@@ -71,4 +72,4 @@ const ConnectionRefused = () => (
|
|
|
71
72
|
</Container>
|
|
72
73
|
);
|
|
73
74
|
|
|
74
|
-
export default ConnectionRefused;
|
|
75
|
+
export default withServerErrorCode(503)(ConnectionRefused);
|