@strapi/admin 4.11.0-exp.push-transfer-push-stuck → 4.11.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/Providers/index.js +32 -32
- package/admin/src/components/Theme/index.js +5 -3
- package/admin/src/content-manager/components/ComponentIcon/ComponentIcon.js +16 -26
- package/admin/src/content-manager/components/ComponentIcon/constants.js +133 -0
- package/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js +307 -0
- package/admin/src/content-manager/components/DynamicTable/index.js +20 -4
- package/admin/src/content-manager/components/DynamicZone/components/AddComponentButton.js +32 -95
- package/admin/src/content-manager/components/DynamicZone/components/ComponentCard.js +10 -2
- package/admin/src/content-manager/components/DynamicZone/components/ComponentCategory.js +63 -15
- package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker.js +50 -63
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +132 -58
- package/admin/src/content-manager/components/DynamicZone/components/DynamicZoneLabel.js +29 -37
- package/admin/src/content-manager/components/DynamicZone/index.js +131 -83
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +31 -8
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +18 -6
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +0 -1
- package/admin/src/content-manager/components/Inputs/index.js +18 -11
- package/admin/src/content-manager/components/Inputs/utils/index.js +0 -1
- package/admin/src/content-manager/pages/EditSettingsView/components/DynamicZoneList.js +7 -1
- package/admin/src/content-manager/pages/EditView/index.js +1 -1
- package/admin/src/content-manager/pages/ListView/index.js +118 -2
- package/admin/src/content-manager/utils/index.js +2 -0
- package/admin/src/content-manager/{components/EditViewDataManagerProvider/utils → utils}/schema.js +1 -1
- package/admin/src/hooks/useContentTypes/useContentTypes.js +0 -2
- package/admin/src/index.js +4 -3
- package/admin/src/injectionZones.js +6 -1
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableCE.js +13 -0
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/Events/index.js +331 -0
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/Combobox.js +54 -4
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/index.js +12 -23
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +129 -116
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +62 -0
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +59 -64
- package/admin/src/translations/ar.json +684 -1
- package/admin/src/translations/en.json +12 -1
- package/build/3562.e0b1a0b3.chunk.js +50 -0
- package/build/371.6e4e2c1f.chunk.js +71 -0
- package/build/5297.31c9ffdc.chunk.js +39 -0
- package/build/5542.64b623c9.chunk.js +63 -0
- package/build/{5563.79950369.chunk.js → 5563.badbffde.chunk.js} +2 -2
- package/build/6691.f7a3b5ac.chunk.js +105 -0
- package/build/6970.d456705f.chunk.js +1 -0
- package/build/{7259.5cc67413.chunk.js → 7259.5d0de931.chunk.js} +1 -1
- package/build/8976.0022f5a3.chunk.js +50 -0
- package/build/{1657.ca8562dd.chunk.js → 9932.5ef475c5.chunk.js} +54 -62
- package/build/Admin-authenticatedApp.ab2b5910.chunk.js +79 -0
- package/build/{Admin_InternalErrorPage.96ceaae1.chunk.js → Admin_InternalErrorPage.f25f04f3.chunk.js} +1 -1
- package/build/Admin_homePage.05063e43.chunk.js +73 -0
- package/build/Admin_marketplace.005d2d5b.chunk.js +55 -0
- package/build/Admin_pluginsPage.5d9d4060.chunk.js +6 -0
- package/build/{Admin_profilePage.a8fa3a56.chunk.js → Admin_profilePage.ab7b94d7.chunk.js} +2 -2
- package/build/Admin_settingsPage.07a6a5f0.chunk.js +79 -0
- package/build/{Upload_ConfigureTheView.aa64ed9a.chunk.js → Upload_ConfigureTheView.121deffb.chunk.js} +1 -1
- package/build/admin-app.7cc667be.chunk.js +63 -0
- package/build/{admin-edit-roles-page.0d12b741.chunk.js → admin-edit-roles-page.bfe3304d.chunk.js} +3 -3
- package/build/{admin-edit-users.f9ce7844.chunk.js → admin-edit-users.6efe0382.chunk.js} +2 -2
- package/build/admin-roles-list.b2577370.chunk.js +23 -0
- package/build/admin-users.4af49ccf.chunk.js +26 -0
- package/build/{api-tokens-create-page.973d2816.chunk.js → api-tokens-create-page.65411a36.chunk.js} +1 -1
- package/build/{api-tokens-edit-page.29725c5e.chunk.js → api-tokens-edit-page.60312cb6.chunk.js} +1 -1
- package/build/{api-tokens-list-page.66c4fbdd.chunk.js → api-tokens-list-page.01a4d5cd.chunk.js} +2 -2
- package/build/ar-json.f530bc3f.chunk.js +1 -0
- package/build/audit-logs-settings-page.b165679b.chunk.js +16 -0
- package/build/content-manager.8cc6c3f9.chunk.js +1094 -0
- package/build/content-type-builder-list-view.58f9ed20.chunk.js +211 -0
- package/build/{content-type-builder-translation-en-json.af293c9e.chunk.js → content-type-builder-translation-en-json.f592325b.chunk.js} +1 -1
- package/build/content-type-builder.baeb0413.chunk.js +132 -0
- package/build/email-settings-page.8caad83f.chunk.js +11 -0
- package/build/en-json.a8f34002.chunk.js +1 -0
- package/build/i18n-settings-page.579d5eab.chunk.js +9 -0
- package/build/i18n-translation-en-json.1ec7becf.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/main.1d678f7b.js +2926 -0
- package/build/{review-workflows-settings.56cab253.chunk.js → review-workflows-settings.3a7bae25.chunk.js} +2 -2
- package/build/{runtime~main.adbe36a4.js → runtime~main.9dbd4553.js} +2 -2
- package/build/{sso-settings-page.265e3d72.chunk.js → sso-settings-page.4bb073e0.chunk.js} +1 -1
- package/build/{transfer-tokens-create-page.170acee6.chunk.js → transfer-tokens-create-page.9ec277d7.chunk.js} +1 -1
- package/build/{transfer-tokens-edit-page.6cf23295.chunk.js → transfer-tokens-edit-page.fa5ade14.chunk.js} +1 -1
- package/build/{transfer-tokens-list-page.c3fec4c1.chunk.js → transfer-tokens-list-page.5d68d590.chunk.js} +2 -2
- package/build/upload-settings.2c1565d6.chunk.js +14 -0
- package/build/upload.257b2aef.chunk.js +26 -0
- package/build/users-advanced-settings-page.ddd29040.chunk.js +9 -0
- package/build/users-email-settings-page.717e2a51.chunk.js +24 -0
- package/build/users-providers-settings-page.c7eae829.chunk.js +29 -0
- package/build/{users-roles-settings-page.2549794b.chunk.js → users-roles-settings-page.63cf2838.chunk.js} +1 -1
- package/build/webhook-edit-page.8576742e.chunk.js +31 -0
- package/build/webhook-list-page.abf5747c.chunk.js +63 -0
- package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableEE.js +23 -0
- package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
- package/ee/server/services/review-workflows/review-workflows.js +4 -0
- package/package.json +22 -24
- package/server/controllers/webhooks.js +6 -6
- package/admin/src/content-manager/components/DynamicTable/ConfirmDialogDeleteAll/index.js +0 -73
- package/admin/src/content-manager/components/DynamicZone/utils/connect.js +0 -12
- package/admin/src/content-manager/components/DynamicZone/utils/select.js +0 -53
- package/admin/src/content-manager/components/Inputs/utils/getStep.js +0 -13
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/EventRow.js +0 -70
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +0 -174
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/keys.js +0 -39
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/fieldsRegex.js +0 -4
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/schema.js +0 -35
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/reducer.js +0 -100
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/utils/formatData.js +0 -20
- package/build/3081.c2cdfac8.chunk.js +0 -108
- package/build/3816.60f858cf.chunk.js +0 -211
- package/build/462.a073ff1f.chunk.js +0 -71
- package/build/5542.002522eb.chunk.js +0 -71
- package/build/617.87b2fe96.chunk.js +0 -155
- package/build/6858.85d76858.chunk.js +0 -50
- package/build/6970.6a329e15.chunk.js +0 -1
- package/build/Admin-authenticatedApp.d425b485.chunk.js +0 -79
- package/build/Admin_homePage.107a9fe0.chunk.js +0 -73
- package/build/Admin_marketplace.717bd7ca.chunk.js +0 -55
- package/build/Admin_pluginsPage.7df6b5a9.chunk.js +0 -6
- package/build/Admin_settingsPage.1394aaf2.chunk.js +0 -79
- package/build/admin-app.ac5b1f59.chunk.js +0 -63
- package/build/admin-roles-list.e8bf9685.chunk.js +0 -31
- package/build/admin-users.751b28b2.chunk.js +0 -34
- package/build/ar-json.39e54aba.chunk.js +0 -1
- package/build/audit-logs-settings-page.3c6cea81.chunk.js +0 -129
- package/build/content-manager.70548048.chunk.js +0 -1123
- package/build/content-type-builder-list-view.1e821eb9.chunk.js +0 -215
- package/build/content-type-builder.b10576e7.chunk.js +0 -126
- package/build/email-settings-page.dba83275.chunk.js +0 -11
- package/build/en-json.d965e364.chunk.js +0 -1
- package/build/i18n-settings-page.55628f74.chunk.js +0 -114
- package/build/i18n-translation-en-json.60af6722.chunk.js +0 -1
- package/build/main.d9d9ed10.js +0 -2630
- package/build/upload-settings.63d99bf5.chunk.js +0 -14
- package/build/upload.c50d8c7a.chunk.js +0 -34
- package/build/users-advanced-settings-page.4f49ca57.chunk.js +0 -9
- package/build/users-email-settings-page.d2429d0a.chunk.js +0 -24
- package/build/users-providers-settings-page.50c5ba27.chunk.js +0 -29
- package/build/webhook-edit-page.ddd5963d.chunk.js +0 -128
- package/build/webhook-list-page.e2fca9f8.chunk.js +0 -71
|
@@ -12,67 +12,19 @@ import {
|
|
|
12
12
|
IconButton,
|
|
13
13
|
Box,
|
|
14
14
|
Flex,
|
|
15
|
+
VisuallyHidden,
|
|
15
16
|
} from '@strapi/design-system';
|
|
17
|
+
import { Menu, MenuItem } from '@strapi/design-system/v2';
|
|
16
18
|
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
|
|
17
|
-
import { Trash, Drag } from '@strapi/icons';
|
|
19
|
+
import { Trash, Drag, More } from '@strapi/icons';
|
|
18
20
|
|
|
19
21
|
import { useContentTypeLayout, useDragAndDrop } from '../../../hooks';
|
|
20
22
|
import { composeRefs, getTrad, ItemTypes } from '../../../utils';
|
|
21
23
|
|
|
22
24
|
import FieldComponent from '../../FieldComponent';
|
|
25
|
+
import { ComponentIcon } from '../../ComponentIcon';
|
|
23
26
|
|
|
24
|
-
const
|
|
25
|
-
/*
|
|
26
|
-
we need to remove the background from the button but we can't
|
|
27
|
-
wrap the element in styled because it breaks the forwardedAs which
|
|
28
|
-
we need for drag handler to work on firefox
|
|
29
|
-
*/
|
|
30
|
-
div[role='button'] {
|
|
31
|
-
background: transparent;
|
|
32
|
-
}
|
|
33
|
-
`;
|
|
34
|
-
|
|
35
|
-
const IconButtonCustom = styled(IconButton)`
|
|
36
|
-
background-color: transparent;
|
|
37
|
-
|
|
38
|
-
svg path {
|
|
39
|
-
fill: ${({ theme, expanded }) =>
|
|
40
|
-
expanded ? theme.colors.primary600 : theme.colors.neutral600};
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
|
|
44
|
-
// TODO: Delete once https://github.com/strapi/design-system/pull/858
|
|
45
|
-
// is merged and released.
|
|
46
|
-
const StyledBox = styled(Box)`
|
|
47
|
-
> div:first-child {
|
|
48
|
-
box-shadow: ${({ theme }) => theme.shadows.tableShadow};
|
|
49
|
-
}
|
|
50
|
-
`;
|
|
51
|
-
|
|
52
|
-
const AccordionContentRadius = styled(Box)`
|
|
53
|
-
border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
|
|
54
|
-
`;
|
|
55
|
-
|
|
56
|
-
const Rectangle = styled(Box)`
|
|
57
|
-
width: ${({ theme }) => theme.spaces[2]};
|
|
58
|
-
height: ${({ theme }) => theme.spaces[4]};
|
|
59
|
-
`;
|
|
60
|
-
|
|
61
|
-
const Preview = styled.span`
|
|
62
|
-
display: block;
|
|
63
|
-
background-color: ${({ theme }) => theme.colors.primary100};
|
|
64
|
-
outline: 1px dashed ${({ theme }) => theme.colors.primary500};
|
|
65
|
-
outline-offset: -1px;
|
|
66
|
-
padding: ${({ theme }) => theme.spaces[6]};
|
|
67
|
-
`;
|
|
68
|
-
|
|
69
|
-
const ComponentContainer = styled(Box)`
|
|
70
|
-
list-style: none;
|
|
71
|
-
padding: 0;
|
|
72
|
-
margin: 0;
|
|
73
|
-
`;
|
|
74
|
-
|
|
75
|
-
const DynamicZoneComponent = ({
|
|
27
|
+
export const DynamicComponent = ({
|
|
76
28
|
componentUid,
|
|
77
29
|
formErrors,
|
|
78
30
|
index,
|
|
@@ -83,6 +35,8 @@ const DynamicZoneComponent = ({
|
|
|
83
35
|
onGrabItem,
|
|
84
36
|
onDropItem,
|
|
85
37
|
onCancel,
|
|
38
|
+
dynamicComponentsByCategory,
|
|
39
|
+
onAddComponent,
|
|
86
40
|
}) => {
|
|
87
41
|
const [isOpen, setIsOpen] = useState(true);
|
|
88
42
|
const { formatMessage } = useIntl();
|
|
@@ -180,11 +134,70 @@ const DynamicZoneComponent = ({
|
|
|
180
134
|
>
|
|
181
135
|
<Drag />
|
|
182
136
|
</IconButton>
|
|
137
|
+
<Menu.Root>
|
|
138
|
+
<Menu.Trigger size="S" endIcon={undefined} paddingLeft={2} paddingRight={2}>
|
|
139
|
+
<More aria-hidden focusable={false} />
|
|
140
|
+
<VisuallyHidden as="span">
|
|
141
|
+
{formatMessage({
|
|
142
|
+
id: getTrad('components.DynamicZone.more-actions'),
|
|
143
|
+
defaultMessage: 'More actions',
|
|
144
|
+
})}
|
|
145
|
+
</VisuallyHidden>
|
|
146
|
+
</Menu.Trigger>
|
|
147
|
+
<Menu.Content>
|
|
148
|
+
<Menu.SubRoot>
|
|
149
|
+
<Menu.SubTrigger>
|
|
150
|
+
{formatMessage({
|
|
151
|
+
id: getTrad('components.DynamicZone.add-item-above'),
|
|
152
|
+
defaultMessage: 'Add component above',
|
|
153
|
+
})}
|
|
154
|
+
</Menu.SubTrigger>
|
|
155
|
+
<Menu.SubContent>
|
|
156
|
+
{Object.entries(dynamicComponentsByCategory).map(([category, components]) => (
|
|
157
|
+
<React.Fragment key={category}>
|
|
158
|
+
<Menu.Label>{category}</Menu.Label>
|
|
159
|
+
{components.map(({ componentUid, info: { displayName } }) => (
|
|
160
|
+
<MenuItem
|
|
161
|
+
key={componentUid}
|
|
162
|
+
onSelect={() => onAddComponent(componentUid, index)}
|
|
163
|
+
>
|
|
164
|
+
{displayName}
|
|
165
|
+
</MenuItem>
|
|
166
|
+
))}
|
|
167
|
+
</React.Fragment>
|
|
168
|
+
))}
|
|
169
|
+
</Menu.SubContent>
|
|
170
|
+
</Menu.SubRoot>
|
|
171
|
+
<Menu.SubRoot>
|
|
172
|
+
<Menu.SubTrigger>
|
|
173
|
+
{formatMessage({
|
|
174
|
+
id: getTrad('components.DynamicZone.add-item-below'),
|
|
175
|
+
defaultMessage: 'Add component below',
|
|
176
|
+
})}
|
|
177
|
+
</Menu.SubTrigger>
|
|
178
|
+
<Menu.SubContent>
|
|
179
|
+
{Object.entries(dynamicComponentsByCategory).map(([category, components]) => (
|
|
180
|
+
<React.Fragment key={category}>
|
|
181
|
+
<Menu.Label>{category}</Menu.Label>
|
|
182
|
+
{components.map(({ componentUid, info: { displayName } }) => (
|
|
183
|
+
<MenuItem
|
|
184
|
+
key={componentUid}
|
|
185
|
+
onSelect={() => onAddComponent(componentUid, index + 1)}
|
|
186
|
+
>
|
|
187
|
+
{displayName}
|
|
188
|
+
</MenuItem>
|
|
189
|
+
))}
|
|
190
|
+
</React.Fragment>
|
|
191
|
+
))}
|
|
192
|
+
</Menu.SubContent>
|
|
193
|
+
</Menu.SubRoot>
|
|
194
|
+
</Menu.Content>
|
|
195
|
+
</Menu.Root>
|
|
183
196
|
</ActionsFlex>
|
|
184
197
|
);
|
|
185
198
|
|
|
186
199
|
return (
|
|
187
|
-
<ComponentContainer as="li">
|
|
200
|
+
<ComponentContainer as="li" width="100%">
|
|
188
201
|
<Flex justifyContent="center">
|
|
189
202
|
<Rectangle background="neutral200" />
|
|
190
203
|
</Flex>
|
|
@@ -194,6 +207,7 @@ const DynamicZoneComponent = ({
|
|
|
194
207
|
) : (
|
|
195
208
|
<Accordion expanded={isOpen} onToggle={handleToggle} size="S" error={errorMessage}>
|
|
196
209
|
<AccordionToggle
|
|
210
|
+
startIcon={<ComponentIcon icon={icon} showBackground={false} size="S" />}
|
|
197
211
|
action={accordionActions}
|
|
198
212
|
title={`${friendlyName}${mainValue}`}
|
|
199
213
|
togglePosition="left"
|
|
@@ -215,26 +229,86 @@ const DynamicZoneComponent = ({
|
|
|
215
229
|
);
|
|
216
230
|
};
|
|
217
231
|
|
|
218
|
-
|
|
232
|
+
const ActionsFlex = styled(Flex)`
|
|
233
|
+
/*
|
|
234
|
+
we need to remove the background from the button but we can't
|
|
235
|
+
wrap the element in styled because it breaks the forwardedAs which
|
|
236
|
+
we need for drag handler to work on firefox
|
|
237
|
+
*/
|
|
238
|
+
div[role='button'] {
|
|
239
|
+
background: transparent;
|
|
240
|
+
}
|
|
241
|
+
`;
|
|
242
|
+
|
|
243
|
+
const IconButtonCustom = styled(IconButton)`
|
|
244
|
+
background-color: transparent;
|
|
245
|
+
|
|
246
|
+
svg path {
|
|
247
|
+
fill: ${({ theme, expanded }) =>
|
|
248
|
+
expanded ? theme.colors.primary600 : theme.colors.neutral600};
|
|
249
|
+
}
|
|
250
|
+
`;
|
|
251
|
+
|
|
252
|
+
// TODO: Delete once https://github.com/strapi/design-system/pull/858
|
|
253
|
+
// is merged and released.
|
|
254
|
+
const StyledBox = styled(Box)`
|
|
255
|
+
> div:first-child {
|
|
256
|
+
box-shadow: ${({ theme }) => theme.shadows.tableShadow};
|
|
257
|
+
}
|
|
258
|
+
`;
|
|
259
|
+
|
|
260
|
+
const AccordionContentRadius = styled(Box)`
|
|
261
|
+
border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
|
|
262
|
+
`;
|
|
263
|
+
|
|
264
|
+
const Rectangle = styled(Box)`
|
|
265
|
+
width: ${({ theme }) => theme.spaces[2]};
|
|
266
|
+
height: ${({ theme }) => theme.spaces[4]};
|
|
267
|
+
`;
|
|
268
|
+
|
|
269
|
+
const Preview = styled.span`
|
|
270
|
+
display: block;
|
|
271
|
+
background-color: ${({ theme }) => theme.colors.primary100};
|
|
272
|
+
outline: 1px dashed ${({ theme }) => theme.colors.primary500};
|
|
273
|
+
outline-offset: -1px;
|
|
274
|
+
padding: ${({ theme }) => theme.spaces[6]};
|
|
275
|
+
`;
|
|
276
|
+
|
|
277
|
+
const ComponentContainer = styled(Box)`
|
|
278
|
+
list-style: none;
|
|
279
|
+
padding: 0;
|
|
280
|
+
margin: 0;
|
|
281
|
+
`;
|
|
282
|
+
|
|
283
|
+
DynamicComponent.defaultProps = {
|
|
284
|
+
dynamicComponentsByCategory: {},
|
|
219
285
|
formErrors: {},
|
|
220
286
|
index: 0,
|
|
221
287
|
isFieldAllowed: true,
|
|
288
|
+
onAddComponent: undefined,
|
|
222
289
|
onGrabItem: undefined,
|
|
223
290
|
onDropItem: undefined,
|
|
224
291
|
onCancel: undefined,
|
|
225
292
|
};
|
|
226
293
|
|
|
227
|
-
|
|
294
|
+
DynamicComponent.propTypes = {
|
|
228
295
|
componentUid: PropTypes.string.isRequired,
|
|
296
|
+
dynamicComponentsByCategory: PropTypes.shape({
|
|
297
|
+
components: PropTypes.arrayOf(
|
|
298
|
+
PropTypes.shape({
|
|
299
|
+
componentUid: PropTypes.string.isRequired,
|
|
300
|
+
info: PropTypes.object,
|
|
301
|
+
})
|
|
302
|
+
),
|
|
303
|
+
}),
|
|
229
304
|
formErrors: PropTypes.object,
|
|
230
305
|
index: PropTypes.number,
|
|
231
306
|
isFieldAllowed: PropTypes.bool,
|
|
232
307
|
name: PropTypes.string.isRequired,
|
|
308
|
+
onAddComponent: PropTypes.func,
|
|
233
309
|
onGrabItem: PropTypes.func,
|
|
234
310
|
onDropItem: PropTypes.func,
|
|
235
311
|
onCancel: PropTypes.func,
|
|
236
312
|
onMoveComponent: PropTypes.func.isRequired,
|
|
237
313
|
onRemoveComponentClick: PropTypes.func.isRequired,
|
|
238
314
|
};
|
|
239
|
-
|
|
240
|
-
export default DynamicZoneComponent;
|
|
@@ -7,15 +7,10 @@
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import { useIntl } from 'react-intl';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
|
-
import styled from 'styled-components';
|
|
11
10
|
import { pxToRem } from '@strapi/helper-plugin';
|
|
12
11
|
import { Box, Flex, Typography } from '@strapi/design-system';
|
|
13
12
|
|
|
14
|
-
const
|
|
15
|
-
border-radius: ${pxToRem(26)};
|
|
16
|
-
`;
|
|
17
|
-
|
|
18
|
-
const DynamicZoneLabel = ({
|
|
13
|
+
export const DynamicZoneLabel = ({
|
|
19
14
|
label,
|
|
20
15
|
labelAction,
|
|
21
16
|
name,
|
|
@@ -28,36 +23,35 @@ const DynamicZoneLabel = ({
|
|
|
28
23
|
|
|
29
24
|
return (
|
|
30
25
|
<Flex justifyContent="center">
|
|
31
|
-
<Box
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
</Flex>
|
|
52
|
-
{intlDescription && (
|
|
53
|
-
<Box paddingTop={1} maxWidth={pxToRem(356)}>
|
|
54
|
-
<Typography variant="pi" textColor="neutral600" ellipsis>
|
|
55
|
-
{formatMessage(intlDescription)}
|
|
56
|
-
</Typography>
|
|
57
|
-
</Box>
|
|
58
|
-
)}
|
|
26
|
+
<Box
|
|
27
|
+
paddingTop={3}
|
|
28
|
+
paddingBottom={3}
|
|
29
|
+
paddingRight={4}
|
|
30
|
+
paddingLeft={4}
|
|
31
|
+
borderRadius={26}
|
|
32
|
+
background="neutral0"
|
|
33
|
+
shadow="filterShadow"
|
|
34
|
+
color="neutral500"
|
|
35
|
+
>
|
|
36
|
+
<Flex direction="column" justifyContent="center">
|
|
37
|
+
<Flex maxWidth={pxToRem(356)}>
|
|
38
|
+
<Typography variant="pi" textColor="neutral600" fontWeight="bold" ellipsis>
|
|
39
|
+
{intlLabel}
|
|
40
|
+
</Typography>
|
|
41
|
+
<Typography variant="pi" textColor="neutral600" fontWeight="bold">
|
|
42
|
+
({numberOfComponents})
|
|
43
|
+
</Typography>
|
|
44
|
+
{required && <Typography textColor="danger600">*</Typography>}
|
|
45
|
+
{labelAction && <Box paddingLeft={1}>{labelAction}</Box>}
|
|
59
46
|
</Flex>
|
|
60
|
-
|
|
47
|
+
{intlDescription && (
|
|
48
|
+
<Box paddingTop={1} maxWidth={pxToRem(356)}>
|
|
49
|
+
<Typography variant="pi" textColor="neutral600" ellipsis>
|
|
50
|
+
{formatMessage(intlDescription)}
|
|
51
|
+
</Typography>
|
|
52
|
+
</Box>
|
|
53
|
+
)}
|
|
54
|
+
</Flex>
|
|
61
55
|
</Box>
|
|
62
56
|
</Flex>
|
|
63
57
|
);
|
|
@@ -82,5 +76,3 @@ DynamicZoneLabel.propTypes = {
|
|
|
82
76
|
numberOfComponents: PropTypes.number,
|
|
83
77
|
required: PropTypes.bool,
|
|
84
78
|
};
|
|
85
|
-
|
|
86
|
-
export default DynamicZoneLabel;
|
|
@@ -1,76 +1,113 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import get from 'lodash/get';
|
|
3
|
-
import isEqual from 'lodash/isEqual';
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
4
2
|
import PropTypes from 'prop-types';
|
|
5
3
|
import { Box, Flex, VisuallyHidden } from '@strapi/design-system';
|
|
6
|
-
import { NotAllowedInput, useNotification } from '@strapi/helper-plugin';
|
|
4
|
+
import { NotAllowedInput, useNotification, useCMEditViewDataManager } from '@strapi/helper-plugin';
|
|
7
5
|
import { useIntl } from 'react-intl';
|
|
8
6
|
|
|
9
7
|
import { getTrad } from '../../utils';
|
|
10
8
|
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
import
|
|
15
|
-
import AddComponentButton from './components/AddComponentButton';
|
|
16
|
-
import DynamicZoneLabel from './components/DynamicZoneLabel';
|
|
17
|
-
import ComponentPicker from './components/ComponentPicker';
|
|
9
|
+
import { DynamicComponent } from './components/DynamicComponent';
|
|
10
|
+
import { AddComponentButton } from './components/AddComponentButton';
|
|
11
|
+
import { DynamicZoneLabel } from './components/DynamicZoneLabel';
|
|
12
|
+
import { ComponentPicker } from './components/ComponentPicker';
|
|
18
13
|
|
|
19
14
|
import { useContentTypeLayout } from '../../hooks';
|
|
20
15
|
|
|
21
|
-
const DynamicZone = ({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
formErrors,
|
|
26
|
-
isCreatingEntry,
|
|
27
|
-
isFieldAllowed,
|
|
28
|
-
isFieldReadable,
|
|
29
|
-
labelAction,
|
|
30
|
-
moveComponentField,
|
|
31
|
-
removeComponentFromDynamicZone,
|
|
32
|
-
dynamicDisplayedComponents,
|
|
33
|
-
fieldSchema,
|
|
34
|
-
metadatas,
|
|
35
|
-
}) => {
|
|
16
|
+
const DynamicZone = ({ name, labelAction, fieldSchema, metadatas }) => {
|
|
17
|
+
// We cannot use the default props here
|
|
18
|
+
const { max = Infinity, min = -Infinity, components = [], required = false } = fieldSchema;
|
|
19
|
+
|
|
36
20
|
const [addComponentIsOpen, setAddComponentIsOpen] = useState(false);
|
|
37
21
|
const [liveText, setLiveText] = useState('');
|
|
38
22
|
|
|
23
|
+
const {
|
|
24
|
+
addComponentToDynamicZone,
|
|
25
|
+
createActionAllowedFields,
|
|
26
|
+
isCreatingEntry,
|
|
27
|
+
formErrors,
|
|
28
|
+
modifiedData,
|
|
29
|
+
moveComponentField,
|
|
30
|
+
removeComponentFromDynamicZone,
|
|
31
|
+
readActionAllowedFields,
|
|
32
|
+
updateActionAllowedFields,
|
|
33
|
+
} = useCMEditViewDataManager();
|
|
34
|
+
|
|
35
|
+
const dynamicDisplayedComponents = useMemo(
|
|
36
|
+
() =>
|
|
37
|
+
(modifiedData?.[name] ?? []).map((data) => {
|
|
38
|
+
return {
|
|
39
|
+
componentUid: data.__component,
|
|
40
|
+
id: data.id ?? data.__temp_key__,
|
|
41
|
+
};
|
|
42
|
+
}),
|
|
43
|
+
[modifiedData, name]
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const { getComponentLayout } = useContentTypeLayout();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @type {Record<string, Array<{category: string; info: unknown, attributes: Record<string, unknown>}>>}
|
|
50
|
+
*/
|
|
51
|
+
const dynamicComponentsByCategory = useMemo(() => {
|
|
52
|
+
return components.reduce((acc, componentUid) => {
|
|
53
|
+
const { category, info, attributes } = getComponentLayout(componentUid);
|
|
54
|
+
const component = { componentUid, info, attributes };
|
|
55
|
+
|
|
56
|
+
if (!acc[category]) {
|
|
57
|
+
acc[category] = [];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
acc[category] = [...acc[category], component];
|
|
61
|
+
|
|
62
|
+
return acc;
|
|
63
|
+
}, {});
|
|
64
|
+
}, [components, getComponentLayout]);
|
|
65
|
+
|
|
39
66
|
const { formatMessage } = useIntl();
|
|
40
67
|
|
|
41
68
|
const toggleNotification = useNotification();
|
|
42
|
-
|
|
69
|
+
|
|
70
|
+
const isFieldAllowed = useMemo(() => {
|
|
71
|
+
const allowedFields = isCreatingEntry ? createActionAllowedFields : updateActionAllowedFields;
|
|
72
|
+
|
|
73
|
+
return allowedFields.includes(name);
|
|
74
|
+
}, [name, isCreatingEntry, createActionAllowedFields, updateActionAllowedFields]);
|
|
75
|
+
|
|
76
|
+
const isFieldReadable = useMemo(() => {
|
|
77
|
+
const allowedFields = isCreatingEntry ? [] : readActionAllowedFields;
|
|
78
|
+
|
|
79
|
+
return allowedFields.includes(name);
|
|
80
|
+
}, [name, isCreatingEntry, readActionAllowedFields]);
|
|
43
81
|
|
|
44
82
|
const dynamicDisplayedComponentsLength = dynamicDisplayedComponents.length;
|
|
45
83
|
const intlDescription = metadatas.description
|
|
46
84
|
? { id: metadatas.description, defaultMessage: metadatas.description }
|
|
47
85
|
: null;
|
|
48
86
|
|
|
49
|
-
|
|
50
|
-
const { max = Infinity, min = -Infinity } = fieldSchema;
|
|
51
|
-
const dynamicZoneErrors = useMemo(() => {
|
|
52
|
-
return Object.keys(formErrors)
|
|
53
|
-
.filter((key) => {
|
|
54
|
-
return key === name;
|
|
55
|
-
})
|
|
56
|
-
.map((key) => formErrors[key]);
|
|
57
|
-
}, [formErrors, name]);
|
|
87
|
+
const dynamicZoneError = formErrors[name];
|
|
58
88
|
|
|
59
89
|
const missingComponentNumber = min - dynamicDisplayedComponentsLength;
|
|
60
|
-
const hasError =
|
|
61
|
-
|
|
62
|
-
const hasMinError =
|
|
63
|
-
dynamicZoneErrors.length > 0 && get(dynamicZoneErrors, [0, 'id'], '').includes('min');
|
|
90
|
+
const hasError = !!dynamicZoneError;
|
|
64
91
|
|
|
65
|
-
const
|
|
66
|
-
hasError && get(dynamicZoneErrors, [0, 'id'], '') === 'components.Input.error.validation.max';
|
|
67
|
-
|
|
68
|
-
const handleAddComponent = (componentUid) => {
|
|
92
|
+
const handleAddComponent = (componentUid, position) => {
|
|
69
93
|
setAddComponentIsOpen(false);
|
|
70
94
|
|
|
71
95
|
const componentLayoutData = getComponentLayout(componentUid);
|
|
72
96
|
|
|
73
|
-
|
|
97
|
+
const allComponents = Object.values(dynamicComponentsByCategory).reduce((acc, components) => {
|
|
98
|
+
const componentObjects = components.reduce((acc, { componentUid, attributes }) => {
|
|
99
|
+
acc[componentUid] = {
|
|
100
|
+
attributes,
|
|
101
|
+
uid: componentUid,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return acc;
|
|
105
|
+
}, {});
|
|
106
|
+
|
|
107
|
+
return { ...acc, ...componentObjects };
|
|
108
|
+
}, {});
|
|
109
|
+
|
|
110
|
+
addComponentToDynamicZone(name, componentLayoutData, allComponents, hasError, position);
|
|
74
111
|
};
|
|
75
112
|
|
|
76
113
|
const handleClickOpenPicker = () => {
|
|
@@ -160,6 +197,38 @@ const DynamicZone = ({
|
|
|
160
197
|
removeComponentFromDynamicZone(name, currentIndex);
|
|
161
198
|
};
|
|
162
199
|
|
|
200
|
+
const renderButtonLabel = () => {
|
|
201
|
+
if (addComponentIsOpen) {
|
|
202
|
+
return formatMessage({ id: 'app.utils.close-label', defaultMessage: 'Close' });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (hasError && dynamicZoneError.id.includes('max')) {
|
|
206
|
+
return formatMessage({
|
|
207
|
+
id: 'components.Input.error.validation.max',
|
|
208
|
+
defaultMessage: 'The value is too high.',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (hasError && dynamicZoneError.id.includes('min')) {
|
|
213
|
+
return formatMessage(
|
|
214
|
+
{
|
|
215
|
+
id: getTrad(`components.DynamicZone.missing-components`),
|
|
216
|
+
defaultMessage:
|
|
217
|
+
'There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}',
|
|
218
|
+
},
|
|
219
|
+
{ number: missingComponentNumber }
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return formatMessage(
|
|
224
|
+
{
|
|
225
|
+
id: getTrad('components.DynamicZone.add-component'),
|
|
226
|
+
defaultMessage: 'Add a component to {componentName}',
|
|
227
|
+
},
|
|
228
|
+
{ componentName: metadatas.label || name }
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
163
232
|
if (!isFieldAllowed && (isCreatingEntry || (!isFieldReadable && !isCreatingEntry))) {
|
|
164
233
|
return (
|
|
165
234
|
<NotAllowedInput
|
|
@@ -183,7 +252,7 @@ const DynamicZone = ({
|
|
|
183
252
|
labelAction={labelAction}
|
|
184
253
|
name={name}
|
|
185
254
|
numberOfComponents={dynamicDisplayedComponentsLength}
|
|
186
|
-
required={
|
|
255
|
+
required={required}
|
|
187
256
|
/>
|
|
188
257
|
<VisuallyHidden id={ariaDescriptionId}>
|
|
189
258
|
{formatMessage({
|
|
@@ -194,7 +263,7 @@ const DynamicZone = ({
|
|
|
194
263
|
<VisuallyHidden aria-live="assertive">{liveText}</VisuallyHidden>
|
|
195
264
|
<ol aria-describedby={ariaDescriptionId}>
|
|
196
265
|
{dynamicDisplayedComponents.map(({ componentUid, id }, index) => (
|
|
197
|
-
<
|
|
266
|
+
<DynamicComponent
|
|
198
267
|
componentUid={componentUid}
|
|
199
268
|
formErrors={formErrors}
|
|
200
269
|
key={`${componentUid}-${id}`}
|
|
@@ -206,26 +275,26 @@ const DynamicZone = ({
|
|
|
206
275
|
onCancel={handleCancel}
|
|
207
276
|
onDropItem={handleDropItem}
|
|
208
277
|
onGrabItem={handleGrabItem}
|
|
278
|
+
onAddComponent={handleAddComponent}
|
|
279
|
+
dynamicComponentsByCategory={dynamicComponentsByCategory}
|
|
209
280
|
/>
|
|
210
281
|
))}
|
|
211
282
|
</ol>
|
|
212
283
|
</Box>
|
|
213
284
|
)}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
onClick={handleClickOpenPicker}
|
|
225
|
-
/>
|
|
285
|
+
<Flex justifyContent="center">
|
|
286
|
+
<AddComponentButton
|
|
287
|
+
hasError={hasError}
|
|
288
|
+
isDisabled={!isFieldAllowed}
|
|
289
|
+
isOpen={addComponentIsOpen}
|
|
290
|
+
onClick={handleClickOpenPicker}
|
|
291
|
+
>
|
|
292
|
+
{renderButtonLabel()}
|
|
293
|
+
</AddComponentButton>
|
|
294
|
+
</Flex>
|
|
226
295
|
<ComponentPicker
|
|
296
|
+
dynamicComponentsByCategory={dynamicComponentsByCategory}
|
|
227
297
|
isOpen={addComponentIsOpen}
|
|
228
|
-
components={fieldSchema.components ?? []}
|
|
229
298
|
onClickAddComponent={handleAddComponent}
|
|
230
299
|
/>
|
|
231
300
|
</Flex>
|
|
@@ -233,44 +302,23 @@ const DynamicZone = ({
|
|
|
233
302
|
};
|
|
234
303
|
|
|
235
304
|
DynamicZone.defaultProps = {
|
|
236
|
-
|
|
237
|
-
fieldSchema: {
|
|
238
|
-
max: Infinity,
|
|
239
|
-
min: -Infinity,
|
|
240
|
-
},
|
|
305
|
+
fieldSchema: {},
|
|
241
306
|
labelAction: null,
|
|
242
307
|
};
|
|
243
308
|
|
|
244
309
|
DynamicZone.propTypes = {
|
|
245
|
-
addComponentToDynamicZone: PropTypes.func.isRequired,
|
|
246
|
-
dynamicDisplayedComponents: PropTypes.arrayOf(
|
|
247
|
-
PropTypes.shape({
|
|
248
|
-
componentUid: PropTypes.string.isRequired,
|
|
249
|
-
id: PropTypes.number.isRequired,
|
|
250
|
-
})
|
|
251
|
-
),
|
|
252
310
|
fieldSchema: PropTypes.shape({
|
|
253
|
-
components: PropTypes.array
|
|
311
|
+
components: PropTypes.array,
|
|
254
312
|
max: PropTypes.number,
|
|
255
313
|
min: PropTypes.number,
|
|
256
314
|
required: PropTypes.bool,
|
|
257
315
|
}),
|
|
258
|
-
formErrors: PropTypes.object.isRequired,
|
|
259
|
-
isCreatingEntry: PropTypes.bool.isRequired,
|
|
260
|
-
isFieldAllowed: PropTypes.bool.isRequired,
|
|
261
|
-
isFieldReadable: PropTypes.bool.isRequired,
|
|
262
316
|
labelAction: PropTypes.element,
|
|
263
317
|
metadatas: PropTypes.shape({
|
|
264
318
|
description: PropTypes.string,
|
|
265
319
|
label: PropTypes.string,
|
|
266
320
|
}).isRequired,
|
|
267
|
-
moveComponentField: PropTypes.func.isRequired,
|
|
268
321
|
name: PropTypes.string.isRequired,
|
|
269
|
-
removeComponentFromDynamicZone: PropTypes.func.isRequired,
|
|
270
322
|
};
|
|
271
323
|
|
|
272
|
-
const Memoized = memo(DynamicZone, isEqual);
|
|
273
|
-
|
|
274
|
-
export default connect(Memoized, select);
|
|
275
|
-
|
|
276
324
|
export { DynamicZone };
|