@strapi/admin 4.11.0-beta.1 → 4.11.0-exp.9xg4-3qfm-9w8f.1
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 +3 -5
- package/admin/src/content-manager/components/DynamicTable/ConfirmDialogDeleteAll/index.js +73 -0
- package/admin/src/content-manager/components/DynamicTable/index.js +4 -20
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +21 -7
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +1 -0
- package/admin/src/content-manager/{utils → components/EditViewDataManagerProvider/utils}/schema.js +1 -1
- package/admin/src/content-manager/components/Inputs/index.js +11 -18
- package/admin/src/content-manager/components/Inputs/utils/getStep.js +13 -0
- package/admin/src/content-manager/components/Inputs/utils/index.js +1 -0
- package/admin/src/content-manager/pages/ListView/index.js +2 -118
- package/admin/src/content-manager/utils/index.js +0 -2
- package/admin/src/hooks/useContentTypes/useContentTypes.js +0 -2
- package/admin/src/index.js +4 -3
- package/admin/src/injectionZones.js +1 -6
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
- package/admin/src/translations/en.json +1 -5
- package/build/{1657.ca8562dd.chunk.js → 1657.3f2b2c11.chunk.js} +1 -9
- package/build/3081.7e9329cb.chunk.js +105 -0
- package/build/462.6f8cbd19.chunk.js +71 -0
- package/build/5542.64b623c9.chunk.js +63 -0
- package/build/617.0518c0ba.chunk.js +155 -0
- package/build/6858.85d76858.chunk.js +50 -0
- package/build/6970.6a329e15.chunk.js +1 -0
- package/build/9036.f7ce35cc.chunk.js +211 -0
- package/build/{Admin-authenticatedApp.990df65d.chunk.js → Admin-authenticatedApp.e7ca2959.chunk.js} +2 -2
- package/build/{Admin_homePage.107a9fe0.chunk.js → Admin_homePage.94dc81b1.chunk.js} +16 -16
- package/build/Admin_marketplace.1b0c3d3b.chunk.js +55 -0
- package/build/Admin_pluginsPage.a28b96d5.chunk.js +6 -0
- package/build/{Admin_profilePage.75bc083a.chunk.js → Admin_profilePage.a8fa3a56.chunk.js} +1 -1
- package/build/Admin_settingsPage.ee76d19e.chunk.js +79 -0
- package/build/admin-app.bd209f08.chunk.js +63 -0
- package/build/admin-roles-list.af53b372.chunk.js +23 -0
- package/build/admin-users.0fc77b35.chunk.js +26 -0
- package/build/audit-logs-settings-page.6bc76e7d.chunk.js +121 -0
- package/build/content-manager.8bfce7f0.chunk.js +1123 -0
- package/build/content-type-builder-list-view.26aab6f3.chunk.js +215 -0
- package/build/email-settings-page.63f269ff.chunk.js +11 -0
- package/build/{en-json.0f5cc115.chunk.js → en-json.ba3290b8.chunk.js} +1 -1
- package/build/i18n-settings-page.2ac4ca58.chunk.js +114 -0
- package/build/i18n-translation-en-json.60af6722.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/main.aca47de6.js +2633 -0
- package/build/{review-workflows-settings.4b39b837.chunk.js → review-workflows-settings.56cab253.chunk.js} +1 -1
- package/build/{runtime~main.55d43bd7.js → runtime~main.0dfc909e.js} +1 -1
- package/build/upload-settings.1d187578.chunk.js +14 -0
- package/build/upload.bc340679.chunk.js +26 -0
- package/build/users-advanced-settings-page.7b4bf63a.chunk.js +9 -0
- package/build/users-email-settings-page.035a026c.chunk.js +24 -0
- package/build/users-providers-settings-page.6873dce9.chunk.js +29 -0
- package/build/{users-roles-settings-page.c773086b.chunk.js → users-roles-settings-page.2549794b.chunk.js} +1 -1
- package/build/{webhook-edit-page.ddd5963d.chunk.js → webhook-edit-page.0bc97587.chunk.js} +1 -1
- package/build/webhook-list-page.0861d3e9.chunk.js +63 -0
- package/ee/server/services/review-workflows/review-workflows.js +4 -0
- package/package.json +17 -19
- package/server/controllers/webhooks.js +6 -6
- package/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js +0 -307
- package/build/3081.c2cdfac8.chunk.js +0 -108
- package/build/3562.e0b1a0b3.chunk.js +0 -50
- package/build/456.9b85d4c6.chunk.js +0 -39
- 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/6970.7ea35fbd.chunk.js +0 -1
- package/build/Admin_marketplace.1436fc2b.chunk.js +0 -55
- package/build/Admin_pluginsPage.e1afd5ed.chunk.js +0 -6
- package/build/Admin_settingsPage.bd715ed3.chunk.js +0 -79
- package/build/admin-app.8b102fe2.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/audit-logs-settings-page.3c6cea81.chunk.js +0 -129
- package/build/content-manager.89099707.chunk.js +0 -1123
- package/build/content-type-builder-list-view.1e821eb9.chunk.js +0 -215
- package/build/email-settings-page.4368689f.chunk.js +0 -11
- package/build/i18n-settings-page.7988d872.chunk.js +0 -114
- package/build/i18n-translation-en-json.1ec7becf.chunk.js +0 -1
- package/build/main.5a232c3d.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.2cfb5d24.chunk.js +0 -9
- package/build/users-email-settings-page.bd6c774a.chunk.js +0 -24
- package/build/users-providers-settings-page.528f0036.chunk.js +0 -29
- package/build/webhook-list-page.b0f5a02c.chunk.js +0 -71
|
@@ -48,29 +48,29 @@ const Providers = ({
|
|
|
48
48
|
themes,
|
|
49
49
|
}) => {
|
|
50
50
|
return (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
<Provider
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
<ThemeToggleProvider themes={themes}>
|
|
52
|
+
<Theme>
|
|
53
|
+
<QueryClientProvider client={queryClient}>
|
|
54
|
+
<Provider store={store}>
|
|
55
|
+
<AdminContext.Provider value={{ getAdminInjectedComponents }}>
|
|
56
|
+
<ConfigurationsProvider
|
|
57
|
+
authLogo={authLogo}
|
|
58
|
+
menuLogo={menuLogo}
|
|
59
|
+
showReleaseNotification={showReleaseNotification}
|
|
60
|
+
showTutorials={showTutorials}
|
|
61
|
+
>
|
|
62
|
+
<StrapiAppProvider
|
|
63
|
+
getPlugin={getPlugin}
|
|
64
|
+
menu={menu}
|
|
65
|
+
plugins={plugins}
|
|
66
|
+
runHookParallel={runHookParallel}
|
|
67
|
+
runHookWaterfall={runHookWaterfall}
|
|
68
|
+
runHookSeries={runHookSeries}
|
|
69
|
+
settings={settings}
|
|
62
70
|
>
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
plugins={plugins}
|
|
67
|
-
runHookParallel={runHookParallel}
|
|
68
|
-
runHookWaterfall={runHookWaterfall}
|
|
69
|
-
runHookSeries={runHookSeries}
|
|
70
|
-
settings={settings}
|
|
71
|
-
>
|
|
72
|
-
<LibraryProvider components={components} fields={fields}>
|
|
73
|
-
<CustomFieldsProvider customFields={customFields}>
|
|
71
|
+
<LibraryProvider components={components} fields={fields}>
|
|
72
|
+
<CustomFieldsProvider customFields={customFields}>
|
|
73
|
+
<LanguageProvider messages={messages} localeNames={localeNames}>
|
|
74
74
|
<AutoReloadOverlayBlockerProvider>
|
|
75
75
|
<OverlayBlockerProvider>
|
|
76
76
|
<GuidedTour>
|
|
@@ -78,16 +78,16 @@ const Providers = ({
|
|
|
78
78
|
</GuidedTour>
|
|
79
79
|
</OverlayBlockerProvider>
|
|
80
80
|
</AutoReloadOverlayBlockerProvider>
|
|
81
|
-
</
|
|
82
|
-
</
|
|
83
|
-
</
|
|
84
|
-
</
|
|
85
|
-
</
|
|
86
|
-
</Provider>
|
|
87
|
-
</
|
|
88
|
-
</
|
|
89
|
-
</
|
|
90
|
-
</
|
|
81
|
+
</LanguageProvider>
|
|
82
|
+
</CustomFieldsProvider>
|
|
83
|
+
</LibraryProvider>
|
|
84
|
+
</StrapiAppProvider>
|
|
85
|
+
</ConfigurationsProvider>
|
|
86
|
+
</AdminContext.Provider>
|
|
87
|
+
</Provider>
|
|
88
|
+
</QueryClientProvider>
|
|
89
|
+
</Theme>
|
|
90
|
+
</ThemeToggleProvider>
|
|
91
91
|
);
|
|
92
92
|
};
|
|
93
93
|
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ThemeProvider } from '@strapi/design-system';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
-
import { useIntl } from 'react-intl';
|
|
5
4
|
import { useThemeToggle } from '../../hooks';
|
|
6
5
|
import GlobalStyle from '../GlobalStyle';
|
|
7
6
|
|
|
8
7
|
const Theme = ({ children }) => {
|
|
9
8
|
const { currentTheme, themes } = useThemeToggle();
|
|
10
|
-
const { locale } = useIntl();
|
|
11
9
|
|
|
12
10
|
return (
|
|
13
|
-
<
|
|
11
|
+
<ThemeProvider theme={themes[currentTheme] || themes.light}>
|
|
14
12
|
{children}
|
|
15
13
|
<GlobalStyle />
|
|
16
|
-
</
|
|
14
|
+
</ThemeProvider>
|
|
17
15
|
);
|
|
18
16
|
};
|
|
19
17
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import { Dialog, DialogBody, DialogFooter, Flex, Typography, Button } from '@strapi/design-system';
|
|
5
|
+
import { ExclamationMarkCircle, Trash } from '@strapi/icons';
|
|
6
|
+
import InjectionZoneList from '../../InjectionZoneList';
|
|
7
|
+
import { getTrad } from '../../../utils';
|
|
8
|
+
|
|
9
|
+
const ConfirmDialogDeleteAll = ({ isConfirmButtonLoading, isOpen, onToggleDialog, onConfirm }) => {
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Dialog
|
|
14
|
+
onClose={onToggleDialog}
|
|
15
|
+
title={formatMessage({
|
|
16
|
+
id: 'app.components.ConfirmDialog.title',
|
|
17
|
+
defaultMessage: 'Confirmation',
|
|
18
|
+
})}
|
|
19
|
+
labelledBy="confirmation"
|
|
20
|
+
describedBy="confirm-description"
|
|
21
|
+
isOpen={isOpen}
|
|
22
|
+
>
|
|
23
|
+
<DialogBody icon={<ExclamationMarkCircle />}>
|
|
24
|
+
<Flex direction="column" alignItems="stretch" gap={2}>
|
|
25
|
+
<Flex justifyContent="center">
|
|
26
|
+
<Typography id="confirm-description">
|
|
27
|
+
{formatMessage({
|
|
28
|
+
id: getTrad('popUpWarning.bodyMessage.contentType.delete.all'),
|
|
29
|
+
defaultMessage: 'Are you sure you want to delete these entries?',
|
|
30
|
+
})}
|
|
31
|
+
</Typography>
|
|
32
|
+
</Flex>
|
|
33
|
+
<Flex>
|
|
34
|
+
<InjectionZoneList area="contentManager.listView.deleteModalAdditionalInfos" />
|
|
35
|
+
</Flex>
|
|
36
|
+
</Flex>
|
|
37
|
+
</DialogBody>
|
|
38
|
+
<DialogFooter
|
|
39
|
+
startAction={
|
|
40
|
+
<Button onClick={onToggleDialog} variant="tertiary">
|
|
41
|
+
{formatMessage({
|
|
42
|
+
id: 'app.components.Button.cancel',
|
|
43
|
+
defaultMessage: 'Cancel',
|
|
44
|
+
})}
|
|
45
|
+
</Button>
|
|
46
|
+
}
|
|
47
|
+
endAction={
|
|
48
|
+
<Button
|
|
49
|
+
onClick={onConfirm}
|
|
50
|
+
variant="danger-light"
|
|
51
|
+
startIcon={<Trash />}
|
|
52
|
+
id="confirm-delete"
|
|
53
|
+
loading={isConfirmButtonLoading}
|
|
54
|
+
>
|
|
55
|
+
{formatMessage({
|
|
56
|
+
id: 'app.components.Button.confirm',
|
|
57
|
+
defaultMessage: 'Confirm',
|
|
58
|
+
})}
|
|
59
|
+
</Button>
|
|
60
|
+
}
|
|
61
|
+
/>
|
|
62
|
+
</Dialog>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
ConfirmDialogDeleteAll.propTypes = {
|
|
67
|
+
isConfirmButtonLoading: PropTypes.bool.isRequired,
|
|
68
|
+
isOpen: PropTypes.bool.isRequired,
|
|
69
|
+
onConfirm: PropTypes.func.isRequired,
|
|
70
|
+
onToggleDialog: PropTypes.func.isRequired,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default ConfirmDialogDeleteAll;
|
|
@@ -9,22 +9,19 @@ import { INJECT_COLUMN_IN_TABLE } from '../../../exposedHooks';
|
|
|
9
9
|
import { selectDisplayedHeaders } from '../../pages/ListView/selectors';
|
|
10
10
|
import { getTrad } from '../../utils';
|
|
11
11
|
import TableRows from './TableRows';
|
|
12
|
+
import ConfirmDialogDeleteAll from './ConfirmDialogDeleteAll';
|
|
12
13
|
import ConfirmDialogDelete from './ConfirmDialogDelete';
|
|
13
14
|
import { PublicationState } from './CellContent/PublicationState/PublicationState';
|
|
14
|
-
import BulkActionsBar from './BulkActionsBar';
|
|
15
15
|
|
|
16
16
|
const DynamicTable = ({
|
|
17
17
|
canCreate,
|
|
18
18
|
canDelete,
|
|
19
|
-
canPublish,
|
|
20
19
|
contentTypeName,
|
|
21
20
|
action,
|
|
22
21
|
isBulkable,
|
|
23
22
|
isLoading,
|
|
24
23
|
onConfirmDelete,
|
|
25
24
|
onConfirmDeleteAll,
|
|
26
|
-
onConfirmPublishAll,
|
|
27
|
-
onConfirmUnpublishAll,
|
|
28
25
|
layout,
|
|
29
26
|
rows,
|
|
30
27
|
}) => {
|
|
@@ -92,27 +89,17 @@ const DynamicTable = ({
|
|
|
92
89
|
|
|
93
90
|
return (
|
|
94
91
|
<Table
|
|
95
|
-
components={{ ConfirmDialogDelete }}
|
|
92
|
+
components={{ ConfirmDialogDelete, ConfirmDialogDeleteAll }}
|
|
96
93
|
contentType={contentTypeName}
|
|
97
94
|
action={action}
|
|
98
95
|
isLoading={isLoading}
|
|
99
96
|
headers={tableHeaders}
|
|
100
97
|
onConfirmDelete={onConfirmDelete}
|
|
98
|
+
onConfirmDeleteAll={onConfirmDeleteAll}
|
|
101
99
|
onOpenDeleteAllModalTrackedEvent="willBulkDeleteEntries"
|
|
102
100
|
rows={rows}
|
|
103
101
|
withBulkActions
|
|
104
|
-
withMainAction={
|
|
105
|
-
renderBulkActionsBar={({ selectedEntries, clearSelectedEntries }) => (
|
|
106
|
-
<BulkActionsBar
|
|
107
|
-
showPublish={canPublish && hasDraftAndPublish}
|
|
108
|
-
showDelete={canDelete}
|
|
109
|
-
onConfirmDeleteAll={onConfirmDeleteAll}
|
|
110
|
-
onConfirmPublishAll={onConfirmPublishAll}
|
|
111
|
-
onConfirmUnpublishAll={onConfirmUnpublishAll}
|
|
112
|
-
selectedEntries={selectedEntries}
|
|
113
|
-
clearSelectedEntries={clearSelectedEntries}
|
|
114
|
-
/>
|
|
115
|
-
)}
|
|
102
|
+
withMainAction={canDelete && isBulkable}
|
|
116
103
|
>
|
|
117
104
|
<TableRows
|
|
118
105
|
canCreate={canCreate}
|
|
@@ -134,7 +121,6 @@ DynamicTable.defaultProps = {
|
|
|
134
121
|
DynamicTable.propTypes = {
|
|
135
122
|
canCreate: PropTypes.bool.isRequired,
|
|
136
123
|
canDelete: PropTypes.bool.isRequired,
|
|
137
|
-
canPublish: PropTypes.bool.isRequired,
|
|
138
124
|
contentTypeName: PropTypes.string.isRequired,
|
|
139
125
|
action: PropTypes.node,
|
|
140
126
|
isBulkable: PropTypes.bool.isRequired,
|
|
@@ -153,8 +139,6 @@ DynamicTable.propTypes = {
|
|
|
153
139
|
}).isRequired,
|
|
154
140
|
onConfirmDelete: PropTypes.func.isRequired,
|
|
155
141
|
onConfirmDeleteAll: PropTypes.func.isRequired,
|
|
156
|
-
onConfirmPublishAll: PropTypes.func.isRequired,
|
|
157
|
-
onConfirmUnpublishAll: PropTypes.func.isRequired,
|
|
158
142
|
rows: PropTypes.array.isRequired,
|
|
159
143
|
};
|
|
160
144
|
|
|
@@ -8,6 +8,7 @@ import set from 'lodash/set';
|
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
9
|
import { useIntl } from 'react-intl';
|
|
10
10
|
import { Prompt, Redirect } from 'react-router-dom';
|
|
11
|
+
import { flushSync } from 'react-dom';
|
|
11
12
|
import { useDispatch, useSelector } from 'react-redux';
|
|
12
13
|
|
|
13
14
|
import { Main } from '@strapi/design-system';
|
|
@@ -21,13 +22,12 @@ import {
|
|
|
21
22
|
getAPIInnerErrors,
|
|
22
23
|
} from '@strapi/helper-plugin';
|
|
23
24
|
|
|
24
|
-
import {
|
|
25
|
+
import { getTrad } from '../../utils';
|
|
25
26
|
|
|
26
27
|
import selectCrudReducer from '../../sharedReducers/crudReducer/selectors';
|
|
27
28
|
|
|
28
29
|
import reducer, { initialState } from './reducer';
|
|
29
|
-
import { cleanData } from './utils';
|
|
30
|
-
|
|
30
|
+
import { cleanData, createYupSchema } from './utils';
|
|
31
31
|
import { clearSetModifiedDataOnly } from '../../sharedReducers/crudReducer/actions';
|
|
32
32
|
import { usePrev } from '../../hooks';
|
|
33
33
|
|
|
@@ -55,6 +55,7 @@ const EditViewDataManagerProvider = ({
|
|
|
55
55
|
status,
|
|
56
56
|
updateActionAllowedFields,
|
|
57
57
|
}) => {
|
|
58
|
+
const [isSaving, setIsSaving] = React.useState(false);
|
|
58
59
|
/**
|
|
59
60
|
* TODO: this should be moved into the global reducer
|
|
60
61
|
* to match ever other reducer in the CM.
|
|
@@ -376,14 +377,20 @@ const EditViewDataManagerProvider = ({
|
|
|
376
377
|
try {
|
|
377
378
|
if (isEmpty(errors)) {
|
|
378
379
|
const formData = createFormData(modifiedData, initialData);
|
|
380
|
+
flushSync(() => {
|
|
381
|
+
setIsSaving(true);
|
|
382
|
+
});
|
|
379
383
|
|
|
380
384
|
if (isCreatingEntry) {
|
|
381
385
|
await onPost(formData, trackerProperty);
|
|
382
386
|
} else {
|
|
383
387
|
await onPut(formData, trackerProperty);
|
|
384
388
|
}
|
|
389
|
+
|
|
390
|
+
setIsSaving(false);
|
|
385
391
|
}
|
|
386
392
|
} catch (err) {
|
|
393
|
+
setIsSaving(false);
|
|
387
394
|
errors = {
|
|
388
395
|
...errors,
|
|
389
396
|
...getAPIInnerErrors(err, { getTrad }),
|
|
@@ -445,9 +452,14 @@ const EditViewDataManagerProvider = ({
|
|
|
445
452
|
|
|
446
453
|
try {
|
|
447
454
|
if (isEmpty(errors)) {
|
|
455
|
+
flushSync(() => {
|
|
456
|
+
setIsSaving(true);
|
|
457
|
+
});
|
|
448
458
|
await onPublish();
|
|
459
|
+
setIsSaving(false);
|
|
449
460
|
}
|
|
450
461
|
} catch (err) {
|
|
462
|
+
setIsSaving(false);
|
|
451
463
|
errors = {
|
|
452
464
|
...errors,
|
|
453
465
|
...getAPIInnerErrors(err, { getTrad }),
|
|
@@ -639,10 +651,12 @@ const EditViewDataManagerProvider = ({
|
|
|
639
651
|
</Main>
|
|
640
652
|
) : (
|
|
641
653
|
<>
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
654
|
+
{!isSaving ? (
|
|
655
|
+
<Prompt
|
|
656
|
+
when={!isEqual(modifiedData, initialData)}
|
|
657
|
+
message={formatMessage({ id: 'global.prompt.unsaved' })}
|
|
658
|
+
/>
|
|
659
|
+
) : null}
|
|
646
660
|
<form noValidate onSubmit={handleSubmit}>
|
|
647
661
|
{children}
|
|
648
662
|
</form>
|
package/admin/src/content-manager/{utils → components/EditViewDataManagerProvider/utils}/schema.js
RENAMED
|
@@ -7,7 +7,7 @@ import toNumber from 'lodash/toNumber';
|
|
|
7
7
|
import * as yup from 'yup';
|
|
8
8
|
import { translatedErrors as errorsTrads } from '@strapi/helper-plugin';
|
|
9
9
|
|
|
10
|
-
import isFieldTypeNumber from '
|
|
10
|
+
import isFieldTypeNumber from '../../../utils/isFieldTypeNumber';
|
|
11
11
|
|
|
12
12
|
yup.addMethod(yup.mixed, 'defined', function () {
|
|
13
13
|
return this.test('defined', errorsTrads.required, (value) => value !== undefined);
|
|
@@ -12,7 +12,14 @@ import Wysiwyg from '../Wysiwyg';
|
|
|
12
12
|
import InputUID from '../InputUID';
|
|
13
13
|
import { RelationInputDataManager } from '../RelationInputDataManager';
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
connect,
|
|
17
|
+
generateOptions,
|
|
18
|
+
getInputType,
|
|
19
|
+
getStep,
|
|
20
|
+
select,
|
|
21
|
+
VALIDATIONS_TO_OMIT,
|
|
22
|
+
} from './utils';
|
|
16
23
|
|
|
17
24
|
function Inputs({
|
|
18
25
|
allowedFields,
|
|
@@ -86,7 +93,9 @@ function Inputs({
|
|
|
86
93
|
return value;
|
|
87
94
|
}, [type, value]);
|
|
88
95
|
|
|
89
|
-
const step =
|
|
96
|
+
const step = useMemo(() => {
|
|
97
|
+
return getStep(type);
|
|
98
|
+
}, [type]);
|
|
90
99
|
|
|
91
100
|
const isUserAllowedToEditField = useMemo(() => {
|
|
92
101
|
const joinedName = fieldName.join('.');
|
|
@@ -175,9 +184,6 @@ function Inputs({
|
|
|
175
184
|
|
|
176
185
|
let minutes;
|
|
177
186
|
|
|
178
|
-
/**
|
|
179
|
-
* Wtf is this?
|
|
180
|
-
*/
|
|
181
187
|
if (inputType === 'datetime') {
|
|
182
188
|
minutes = parseInt(inputValue.substr(14, 2), 10);
|
|
183
189
|
} else if (inputType === 'time') {
|
|
@@ -310,19 +316,6 @@ Inputs.propTypes = {
|
|
|
310
316
|
customFieldInputs: PropTypes.object,
|
|
311
317
|
};
|
|
312
318
|
|
|
313
|
-
const getStep = (type) => {
|
|
314
|
-
switch (type) {
|
|
315
|
-
case 'float':
|
|
316
|
-
case 'decimal':
|
|
317
|
-
return 0.01;
|
|
318
|
-
case 'time':
|
|
319
|
-
case 'datetime':
|
|
320
|
-
return 15;
|
|
321
|
-
default:
|
|
322
|
-
return 1;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
|
|
326
319
|
const Memoized = memo(Inputs, isEqual);
|
|
327
320
|
|
|
328
321
|
export default connect(Memoized, select);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as connect } from './connect';
|
|
2
2
|
export { default as generateOptions } from './generateOptions';
|
|
3
3
|
export { default as getInputType } from './getInputType';
|
|
4
|
+
export { default as getStep } from './getStep';
|
|
4
5
|
export { default as select } from './select';
|
|
5
6
|
export { default as VALIDATIONS_TO_OMIT } from './VALIDATIONS_TO_OMIT';
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
useTracking,
|
|
22
22
|
Link,
|
|
23
23
|
useAPIErrorHandler,
|
|
24
|
-
getYupInnerErrors,
|
|
25
24
|
} from '@strapi/helper-plugin';
|
|
26
25
|
|
|
27
26
|
import {
|
|
@@ -36,7 +35,6 @@ import {
|
|
|
36
35
|
} from '@strapi/design-system';
|
|
37
36
|
|
|
38
37
|
import { ArrowLeft, Plus, Cog } from '@strapi/icons';
|
|
39
|
-
import { useMutation } from 'react-query';
|
|
40
38
|
|
|
41
39
|
import DynamicTable from '../../components/DynamicTable';
|
|
42
40
|
import AttributeFilter from '../../components/AttributeFilter';
|
|
@@ -44,7 +42,7 @@ import { InjectionZone } from '../../../shared/components';
|
|
|
44
42
|
|
|
45
43
|
import permissions from '../../../permissions';
|
|
46
44
|
|
|
47
|
-
import {
|
|
45
|
+
import { getRequestUrl, getTrad } from '../../utils';
|
|
48
46
|
|
|
49
47
|
import FieldPicker from './FieldPicker';
|
|
50
48
|
import PaginationFooter from './PaginationFooter';
|
|
@@ -66,7 +64,6 @@ function ListView({
|
|
|
66
64
|
canCreate,
|
|
67
65
|
canDelete,
|
|
68
66
|
canRead,
|
|
69
|
-
canPublish,
|
|
70
67
|
data,
|
|
71
68
|
getData,
|
|
72
69
|
getDataSucceeded,
|
|
@@ -103,50 +100,6 @@ function ListView({
|
|
|
103
100
|
const fetchClient = useFetchClient();
|
|
104
101
|
const { post, del } = fetchClient;
|
|
105
102
|
|
|
106
|
-
const bulkPublishMutation = useMutation(
|
|
107
|
-
(data) =>
|
|
108
|
-
post(`/content-manager/collection-types/${contentType.uid}/actions/bulkPublish`, data),
|
|
109
|
-
{
|
|
110
|
-
onSuccess() {
|
|
111
|
-
toggleNotification({
|
|
112
|
-
type: 'success',
|
|
113
|
-
message: { id: 'content-manager.success.record.publish', defaultMessage: 'Published' },
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
fetchData(`/content-manager/collection-types/${slug}${params}`);
|
|
117
|
-
},
|
|
118
|
-
onError(error) {
|
|
119
|
-
toggleNotification({
|
|
120
|
-
type: 'warning',
|
|
121
|
-
message: formatAPIError(error),
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
);
|
|
126
|
-
const bulkUnpublishMutation = useMutation(
|
|
127
|
-
(data) =>
|
|
128
|
-
post(`/content-manager/collection-types/${contentType.uid}/actions/bulkUnpublish`, data),
|
|
129
|
-
{
|
|
130
|
-
onSuccess() {
|
|
131
|
-
toggleNotification({
|
|
132
|
-
type: 'success',
|
|
133
|
-
message: {
|
|
134
|
-
id: 'content-manager.success.record.unpublish',
|
|
135
|
-
defaultMessage: 'Unpublished',
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
fetchData(`/content-manager/collection-types/${slug}${params}`);
|
|
140
|
-
},
|
|
141
|
-
onError(error) {
|
|
142
|
-
toggleNotification({
|
|
143
|
-
type: 'warning',
|
|
144
|
-
message: formatAPIError(error),
|
|
145
|
-
});
|
|
146
|
-
},
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
|
-
|
|
150
103
|
// FIXME
|
|
151
104
|
// Using a ref to avoid requests being fired multiple times on slug on change
|
|
152
105
|
// We need it because the hook as mulitple dependencies so it may run before the permissions have checked
|
|
@@ -246,70 +199,6 @@ function ListView({
|
|
|
246
199
|
[slug, params, fetchData, toggleNotification, formatAPIError, del]
|
|
247
200
|
);
|
|
248
201
|
|
|
249
|
-
/**
|
|
250
|
-
* @param {number[]} selectedEntries - Array of ids to publish
|
|
251
|
-
* @returns {{validIds: number[], errors: Object.<number, string>}} - Returns an object with the valid ids and the errors
|
|
252
|
-
*/
|
|
253
|
-
const validateEntriesToPublish = async (selectedEntries) => {
|
|
254
|
-
const validations = { validIds: [], errors: {} };
|
|
255
|
-
// Create the validation schema based on the contentType
|
|
256
|
-
const schema = createYupSchema(
|
|
257
|
-
contentType,
|
|
258
|
-
{ components: layout.components },
|
|
259
|
-
{ isDraft: false }
|
|
260
|
-
);
|
|
261
|
-
// Get the selected entries
|
|
262
|
-
const entries = data.filter((entry) => {
|
|
263
|
-
return selectedEntries.includes(entry.id);
|
|
264
|
-
});
|
|
265
|
-
// Validate each entry and map the unresolved promises
|
|
266
|
-
const validationPromises = entries.map((entry) =>
|
|
267
|
-
schema.validate(entry, { abortEarly: false })
|
|
268
|
-
);
|
|
269
|
-
// Resolve all the promises in one go
|
|
270
|
-
const resolvedPromises = await Promise.allSettled(validationPromises);
|
|
271
|
-
// Set the validations
|
|
272
|
-
resolvedPromises.forEach((promise) => {
|
|
273
|
-
if (promise.status === 'rejected') {
|
|
274
|
-
const entityId = promise.reason.value.id;
|
|
275
|
-
validations.errors[entityId] = getYupInnerErrors(promise.reason);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (promise.status === 'fulfilled') {
|
|
279
|
-
validations.validIds.push(promise.value.id);
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
return validations;
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
const handleConfirmPublishAllData = async (selectedEntries) => {
|
|
287
|
-
const validations = await validateEntriesToPublish(selectedEntries);
|
|
288
|
-
|
|
289
|
-
if (Object.values(validations.errors).length) {
|
|
290
|
-
toggleNotification({
|
|
291
|
-
type: 'warning',
|
|
292
|
-
title: {
|
|
293
|
-
id: 'content-manager.listView.validation.errors.title',
|
|
294
|
-
defaultMessage: 'Action required',
|
|
295
|
-
},
|
|
296
|
-
message: {
|
|
297
|
-
id: 'content-manager.listView.validation.errors.message',
|
|
298
|
-
defaultMessage:
|
|
299
|
-
'Please make sure all fields are valid before publishing (required field, min/max character limit, etc.)',
|
|
300
|
-
},
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
throw new Error('Validation error');
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return bulkPublishMutation.mutateAsync({ ids: selectedEntries });
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
const handleConfirmUnpublishAllData = (selectedEntries) => {
|
|
310
|
-
return bulkUnpublishMutation.mutateAsync({ ids: selectedEntries });
|
|
311
|
-
};
|
|
312
|
-
|
|
313
202
|
useEffect(() => {
|
|
314
203
|
const CancelToken = axios.CancelToken;
|
|
315
204
|
const source = CancelToken.source();
|
|
@@ -441,12 +330,9 @@ function ListView({
|
|
|
441
330
|
<DynamicTable
|
|
442
331
|
canCreate={canCreate}
|
|
443
332
|
canDelete={canDelete}
|
|
444
|
-
canPublish={canPublish}
|
|
445
333
|
contentTypeName={headerLayoutTitle}
|
|
446
|
-
onConfirmDelete={handleConfirmDeleteData}
|
|
447
334
|
onConfirmDeleteAll={handleConfirmDeleteAllData}
|
|
448
|
-
|
|
449
|
-
onConfirmUnpublishAll={handleConfirmUnpublishAllData}
|
|
335
|
+
onConfirmDelete={handleConfirmDeleteData}
|
|
450
336
|
isBulkable={isBulkable}
|
|
451
337
|
isLoading={isLoading}
|
|
452
338
|
// FIXME: remove the layout props drilling
|
|
@@ -468,12 +354,10 @@ ListView.propTypes = {
|
|
|
468
354
|
canCreate: PropTypes.bool.isRequired,
|
|
469
355
|
canDelete: PropTypes.bool.isRequired,
|
|
470
356
|
canRead: PropTypes.bool.isRequired,
|
|
471
|
-
canPublish: PropTypes.bool.isRequired,
|
|
472
357
|
data: PropTypes.array.isRequired,
|
|
473
358
|
layout: PropTypes.exact({
|
|
474
359
|
components: PropTypes.object.isRequired,
|
|
475
360
|
contentType: PropTypes.shape({
|
|
476
|
-
uid: PropTypes.string.isRequired,
|
|
477
361
|
attributes: PropTypes.object.isRequired,
|
|
478
362
|
metadatas: PropTypes.object.isRequired,
|
|
479
363
|
info: PropTypes.shape({ displayName: PropTypes.string.isRequired }).isRequired,
|
|
@@ -18,5 +18,3 @@ export { default as mergeMetasWithSchema } from './mergeMetasWithSchema';
|
|
|
18
18
|
|
|
19
19
|
export { default as removeKeyInObject } from './removeKeyInObject';
|
|
20
20
|
export { default as removePasswordFieldsFromData } from './removePasswordFieldsFromData';
|
|
21
|
-
|
|
22
|
-
export { default as createYupSchema } from './schema';
|
|
@@ -2,8 +2,6 @@ import { useAPIErrorHandler, useFetchClient, useNotification } from '@strapi/hel
|
|
|
2
2
|
import { useQueries } from 'react-query';
|
|
3
3
|
|
|
4
4
|
export function useContentTypes() {
|
|
5
|
-
console.log('----> read');
|
|
6
|
-
|
|
7
5
|
const { get } = useFetchClient();
|
|
8
6
|
const { formatAPIError } = useAPIErrorHandler();
|
|
9
7
|
const toggleNotification = useNotification();
|
package/admin/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import ReactDOM from 'react-dom';
|
|
2
1
|
import { getFetchClient } from '@strapi/helper-plugin';
|
|
3
|
-
import {
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
4
3
|
import appCustomisations from './app';
|
|
4
|
+
import { Components, Fields, Middlewares, Reducers } from './core/apis';
|
|
5
5
|
// eslint-disable-next-line import/extensions
|
|
6
6
|
import plugins from './plugins';
|
|
7
7
|
import appReducers from './reducers';
|
|
@@ -68,7 +68,8 @@ const run = async () => {
|
|
|
68
68
|
|
|
69
69
|
await app.loadTrads();
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
const root = createRoot(MOUNT_NODE);
|
|
72
|
+
root.render(app.render());
|
|
72
73
|
};
|
|
73
74
|
|
|
74
75
|
run();
|
|
@@ -13,12 +13,7 @@ const injectionZones = {
|
|
|
13
13
|
},
|
|
14
14
|
contentManager: {
|
|
15
15
|
editView: { informations: [], 'right-links': [] },
|
|
16
|
-
listView: {
|
|
17
|
-
actions: [],
|
|
18
|
-
deleteModalAdditionalInfos: [],
|
|
19
|
-
publishModalAdditionalInfos: [],
|
|
20
|
-
unpublishModalAdditionalInfos: [],
|
|
21
|
-
},
|
|
16
|
+
listView: { actions: [], deleteModalAdditionalInfos: [] },
|
|
22
17
|
},
|
|
23
18
|
};
|
|
24
19
|
|