@strapi/admin 4.5.4 → 4.6.0-beta.0
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/admin/src/components/AuthenticatedApp/index.js +2 -13
- package/admin/src/content-manager/components/ComponentInitializer/index.js +1 -7
- package/admin/src/content-manager/components/{RepeatableComponent/DragPreview.js → DragLayer/ComponentDragPreview.js} +25 -12
- package/admin/src/content-manager/components/DragLayer/RelationDragPreview.js +75 -0
- package/admin/src/content-manager/components/DragLayer/index.js +23 -7
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +130 -84
- package/admin/src/content-manager/components/DynamicZone/index.js +99 -24
- package/admin/src/content-manager/components/DynamicZone/utils/select.js +9 -5
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +37 -11
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +18 -22
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +24 -5
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +209 -64
- package/admin/src/content-manager/components/RelationInput/components/RelationItem.js +134 -21
- package/admin/src/content-manager/components/RelationInput/components/RelationList.js +1 -2
- package/admin/src/content-manager/components/RelationInput/constants.js +1 -0
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +131 -9
- package/admin/src/content-manager/components/RepeatableComponent/components/Accordion.js +77 -0
- package/admin/src/content-manager/components/RepeatableComponent/components/Component.js +262 -0
- package/admin/src/content-manager/components/RepeatableComponent/{DraggedItem → components}/Preview.js +0 -0
- package/admin/src/content-manager/components/RepeatableComponent/index.js +147 -87
- package/admin/src/content-manager/components/RepeatableComponent/utils/getComponentErrorKeys.js +1 -1
- package/admin/src/content-manager/hooks/index.js +2 -0
- package/admin/src/content-manager/hooks/useDragAndDrop.js +120 -0
- package/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js +98 -0
- package/admin/src/content-manager/utils/ItemTypes.js +1 -1
- package/admin/src/content-manager/utils/composeRefs.js +28 -0
- package/admin/src/content-manager/utils/getMaxTempKey.js +1 -1
- package/admin/src/content-manager/utils/index.js +7 -0
- package/admin/src/pages/App/index.js +13 -20
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +3 -2
- package/admin/src/translations/en.json +6 -0
- package/admin/src/translations/tr.json +5 -485
- package/admin/src/utils/index.js +0 -1
- package/build/4318.80bdf035.chunk.js +30 -0
- package/build/{8176.e929d326.chunk.js → 8176.b19bc128.chunk.js} +32 -32
- package/build/{1233.802422fa.chunk.js → 8186.55910742.chunk.js} +96 -96
- package/build/{8633.43ec9042.chunk.js → 8633.59223842.chunk.js} +1 -1
- package/build/Admin-authenticatedApp.f9e74dc0.chunk.js +80 -0
- package/build/{Admin_profilePage.60ab80bb.chunk.js → Admin_profilePage.c07bdf08.chunk.js} +1 -1
- package/build/{Admin_settingsPage.6ef8acc9.chunk.js → Admin_settingsPage.50a8765b.chunk.js} +1 -1
- package/build/admin-app.2861b6d2.chunk.js +112 -0
- package/build/admin-edit-users.85231e4c.chunk.js +10 -0
- package/build/{admin-users.e64fb0f1.chunk.js → admin-users.a2707644.chunk.js} +2 -2
- package/build/api-tokens-create-page.dd4ddfcb.chunk.js +1 -0
- package/build/api-tokens-edit-page.821c5a6c.chunk.js +1 -0
- package/build/content-manager.ee948f75.chunk.js +1186 -0
- package/build/content-type-builder-translation-tr-json.2e52bc60.chunk.js +1 -0
- package/build/email-settings-page.db0d98d1.chunk.js +15 -0
- package/build/email-translation-tr-json.87f2feb3.chunk.js +1 -0
- package/build/{en-json.7dd57947.chunk.js → en-json.4a56dca7.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/main.faac89ee.js +2025 -0
- package/build/runtime~main.75a15b8e.js +2 -0
- package/build/sso-settings-page.adb12ac3.chunk.js +1 -0
- package/build/tr-json.9c44ea0c.chunk.js +1 -0
- package/build/{upload.74540aab.chunk.js → upload.e2034370.chunk.js} +3 -3
- package/build/users-permissions-translation-tr-json.cdc49a3c.chunk.js +1 -0
- package/package.json +9 -9
- package/server/controllers/admin.js +0 -2
- package/server/routes/admin.js +1 -1
- package/server/services/metrics.js +2 -5
- package/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +0 -122
- package/admin/src/content-manager/components/RepeatableComponent/AddFieldButton.js +0 -58
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/DraggingSibling.js +0 -72
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/IconButtonCustoms.js +0 -32
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +0 -326
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/connect.js +0 -11
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/index.js +0 -2
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/select.js +0 -30
- package/admin/src/content-manager/components/RepeatableComponent/utils/connect.js +0 -11
- package/admin/src/content-manager/components/RepeatableComponent/utils/select.js +0 -12
- package/admin/src/content-manager/hooks/__test__/usePrev.test.js +0 -26
- package/admin/src/utils/uniqueAdminHash.js +0 -22
- package/build/4318.9283c350.chunk.js +0 -30
- package/build/Admin-authenticatedApp.0da578b8.chunk.js +0 -80
- package/build/admin-app.a3277e72.chunk.js +0 -112
- package/build/admin-edit-users.5547b126.chunk.js +0 -10
- package/build/api-tokens-create-page.93dd0689.chunk.js +0 -1
- package/build/api-tokens-edit-page.b0adac81.chunk.js +0 -1
- package/build/content-manager.f9630c3b.chunk.js +0 -1197
- package/build/content-type-builder-translation-tr-json.949e22eb.chunk.js +0 -1
- package/build/email-settings-page.c6e62f6b.chunk.js +0 -15
- package/build/email-translation-tr-json.8aa034bb.chunk.js +0 -1
- package/build/i18n-translation-tr-json.34ca9d61.chunk.js +0 -1
- package/build/main.71f24343.js +0 -2034
- package/build/runtime~main.1115f82b.js +0 -2
- package/build/sso-settings-page.feed2f45.chunk.js +0 -1
- package/build/tr-json.eac8bd79.chunk.js +0 -1
- package/build/upload-translation-tr-json.b173223a.chunk.js +0 -1
- package/build/users-permissions-translation-tr-json.9bebc250.chunk.js +0 -1
package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import React, { memo, useMemo } from 'react';
|
|
3
|
+
import React, { memo, useMemo, useState } from 'react';
|
|
4
4
|
import { useIntl } from 'react-intl';
|
|
5
5
|
import get from 'lodash/get';
|
|
6
6
|
import pick from 'lodash/pick';
|
|
@@ -36,9 +36,18 @@ export const RelationInputDataManager = ({
|
|
|
36
36
|
size,
|
|
37
37
|
targetModel,
|
|
38
38
|
}) => {
|
|
39
|
+
const [liveText, setLiveText] = useState('');
|
|
40
|
+
|
|
39
41
|
const { formatMessage } = useIntl();
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
+
const {
|
|
43
|
+
slug,
|
|
44
|
+
initialData,
|
|
45
|
+
modifiedData,
|
|
46
|
+
relationConnect,
|
|
47
|
+
relationDisconnect,
|
|
48
|
+
relationLoad,
|
|
49
|
+
relationReorder,
|
|
50
|
+
} = useCMEditViewDataManager();
|
|
42
51
|
|
|
43
52
|
const relationsFromModifiedData = get(modifiedData, name, []);
|
|
44
53
|
|
|
@@ -54,7 +63,7 @@ export const RelationInputDataManager = ({
|
|
|
54
63
|
...defaultParams,
|
|
55
64
|
pageSize: RELATIONS_TO_DISPLAY,
|
|
56
65
|
},
|
|
57
|
-
onLoad:
|
|
66
|
+
onLoad: relationLoad,
|
|
58
67
|
normalizeArguments: {
|
|
59
68
|
mainFieldName: mainField.name,
|
|
60
69
|
shouldAddLink: shouldDisplayRelationLink,
|
|
@@ -104,11 +113,11 @@ export const RelationInputDataManager = ({
|
|
|
104
113
|
targetModel,
|
|
105
114
|
});
|
|
106
115
|
|
|
107
|
-
|
|
116
|
+
relationConnect({ name, value: normalizedRelation, toOneRelation });
|
|
108
117
|
};
|
|
109
118
|
|
|
110
119
|
const handleRelationDisconnect = (relation) => {
|
|
111
|
-
|
|
120
|
+
relationDisconnect({ name, id: relation.id });
|
|
112
121
|
};
|
|
113
122
|
|
|
114
123
|
const handleRelationLoadMore = () => {
|
|
@@ -130,6 +139,105 @@ export const RelationInputDataManager = ({
|
|
|
130
139
|
const handleSearchMore = () => {
|
|
131
140
|
search.fetchNextPage();
|
|
132
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
*
|
|
144
|
+
* @param {number} index
|
|
145
|
+
* @returns {string}
|
|
146
|
+
*/
|
|
147
|
+
const getItemPos = (index) => `${index + 1} of ${relationsFromModifiedData.length}`;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
*
|
|
151
|
+
* @param {number} currentIndex
|
|
152
|
+
* @param {number} oldIndex
|
|
153
|
+
*/
|
|
154
|
+
const handleRelationReorder = (oldIndex, newIndex) => {
|
|
155
|
+
const item = relationsFromModifiedData[oldIndex];
|
|
156
|
+
|
|
157
|
+
setLiveText(
|
|
158
|
+
formatMessage(
|
|
159
|
+
{
|
|
160
|
+
id: getTrad('dnd.reorder'),
|
|
161
|
+
defaultMessage: '{item}, moved. New position in list: {position}.',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
item: item.mainField ?? item.id,
|
|
165
|
+
position: getItemPos(newIndex),
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
relationReorder({
|
|
171
|
+
name,
|
|
172
|
+
newIndex,
|
|
173
|
+
oldIndex,
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
*
|
|
179
|
+
* @param {number} index
|
|
180
|
+
* @returns {void}
|
|
181
|
+
*/
|
|
182
|
+
const handleGrabItem = (index) => {
|
|
183
|
+
const item = relationsFromModifiedData[index];
|
|
184
|
+
|
|
185
|
+
setLiveText(
|
|
186
|
+
formatMessage(
|
|
187
|
+
{
|
|
188
|
+
id: getTrad('dnd.grab-item'),
|
|
189
|
+
defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
item: item.mainField ?? item.id,
|
|
193
|
+
position: getItemPos(index),
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
*
|
|
201
|
+
* @param {number} index
|
|
202
|
+
* @returns {void}
|
|
203
|
+
*/
|
|
204
|
+
const handleDropItem = (index) => {
|
|
205
|
+
const item = relationsFromModifiedData[index];
|
|
206
|
+
|
|
207
|
+
setLiveText(
|
|
208
|
+
formatMessage(
|
|
209
|
+
{
|
|
210
|
+
id: getTrad('dnd.drop-item'),
|
|
211
|
+
defaultMessage: `{item}, dropped. Final position in list: {position}.`,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
item: item.mainField ?? item.id,
|
|
215
|
+
position: getItemPos(index),
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
*
|
|
223
|
+
* @param {number} index
|
|
224
|
+
* @returns {void}
|
|
225
|
+
*/
|
|
226
|
+
const handleCancel = (index) => {
|
|
227
|
+
const item = relationsFromModifiedData[index];
|
|
228
|
+
|
|
229
|
+
setLiveText(
|
|
230
|
+
formatMessage(
|
|
231
|
+
{
|
|
232
|
+
id: getTrad('dnd.cancel-item'),
|
|
233
|
+
defaultMessage: '{item}, dropped. Re-order cancelled.',
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
item: item.mainField ?? item.id,
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
};
|
|
133
241
|
|
|
134
242
|
if (
|
|
135
243
|
(!isFieldAllowed && isCreatingEntry) ||
|
|
@@ -163,8 +271,13 @@ export const RelationInputDataManager = ({
|
|
|
163
271
|
return (
|
|
164
272
|
<RelationInput
|
|
165
273
|
error={error}
|
|
274
|
+
canReorder={!toOneRelation}
|
|
166
275
|
description={description}
|
|
167
276
|
disabled={isDisabled}
|
|
277
|
+
iconButtonAriaLabel={formatMessage({
|
|
278
|
+
id: getTrad('components.RelationInput.icon-button-aria-label'),
|
|
279
|
+
defaultMessage: 'Drag',
|
|
280
|
+
})}
|
|
168
281
|
id={name}
|
|
169
282
|
label={`${formatMessage({
|
|
170
283
|
id: intlLabel.id,
|
|
@@ -183,7 +296,12 @@ export const RelationInputDataManager = ({
|
|
|
183
296
|
id: getTrad('relation.disconnect'),
|
|
184
297
|
defaultMessage: 'Remove',
|
|
185
298
|
})}
|
|
299
|
+
listAriaDescription={formatMessage({
|
|
300
|
+
id: getTrad('dnd.instructions'),
|
|
301
|
+
defaultMessage: `Press spacebar to grab and re-order`,
|
|
302
|
+
})}
|
|
186
303
|
listHeight={320}
|
|
304
|
+
liveText={liveText}
|
|
187
305
|
loadingMessage={formatMessage({
|
|
188
306
|
id: getTrad('relation.isLoading'),
|
|
189
307
|
defaultMessage: 'Relations are loading',
|
|
@@ -194,9 +312,13 @@ export const RelationInputDataManager = ({
|
|
|
194
312
|
defaultMessage: 'No relations available',
|
|
195
313
|
})}
|
|
196
314
|
numberOfRelationsToDisplay={RELATIONS_TO_DISPLAY}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
315
|
+
onDropItem={handleDropItem}
|
|
316
|
+
onGrabItem={handleGrabItem}
|
|
317
|
+
onCancel={handleCancel}
|
|
318
|
+
onRelationConnect={handleRelationConnect}
|
|
319
|
+
onRelationDisconnect={handleRelationDisconnect}
|
|
320
|
+
onRelationLoadMore={handleRelationLoadMore}
|
|
321
|
+
onRelationReorder={handleRelationReorder}
|
|
200
322
|
onSearch={(term) => handleSearch(term)}
|
|
201
323
|
onSearchNextPage={() => handleSearchMore()}
|
|
202
324
|
placeholder={formatMessage(
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { Box, Typography, KeyboardNavigable } from '@strapi/design-system';
|
|
6
|
+
|
|
7
|
+
export const Footer = styled(Box)`
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
10
|
+
border-right: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
11
|
+
border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
12
|
+
border-radius: 0 0 ${({ theme }) => theme.borderRadius} ${({ theme }) => theme.borderRadius};
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const Content = styled(Box)`
|
|
16
|
+
border-bottom: none;
|
|
17
|
+
|
|
18
|
+
/* add the borders and make sure the top is transparent to avoid jumping with the hover effect */
|
|
19
|
+
& > div > div {
|
|
20
|
+
border: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
21
|
+
border-top-color: transparent;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* the top accordion _does_ need a border though */
|
|
25
|
+
& > div:first-child > div {
|
|
26
|
+
border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Reset all the border-radius' */
|
|
30
|
+
& > div > div,
|
|
31
|
+
& > div > div > div {
|
|
32
|
+
border-radius: unset;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Give the border radius back to the first accordion */
|
|
36
|
+
& > div:first-child > div,
|
|
37
|
+
& > div:first-child > div > div {
|
|
38
|
+
border-radius: ${({ theme }) => theme.borderRadius} ${({ theme }) => theme.borderRadius} 0 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
& > div > div[data-strapi-expanded='true'] {
|
|
42
|
+
border: 1px solid ${({ theme }) => theme.colors.primary600};
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
export const Group = ({ children, error }) => {
|
|
47
|
+
const { formatMessage } = useIntl();
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<KeyboardNavigable attributeName="data-strapi-accordion-toggle">
|
|
51
|
+
{children}
|
|
52
|
+
{error && (
|
|
53
|
+
<Box paddingTop={1}>
|
|
54
|
+
<Typography variant="pi" textColor="danger600">
|
|
55
|
+
{formatMessage(
|
|
56
|
+
{ id: error.id, defaultMessage: error.defaultMessage },
|
|
57
|
+
{ ...error.values }
|
|
58
|
+
)}
|
|
59
|
+
</Typography>
|
|
60
|
+
</Box>
|
|
61
|
+
)}
|
|
62
|
+
</KeyboardNavigable>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
Group.defaultProps = {
|
|
67
|
+
error: undefined,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
Group.propTypes = {
|
|
71
|
+
children: PropTypes.node.isRequired,
|
|
72
|
+
error: PropTypes.shape({
|
|
73
|
+
id: PropTypes.string.isRequired,
|
|
74
|
+
defaultMessage: PropTypes.string.isRequired,
|
|
75
|
+
values: PropTypes.object,
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/* eslint-disable import/no-cycle */
|
|
2
|
+
import React, { memo, useEffect, useRef } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { getEmptyImage } from 'react-dnd-html5-backend';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import toString from 'lodash/toString';
|
|
8
|
+
import get from 'lodash/get';
|
|
9
|
+
|
|
10
|
+
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
|
|
11
|
+
import {
|
|
12
|
+
Accordion,
|
|
13
|
+
AccordionToggle,
|
|
14
|
+
AccordionContent,
|
|
15
|
+
Grid,
|
|
16
|
+
GridItem,
|
|
17
|
+
Stack,
|
|
18
|
+
Box,
|
|
19
|
+
IconButton,
|
|
20
|
+
} from '@strapi/design-system';
|
|
21
|
+
import { Trash, Drag } from '@strapi/icons';
|
|
22
|
+
|
|
23
|
+
import { useDragAndDrop } from '../../../hooks/useDragAndDrop';
|
|
24
|
+
|
|
25
|
+
import { composeRefs, getTrad, ItemTypes } from '../../../utils';
|
|
26
|
+
|
|
27
|
+
import Inputs from '../../Inputs';
|
|
28
|
+
import FieldComponent from '../../FieldComponent';
|
|
29
|
+
|
|
30
|
+
import Preview from './Preview';
|
|
31
|
+
import useLazyComponents from '../../../hooks/useLazyComponents';
|
|
32
|
+
|
|
33
|
+
const CustomIconButton = styled(IconButton)`
|
|
34
|
+
background-color: transparent;
|
|
35
|
+
|
|
36
|
+
svg {
|
|
37
|
+
path {
|
|
38
|
+
fill: ${({ theme, expanded }) =>
|
|
39
|
+
expanded ? theme.colors.primary600 : theme.colors.neutral600};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:hover {
|
|
44
|
+
svg {
|
|
45
|
+
path {
|
|
46
|
+
fill: ${({ theme }) => theme.colors.primary600};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
const ActionsStack = styled(Stack)`
|
|
53
|
+
& .drag-handle {
|
|
54
|
+
background: unset;
|
|
55
|
+
|
|
56
|
+
svg {
|
|
57
|
+
path {
|
|
58
|
+
fill: ${({ theme, expanded }) => (expanded ? theme.colors.primary600 : undefined)};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:hover {
|
|
63
|
+
svg {
|
|
64
|
+
path {
|
|
65
|
+
/* keeps the hover style of the accordion */
|
|
66
|
+
fill: ${({ theme }) => theme.colors.primary600};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
// Issues:
|
|
74
|
+
// https://github.com/react-dnd/react-dnd/issues/1368
|
|
75
|
+
// https://github.com/frontend-collective/react-sortable-tree/issues/490
|
|
76
|
+
|
|
77
|
+
const DraggedItem = ({
|
|
78
|
+
componentFieldName,
|
|
79
|
+
componentUid,
|
|
80
|
+
fields,
|
|
81
|
+
index,
|
|
82
|
+
isOpen,
|
|
83
|
+
isReadOnly,
|
|
84
|
+
mainField,
|
|
85
|
+
moveComponentField,
|
|
86
|
+
onClickToggle,
|
|
87
|
+
toggleCollapses,
|
|
88
|
+
onGrabItem,
|
|
89
|
+
onDropItem,
|
|
90
|
+
onCancel,
|
|
91
|
+
}) => {
|
|
92
|
+
const { modifiedData, removeRepeatableField, triggerFormValidation } = useCMEditViewDataManager();
|
|
93
|
+
|
|
94
|
+
const displayedValue = toString(
|
|
95
|
+
get(modifiedData, [...componentFieldName.split('.'), mainField], '')
|
|
96
|
+
);
|
|
97
|
+
const accordionRef = useRef(null);
|
|
98
|
+
const { formatMessage } = useIntl();
|
|
99
|
+
|
|
100
|
+
const [parentFieldName] = componentFieldName.split('.');
|
|
101
|
+
|
|
102
|
+
const [{ handlerId, isDragging, handleKeyDown }, boxRef, dropRef, dragRef, dragPreviewRef] =
|
|
103
|
+
useDragAndDrop(!isReadOnly, {
|
|
104
|
+
type: `${ItemTypes.COMPONENT}_${parentFieldName}`,
|
|
105
|
+
index,
|
|
106
|
+
item: {
|
|
107
|
+
displayedValue,
|
|
108
|
+
},
|
|
109
|
+
onMoveItem: moveComponentField,
|
|
110
|
+
onStart() {
|
|
111
|
+
// Close all collapses
|
|
112
|
+
toggleCollapses();
|
|
113
|
+
},
|
|
114
|
+
onEnd() {
|
|
115
|
+
// Update the errors
|
|
116
|
+
triggerFormValidation();
|
|
117
|
+
},
|
|
118
|
+
onGrabItem,
|
|
119
|
+
onDropItem,
|
|
120
|
+
onCancel,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
|
|
125
|
+
}, [dragPreviewRef, index]);
|
|
126
|
+
|
|
127
|
+
const composedAccordionRefs = composeRefs(accordionRef, dragRef);
|
|
128
|
+
const composedBoxRefs = composeRefs(boxRef, dropRef);
|
|
129
|
+
|
|
130
|
+
const { lazyComponentStore } = useLazyComponents();
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<Box ref={composedBoxRefs}>
|
|
134
|
+
{isDragging ? (
|
|
135
|
+
<Preview />
|
|
136
|
+
) : (
|
|
137
|
+
<Accordion expanded={isOpen} onToggle={onClickToggle} id={componentFieldName} size="S">
|
|
138
|
+
<AccordionToggle
|
|
139
|
+
action={
|
|
140
|
+
isReadOnly ? null : (
|
|
141
|
+
<ActionsStack horizontal spacing={0} expanded={isOpen}>
|
|
142
|
+
<CustomIconButton
|
|
143
|
+
expanded={isOpen}
|
|
144
|
+
noBorder
|
|
145
|
+
onClick={() => {
|
|
146
|
+
removeRepeatableField(componentFieldName);
|
|
147
|
+
toggleCollapses();
|
|
148
|
+
}}
|
|
149
|
+
label={formatMessage({
|
|
150
|
+
id: getTrad('containers.Edit.delete'),
|
|
151
|
+
defaultMessage: 'Delete',
|
|
152
|
+
})}
|
|
153
|
+
icon={<Trash />}
|
|
154
|
+
/>
|
|
155
|
+
<IconButton
|
|
156
|
+
className="drag-handle"
|
|
157
|
+
ref={composedAccordionRefs}
|
|
158
|
+
forwardedAs="div"
|
|
159
|
+
role="button"
|
|
160
|
+
noBorder
|
|
161
|
+
tabIndex={0}
|
|
162
|
+
onClick={(e) => e.stopPropagation()}
|
|
163
|
+
data-handler-id={handlerId}
|
|
164
|
+
label={formatMessage({
|
|
165
|
+
id: getTrad('components.DragHandle-label'),
|
|
166
|
+
defaultMessage: 'Drag',
|
|
167
|
+
})}
|
|
168
|
+
onKeyDown={handleKeyDown}
|
|
169
|
+
>
|
|
170
|
+
<Drag />
|
|
171
|
+
</IconButton>
|
|
172
|
+
</ActionsStack>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
title={displayedValue}
|
|
176
|
+
togglePosition="left"
|
|
177
|
+
/>
|
|
178
|
+
<AccordionContent>
|
|
179
|
+
<Stack background="neutral100" padding={6} spacing={6}>
|
|
180
|
+
{fields.map((fieldRow, key) => {
|
|
181
|
+
return (
|
|
182
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
183
|
+
<Grid gap={4} key={key}>
|
|
184
|
+
{fieldRow.map(({ name, fieldSchema, metadatas, queryInfos, size }) => {
|
|
185
|
+
const isComponent = fieldSchema.type === 'component';
|
|
186
|
+
const keys = `${componentFieldName}.${name}`;
|
|
187
|
+
|
|
188
|
+
if (isComponent) {
|
|
189
|
+
const componentUid = fieldSchema.component;
|
|
190
|
+
|
|
191
|
+
return (
|
|
192
|
+
<GridItem col={size} s={12} xs={12} key={name}>
|
|
193
|
+
<FieldComponent
|
|
194
|
+
componentUid={componentUid}
|
|
195
|
+
intlLabel={{
|
|
196
|
+
id: metadatas.label,
|
|
197
|
+
defaultMessage: metadatas.label,
|
|
198
|
+
}}
|
|
199
|
+
isRepeatable={fieldSchema.repeatable}
|
|
200
|
+
isNested
|
|
201
|
+
name={keys}
|
|
202
|
+
max={fieldSchema.max}
|
|
203
|
+
min={fieldSchema.min}
|
|
204
|
+
required={fieldSchema.required}
|
|
205
|
+
/>
|
|
206
|
+
</GridItem>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<GridItem key={keys} col={size} s={12} xs={12}>
|
|
212
|
+
<Inputs
|
|
213
|
+
componentUid={componentUid}
|
|
214
|
+
fieldSchema={fieldSchema}
|
|
215
|
+
keys={keys}
|
|
216
|
+
metadatas={metadatas}
|
|
217
|
+
queryInfos={queryInfos}
|
|
218
|
+
size={size}
|
|
219
|
+
customFieldInputs={lazyComponentStore}
|
|
220
|
+
/>
|
|
221
|
+
</GridItem>
|
|
222
|
+
);
|
|
223
|
+
})}
|
|
224
|
+
</Grid>
|
|
225
|
+
);
|
|
226
|
+
})}
|
|
227
|
+
</Stack>
|
|
228
|
+
</AccordionContent>
|
|
229
|
+
</Accordion>
|
|
230
|
+
)}
|
|
231
|
+
</Box>
|
|
232
|
+
);
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
DraggedItem.defaultProps = {
|
|
236
|
+
componentUid: undefined,
|
|
237
|
+
fields: [],
|
|
238
|
+
isReadOnly: false,
|
|
239
|
+
isOpen: false,
|
|
240
|
+
onGrabItem: undefined,
|
|
241
|
+
onDropItem: undefined,
|
|
242
|
+
onCancel: undefined,
|
|
243
|
+
toggleCollapses() {},
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
DraggedItem.propTypes = {
|
|
247
|
+
componentFieldName: PropTypes.string.isRequired,
|
|
248
|
+
componentUid: PropTypes.string,
|
|
249
|
+
fields: PropTypes.array,
|
|
250
|
+
index: PropTypes.number.isRequired,
|
|
251
|
+
isOpen: PropTypes.bool,
|
|
252
|
+
isReadOnly: PropTypes.bool,
|
|
253
|
+
mainField: PropTypes.string.isRequired,
|
|
254
|
+
moveComponentField: PropTypes.func.isRequired,
|
|
255
|
+
onGrabItem: PropTypes.func,
|
|
256
|
+
onDropItem: PropTypes.func,
|
|
257
|
+
onCancel: PropTypes.func,
|
|
258
|
+
onClickToggle: PropTypes.func.isRequired,
|
|
259
|
+
toggleCollapses: PropTypes.func,
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export default memo(DraggedItem);
|
|
File without changes
|