@strapi/admin 4.11.3 → 4.11.5
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 -2
- package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +8 -5
- package/admin/src/content-manager/components/Inputs/index.js +3 -47
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +99 -178
- package/admin/src/content-manager/components/RelationInput/components/Option.js +17 -15
- package/admin/src/content-manager/components/RelationInput/components/RelationList.js +2 -2
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +34 -37
- package/admin/src/content-manager/pages/EditSettingsView/components/ModalForm.js +0 -27
- package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +93 -14
- package/admin/src/content-manager/pages/ListView/index.js +65 -47
- package/admin/src/content-manager/pages/ListView/utils/buildValidGetParams.js +30 -0
- package/admin/src/content-manager/pages/ListView/utils/index.js +1 -1
- package/admin/src/hooks/useAdminUsers/useAdminUsers.js +3 -3
- package/admin/src/hooks/useEnterprise/useEnterprise.js +4 -4
- package/admin/src/hooks/useSettingsMenu/index.js +35 -21
- package/admin/src/pages/App/index.js +0 -3
- package/admin/src/pages/AuthPage/components/Register/index.js +5 -1
- package/admin/src/pages/ProfilePage/index.js +12 -12
- package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +13 -11
- package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +15 -1
- package/admin/src/pages/SettingsPage/components/Tokens/TokenBox/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Roles/ProtectedEditPage/index.js +4 -10
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +2 -2
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +11 -5
- package/admin/src/translations/ca.json +1 -0
- package/admin/src/translations/en.json +4 -1
- package/admin/src/translations/es.json +5 -0
- package/admin/src/translations/fr.json +1 -0
- package/admin/src/translations/zh-Hans.json +1 -1
- package/build/2799.cf9b491f.chunk.js +1 -0
- package/build/539.865446c0.chunk.js +1 -0
- package/build/{5542.64b623c9.chunk.js → 5542.c62d0daf.chunk.js} +1 -1
- package/build/{5563.86f9aa9c.chunk.js → 5563.27e2de0c.chunk.js} +3 -3
- package/build/5932.f8be7e31.chunk.js +1 -0
- package/build/7259.0e25ab5d.chunk.js +1 -0
- package/build/{6405.27e1bee5.chunk.js → 970.89601f27.chunk.js} +2 -2
- package/build/{9932.7e2b71de.chunk.js → 9932.9f3790a5.chunk.js} +81 -81
- package/build/9944.29289a16.chunk.js +26 -0
- package/build/Admin-authenticatedApp.7f04c595.chunk.js +79 -0
- package/build/{Admin_profilePage.2131eb68.chunk.js → Admin_profilePage.0adb571e.chunk.js} +2 -2
- package/build/{Admin_settingsPage.4069bb8a.chunk.js → Admin_settingsPage.36152558.chunk.js} +9 -9
- package/build/admin-app.3ea6009c.chunk.js +61 -0
- package/build/{admin-edit-roles-page.2040034a.chunk.js → admin-edit-roles-page.3fdd6b9d.chunk.js} +11 -11
- package/build/admin-edit-users.78552758.chunk.js +10 -0
- package/build/admin-users.c23322fc.chunk.js +11 -0
- package/build/api-tokens-list-page.a103f526.chunk.js +16 -0
- package/build/audit-logs-settings-page.37fe915c.chunk.js +1 -0
- package/build/ca-json.1fed5d8b.chunk.js +1 -0
- package/build/content-manager.552c7418.chunk.js +1094 -0
- package/build/{content-type-builder-list-view.0c3ceb4e.chunk.js → content-type-builder-list-view.82cfadc0.chunk.js} +7 -7
- package/build/content-type-builder.238687f9.chunk.js +166 -0
- package/build/{email-settings-page.6b38222d.chunk.js → email-settings-page.45695daa.chunk.js} +1 -1
- package/build/en-json.fb9f6ddd.chunk.js +1 -0
- package/build/es-json.42096084.chunk.js +1 -0
- package/build/fr-json.69789980.chunk.js +1 -0
- package/build/{i18n-settings-page.ff863f20.chunk.js → i18n-settings-page.29308d0b.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/main.3d752c03.js +2927 -0
- package/build/runtime~main.87232977.js +2 -0
- package/build/sso-settings-page.0cdb96a6.chunk.js +1 -0
- package/build/transfer-tokens-list-page.7237443d.chunk.js +16 -0
- package/build/{upload-settings.43cf16cd.chunk.js → upload-settings.cb6c14c3.chunk.js} +1 -1
- package/build/{upload.72f8f8fc.chunk.js → upload.7e629643.chunk.js} +2 -2
- package/build/users-advanced-settings-page.750b1f76.chunk.js +9 -0
- package/build/{users-email-settings-page.33359797.chunk.js → users-email-settings-page.e9bcd865.chunk.js} +1 -1
- package/build/{users-providers-settings-page.1e7a4a71.chunk.js → users-providers-settings-page.a94253e9.chunk.js} +1 -1
- package/build/{users-roles-settings-page.235378b6.chunk.js → users-roles-settings-page.d286426a.chunk.js} +5 -5
- package/build/webhook-edit-page.77ef4f1a.chunk.js +33 -0
- package/build/{zh-Hans-json.4cfef87d.chunk.js → zh-Hans-json.fada6f40.chunk.js} +1 -1
- package/ee/admin/content-manager/{components/DynamicTable/CellContent/ReviewWorkflowsStage → pages/ListView/ReviewWorkflowsColumn}/ReviewWorkflowsStageEE.js +7 -2
- package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants.js +24 -0
- package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/index.js +1 -0
- package/ee/admin/hooks/useLicenseLimitNotification/index.js +17 -6
- package/ee/admin/hooks/useLicenseLimits/index.js +1 -32
- package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +44 -0
- package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +6 -4
- package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +6 -4
- package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/index.js +4 -9
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +3 -5
- package/ee/admin/pages/SettingsPage/pages/SingleSignOn/index.js +4 -9
- package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +9 -2
- package/ee/server/services/review-workflows/entity-service-decorator.js +20 -11
- package/package.json +14 -15
- package/server/content-types/User.js +10 -0
- package/server/strategies/api-token.js +9 -5
- package/server/strategies/data-transfer.js +9 -5
- package/admin/src/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -2
- package/admin/src/content-manager/components/RelationInput/components/Relation.js +0 -53
- package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +0 -36
- package/admin/src/content-manager/pages/ListView/utils/createPluginsFilter.js +0 -4
- package/admin/src/pages/App/utils/index.js +0 -3
- package/admin/src/pages/App/utils/unique-identifier.js +0 -12
- package/build/1799.84268ad3.chunk.js +0 -33
- package/build/5932.6a23b88c.chunk.js +0 -1
- package/build/7259.fb69d4bf.chunk.js +0 -1
- package/build/Admin-authenticatedApp.69855f1b.chunk.js +0 -79
- package/build/admin-app.fea867af.chunk.js +0 -61
- package/build/admin-edit-users.53e4290a.chunk.js +0 -10
- package/build/admin-users.3b12dca2.chunk.js +0 -11
- package/build/api-tokens-list-page.201fb67a.chunk.js +0 -16
- package/build/audit-logs-settings-page.b07ad202.chunk.js +0 -1
- package/build/ca-json.43e14418.chunk.js +0 -1
- package/build/content-manager.66cec770.chunk.js +0 -1094
- package/build/content-type-builder.e1b6d13b.chunk.js +0 -166
- package/build/en-json.f5fa476a.chunk.js +0 -1
- package/build/es-json.715b6fd8.chunk.js +0 -1
- package/build/fr-json.73494bf5.chunk.js +0 -1
- package/build/main.83edb3fc.js +0 -2926
- package/build/runtime~main.20c3cac6.js +0 -2
- package/build/sso-settings-page.35b67909.chunk.js +0 -1
- package/build/transfer-tokens-list-page.217573c3.chunk.js +0 -16
- package/build/users-advanced-settings-page.1911adf5.chunk.js +0 -9
- package/build/webhook-edit-page.1ee02c4b.chunk.js +0 -33
- package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -58
- package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/index.js +0 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
|
1
|
+
import { memo, useCallback, useEffect, useRef, useState, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
formatContentTypeData,
|
|
@@ -16,7 +16,7 @@ import { useQueryClient } from 'react-query';
|
|
|
16
16
|
import { useDispatch, useSelector } from 'react-redux';
|
|
17
17
|
import { useHistory } from 'react-router-dom';
|
|
18
18
|
|
|
19
|
-
import
|
|
19
|
+
import { buildValidGetParams } from '../../pages/ListView/utils';
|
|
20
20
|
import {
|
|
21
21
|
getData,
|
|
22
22
|
getDataSucceeded,
|
|
@@ -40,7 +40,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
40
40
|
const trackUsageRef = useRef(trackUsage);
|
|
41
41
|
const [isCreatingEntry, setIsCreatingEntry] = useState(true);
|
|
42
42
|
const [{ query, rawQuery }] = useQueryParams();
|
|
43
|
-
const
|
|
43
|
+
const params = useMemo(() => buildValidGetParams(query), [query]);
|
|
44
44
|
const toggleNotification = useNotification();
|
|
45
45
|
const dispatch = useDispatch();
|
|
46
46
|
const { formatAPIError } = useAPIErrorHandler(getTrad);
|
|
@@ -110,8 +110,9 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
110
110
|
setIsCreatingEntry(true);
|
|
111
111
|
|
|
112
112
|
try {
|
|
113
|
-
const { data } = await fetchClient.get(getRequestUrl(
|
|
113
|
+
const { data } = await fetchClient.get(getRequestUrl(slug), {
|
|
114
114
|
cancelToken: source.token,
|
|
115
|
+
params,
|
|
115
116
|
});
|
|
116
117
|
|
|
117
118
|
dispatch(getDataSucceeded(cleanReceivedData(data)));
|
|
@@ -143,16 +144,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
143
144
|
fetchData(source);
|
|
144
145
|
|
|
145
146
|
return () => source.cancel('Operation canceled by the user.');
|
|
146
|
-
}, [
|
|
147
|
-
fetchClient,
|
|
148
|
-
cleanReceivedData,
|
|
149
|
-
push,
|
|
150
|
-
slug,
|
|
151
|
-
dispatch,
|
|
152
|
-
searchToSend,
|
|
153
|
-
rawQuery,
|
|
154
|
-
toggleNotification,
|
|
155
|
-
]);
|
|
147
|
+
}, [fetchClient, cleanReceivedData, push, slug, dispatch, params, rawQuery, toggleNotification]);
|
|
156
148
|
|
|
157
149
|
const displayErrors = useCallback(
|
|
158
150
|
(err) => {
|
|
@@ -166,7 +158,9 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
166
158
|
try {
|
|
167
159
|
trackUsageRef.current('willDeleteEntry', trackerProperty);
|
|
168
160
|
|
|
169
|
-
const { data } = await del(getRequestUrl(
|
|
161
|
+
const { data } = await del(getRequestUrl(slug), {
|
|
162
|
+
params: query,
|
|
163
|
+
});
|
|
170
164
|
|
|
171
165
|
toggleNotification({
|
|
172
166
|
type: 'success',
|
|
@@ -187,17 +181,17 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
187
181
|
return Promise.reject(err);
|
|
188
182
|
}
|
|
189
183
|
},
|
|
190
|
-
[del, slug, displayErrors, toggleNotification,
|
|
184
|
+
[del, slug, displayErrors, toggleNotification, query, dispatch, rawQuery]
|
|
191
185
|
);
|
|
192
186
|
|
|
193
187
|
const onPost = useCallback(
|
|
194
188
|
async (body, trackerProperty) => {
|
|
195
|
-
const endPoint = getRequestUrl(
|
|
189
|
+
const endPoint = getRequestUrl(slug);
|
|
196
190
|
|
|
197
191
|
try {
|
|
198
192
|
dispatch(setStatus('submit-pending'));
|
|
199
193
|
|
|
200
|
-
const { data } = await put(endPoint, body);
|
|
194
|
+
const { data } = await put(endPoint, body, { params: query });
|
|
201
195
|
|
|
202
196
|
trackUsageRef.current('didCreateEntry', trackerProperty);
|
|
203
197
|
toggleNotification({
|
|
@@ -232,7 +226,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
232
226
|
displayErrors,
|
|
233
227
|
slug,
|
|
234
228
|
dispatch,
|
|
235
|
-
|
|
229
|
+
query,
|
|
236
230
|
toggleNotification,
|
|
237
231
|
setCurrentStep,
|
|
238
232
|
queryClient,
|
|
@@ -263,11 +257,17 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
263
257
|
const onPublish = useCallback(async () => {
|
|
264
258
|
try {
|
|
265
259
|
trackUsageRef.current('willPublishEntry');
|
|
266
|
-
const endPoint = getRequestUrl(`${slug}/actions/publish
|
|
260
|
+
const endPoint = getRequestUrl(`${slug}/actions/publish`);
|
|
267
261
|
|
|
268
262
|
dispatch(setStatus('publish-pending'));
|
|
269
263
|
|
|
270
|
-
const { data } = await post(
|
|
264
|
+
const { data } = await post(
|
|
265
|
+
endPoint,
|
|
266
|
+
{},
|
|
267
|
+
{
|
|
268
|
+
params: query,
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
271
|
|
|
272
272
|
trackUsageRef.current('didPublishEntry');
|
|
273
273
|
toggleNotification({
|
|
@@ -287,18 +287,18 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
287
287
|
|
|
288
288
|
return Promise.reject(err);
|
|
289
289
|
}
|
|
290
|
-
}, [post, cleanReceivedData, displayErrors, slug,
|
|
290
|
+
}, [post, cleanReceivedData, displayErrors, slug, query, dispatch, toggleNotification]);
|
|
291
291
|
|
|
292
292
|
const onPut = useCallback(
|
|
293
293
|
async (body, trackerProperty) => {
|
|
294
|
-
const endPoint = getRequestUrl(
|
|
294
|
+
const endPoint = getRequestUrl(slug);
|
|
295
295
|
|
|
296
296
|
try {
|
|
297
297
|
trackUsageRef.current('willEditEntry', trackerProperty);
|
|
298
298
|
|
|
299
299
|
dispatch(setStatus('submit-pending'));
|
|
300
300
|
|
|
301
|
-
const { data } = await put(endPoint, body);
|
|
301
|
+
const { data } = await put(endPoint, body, { params: query });
|
|
302
302
|
|
|
303
303
|
toggleNotification({
|
|
304
304
|
type: 'success',
|
|
@@ -325,28 +325,25 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
325
325
|
return Promise.reject(err);
|
|
326
326
|
}
|
|
327
327
|
},
|
|
328
|
-
[
|
|
329
|
-
put,
|
|
330
|
-
cleanReceivedData,
|
|
331
|
-
displayErrors,
|
|
332
|
-
slug,
|
|
333
|
-
dispatch,
|
|
334
|
-
rawQuery,
|
|
335
|
-
toggleNotification,
|
|
336
|
-
queryClient,
|
|
337
|
-
]
|
|
328
|
+
[put, cleanReceivedData, displayErrors, slug, dispatch, query, toggleNotification, queryClient]
|
|
338
329
|
);
|
|
339
330
|
|
|
340
331
|
// The publish and unpublish method could be refactored but let's leave the duplication for now
|
|
341
332
|
const onUnpublish = useCallback(async () => {
|
|
342
|
-
const endPoint = getRequestUrl(`${slug}/actions/unpublish
|
|
333
|
+
const endPoint = getRequestUrl(`${slug}/actions/unpublish`);
|
|
343
334
|
|
|
344
335
|
dispatch(setStatus('unpublish-pending'));
|
|
345
336
|
|
|
346
337
|
try {
|
|
347
338
|
trackUsageRef.current('willUnpublishEntry');
|
|
348
339
|
|
|
349
|
-
const { data } = await post(
|
|
340
|
+
const { data } = await post(
|
|
341
|
+
endPoint,
|
|
342
|
+
{},
|
|
343
|
+
{
|
|
344
|
+
params: query,
|
|
345
|
+
}
|
|
346
|
+
);
|
|
350
347
|
|
|
351
348
|
trackUsageRef.current('didUnpublishEntry');
|
|
352
349
|
toggleNotification({
|
|
@@ -361,7 +358,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
361
358
|
dispatch(setStatus('resolved'));
|
|
362
359
|
displayErrors(err);
|
|
363
360
|
}
|
|
364
|
-
}, [post, cleanReceivedData, toggleNotification, displayErrors, slug, dispatch,
|
|
361
|
+
}, [post, cleanReceivedData, toggleNotification, displayErrors, slug, dispatch, query]);
|
|
365
362
|
|
|
366
363
|
return children({
|
|
367
364
|
componentsDataStructure,
|
|
@@ -20,10 +20,6 @@ const FIELD_SIZES = [
|
|
|
20
20
|
[12, '100%'],
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
-
const TIME_FIELD_OPTIONS = [1, 5, 10, 15, 30, 60];
|
|
24
|
-
|
|
25
|
-
const TIME_FIELD_TYPES = ['datetime', 'time'];
|
|
26
|
-
|
|
27
23
|
const ModalForm = ({ onMetaChange, onSizeChange }) => {
|
|
28
24
|
const { formatMessage } = useIntl();
|
|
29
25
|
const { modifiedData, selectedField, attributes, fieldForm } = useLayoutDnd();
|
|
@@ -131,33 +127,10 @@ const ModalForm = ({ onMetaChange, onSizeChange }) => {
|
|
|
131
127
|
</GridItem>
|
|
132
128
|
);
|
|
133
129
|
|
|
134
|
-
const hasTimePicker = TIME_FIELD_TYPES.includes(attributes[selectedField].type);
|
|
135
|
-
|
|
136
|
-
const timeStepField = (
|
|
137
|
-
<GridItem col={6} key="step">
|
|
138
|
-
<Select
|
|
139
|
-
value={get(fieldForm, ['metadata', 'step'], 1)}
|
|
140
|
-
name="step"
|
|
141
|
-
onChange={(value) => onMetaChange({ target: { name: 'step', value } })}
|
|
142
|
-
label={formatMessage({
|
|
143
|
-
id: getTrad('containers.SettingPage.editSettings.step.label'),
|
|
144
|
-
defaultMessage: 'Time interval (minutes)',
|
|
145
|
-
})}
|
|
146
|
-
>
|
|
147
|
-
{TIME_FIELD_OPTIONS.map((value) => (
|
|
148
|
-
<Option key={value} value={value}>
|
|
149
|
-
{value}
|
|
150
|
-
</Option>
|
|
151
|
-
))}
|
|
152
|
-
</Select>
|
|
153
|
-
</GridItem>
|
|
154
|
-
);
|
|
155
|
-
|
|
156
130
|
return (
|
|
157
131
|
<>
|
|
158
132
|
{metaFields}
|
|
159
133
|
{isResizable && sizeField}
|
|
160
|
-
{hasTimePicker && timeStepField}
|
|
161
134
|
</>
|
|
162
135
|
);
|
|
163
136
|
};
|
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
BaseCheckbox,
|
|
5
|
+
IconButton,
|
|
6
|
+
Tbody,
|
|
7
|
+
Td,
|
|
8
|
+
Tr,
|
|
9
|
+
Flex,
|
|
10
|
+
Status,
|
|
11
|
+
Typography,
|
|
12
|
+
} from '@strapi/design-system';
|
|
13
|
+
import {
|
|
14
|
+
useTracking,
|
|
15
|
+
useFetchClient,
|
|
16
|
+
useAPIErrorHandler,
|
|
17
|
+
useQueryParams,
|
|
18
|
+
} from '@strapi/helper-plugin';
|
|
5
19
|
import { Trash, Duplicate, Pencil } from '@strapi/icons';
|
|
6
20
|
import { AxiosError } from 'axios';
|
|
7
21
|
import PropTypes from 'prop-types';
|
|
8
22
|
import { useIntl } from 'react-intl';
|
|
9
23
|
import { Link, useHistory } from 'react-router-dom';
|
|
10
24
|
|
|
25
|
+
import { useEnterprise } from '../../../../../hooks/useEnterprise';
|
|
11
26
|
import { getFullName } from '../../../../../utils';
|
|
12
27
|
import { usePluginsQueryParams } from '../../../../hooks';
|
|
13
28
|
import { getTrad } from '../../../../utils';
|
|
14
29
|
import CellContent from '../CellContent';
|
|
15
30
|
|
|
31
|
+
const REVIEW_WORKFLOW_COLUMNS_CE = () => null;
|
|
32
|
+
|
|
16
33
|
export const TableRows = ({
|
|
17
34
|
canCreate,
|
|
18
35
|
canDelete,
|
|
19
36
|
contentType,
|
|
37
|
+
features: { hasDraftAndPublish, hasReviewWorkflows },
|
|
20
38
|
headers,
|
|
21
39
|
entriesToDelete,
|
|
22
40
|
onClickDelete,
|
|
@@ -32,7 +50,20 @@ export const TableRows = ({
|
|
|
32
50
|
|
|
33
51
|
const { trackUsage } = useTracking();
|
|
34
52
|
const pluginsQueryParams = usePluginsQueryParams();
|
|
53
|
+
const [{ query }] = useQueryParams();
|
|
35
54
|
const { formatAPIError } = useAPIErrorHandler(getTrad);
|
|
55
|
+
const ReviewWorkflowsStage = useEnterprise(
|
|
56
|
+
REVIEW_WORKFLOW_COLUMNS_CE,
|
|
57
|
+
async () =>
|
|
58
|
+
(
|
|
59
|
+
await import(
|
|
60
|
+
'../../../../../../../ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn'
|
|
61
|
+
)
|
|
62
|
+
).ReviewWorkflowsStageEE,
|
|
63
|
+
{
|
|
64
|
+
enabled: hasReviewWorkflows,
|
|
65
|
+
}
|
|
66
|
+
);
|
|
36
67
|
|
|
37
68
|
/**
|
|
38
69
|
*
|
|
@@ -53,7 +84,9 @@ export const TableRows = ({
|
|
|
53
84
|
const handleCloneClick = (id) => async () => {
|
|
54
85
|
try {
|
|
55
86
|
const { data } = await post(
|
|
56
|
-
`/content-manager/collection-types/${contentType.uid}/auto-clone/${id}
|
|
87
|
+
`/content-manager/collection-types/${contentType.uid}/auto-clone/${id}`,
|
|
88
|
+
{},
|
|
89
|
+
{ params: { plugins: query?.plugins } }
|
|
57
90
|
);
|
|
58
91
|
|
|
59
92
|
if ('id' in data) {
|
|
@@ -74,6 +107,11 @@ export const TableRows = ({
|
|
|
74
107
|
}
|
|
75
108
|
};
|
|
76
109
|
|
|
110
|
+
// block rendering until the review stage component is fully loaded in EE
|
|
111
|
+
if (!ReviewWorkflowsStage) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
77
115
|
/**
|
|
78
116
|
* Table Cells with actions e.g edit, delete, duplicate have `stopPropagation`
|
|
79
117
|
* to prevent the row from being selected.
|
|
@@ -113,20 +151,57 @@ export const TableRows = ({
|
|
|
113
151
|
/>
|
|
114
152
|
</Td>
|
|
115
153
|
)}
|
|
154
|
+
|
|
116
155
|
{headers.map(({ key, cellFormatter, name, ...rest }) => {
|
|
156
|
+
if (hasDraftAndPublish && name === 'publishedAt') {
|
|
157
|
+
return (
|
|
158
|
+
<Td key={key}>
|
|
159
|
+
<Status
|
|
160
|
+
width="min-content"
|
|
161
|
+
showBullet={false}
|
|
162
|
+
variant={data.publishedAt ? 'success' : 'secondary'}
|
|
163
|
+
size="S"
|
|
164
|
+
>
|
|
165
|
+
<Typography
|
|
166
|
+
fontWeight="bold"
|
|
167
|
+
textColor={`${data.publishedAt ? 'success' : 'secondary'}700`}
|
|
168
|
+
>
|
|
169
|
+
{formatMessage({
|
|
170
|
+
id: getTrad(
|
|
171
|
+
`containers.List.${data.publishedAt ? 'published' : 'draft'}`
|
|
172
|
+
),
|
|
173
|
+
defaultMessage: data.publishedAt ? 'Published' : 'Draft',
|
|
174
|
+
})}
|
|
175
|
+
</Typography>
|
|
176
|
+
</Status>
|
|
177
|
+
</Td>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (hasReviewWorkflows && name === 'strapi_reviewWorkflows_stage') {
|
|
182
|
+
return (
|
|
183
|
+
<Td key={key}>
|
|
184
|
+
{data.strapi_reviewWorkflows_stage ? (
|
|
185
|
+
<ReviewWorkflowsStage
|
|
186
|
+
color={data.strapi_reviewWorkflows_stage.color}
|
|
187
|
+
name={data.strapi_reviewWorkflows_stage.name}
|
|
188
|
+
/>
|
|
189
|
+
) : (
|
|
190
|
+
<Typography textColor="neutral800">-</Typography>
|
|
191
|
+
)}
|
|
192
|
+
</Td>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
117
196
|
return (
|
|
118
197
|
<Td key={key}>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{...rest}
|
|
127
|
-
rowId={data.id}
|
|
128
|
-
/>
|
|
129
|
-
)}
|
|
198
|
+
<CellContent
|
|
199
|
+
content={data[name.split('.')[0]]}
|
|
200
|
+
name={name}
|
|
201
|
+
contentType={contentType}
|
|
202
|
+
{...rest}
|
|
203
|
+
rowId={data.id}
|
|
204
|
+
/>
|
|
130
205
|
</Td>
|
|
131
206
|
);
|
|
132
207
|
})}
|
|
@@ -212,6 +287,10 @@ TableRows.propTypes = {
|
|
|
212
287
|
uid: PropTypes.string.isRequired,
|
|
213
288
|
}).isRequired,
|
|
214
289
|
entriesToDelete: PropTypes.array,
|
|
290
|
+
features: PropTypes.shape({
|
|
291
|
+
hasDraftAndPublish: PropTypes.bool.isRequired,
|
|
292
|
+
hasReviewWorkflows: PropTypes.bool.isRequired,
|
|
293
|
+
}).isRequired,
|
|
215
294
|
headers: PropTypes.array.isRequired,
|
|
216
295
|
onClickDelete: PropTypes.func,
|
|
217
296
|
onSelectRow: PropTypes.func,
|
|
@@ -10,8 +10,6 @@ import {
|
|
|
10
10
|
HeaderLayout,
|
|
11
11
|
useNotifyAT,
|
|
12
12
|
Flex,
|
|
13
|
-
Typography,
|
|
14
|
-
Status,
|
|
15
13
|
} from '@strapi/design-system';
|
|
16
14
|
import {
|
|
17
15
|
NoPermissions,
|
|
@@ -44,6 +42,7 @@ import { bindActionCreators, compose } from 'redux';
|
|
|
44
42
|
import styled from 'styled-components';
|
|
45
43
|
|
|
46
44
|
import { INJECT_COLUMN_IN_TABLE } from '../../../exposedHooks';
|
|
45
|
+
import { useEnterprise } from '../../../hooks/useEnterprise';
|
|
47
46
|
import { selectAdminPermissions } from '../../../pages/App/selectors';
|
|
48
47
|
import { InjectionZone } from '../../../shared/components';
|
|
49
48
|
import AttributeFilter from '../../components/AttributeFilter';
|
|
@@ -56,7 +55,7 @@ import { ConfirmDialogDeleteAll } from './components/ConfirmDialogDeleteAll';
|
|
|
56
55
|
import { FieldPicker } from './components/FieldPicker';
|
|
57
56
|
import { TableRows } from './components/TableRows';
|
|
58
57
|
import makeSelectListView, { selectDisplayedHeaders } from './selectors';
|
|
59
|
-
import {
|
|
58
|
+
import { buildValidGetParams } from './utils';
|
|
60
59
|
|
|
61
60
|
const ConfigureLayoutBox = styled(Box)`
|
|
62
61
|
svg {
|
|
@@ -66,6 +65,8 @@ const ConfigureLayoutBox = styled(Box)`
|
|
|
66
65
|
}
|
|
67
66
|
`;
|
|
68
67
|
|
|
68
|
+
const REVIEW_WORKFLOW_COLUMNS_CE = null;
|
|
69
|
+
|
|
69
70
|
function ListView({
|
|
70
71
|
canCreate,
|
|
71
72
|
canDelete,
|
|
@@ -100,14 +101,30 @@ function ListView({
|
|
|
100
101
|
useFocusWhenNavigate();
|
|
101
102
|
|
|
102
103
|
const [{ query }] = useQueryParams();
|
|
103
|
-
const params =
|
|
104
|
+
const params = React.useMemo(() => buildValidGetParams(query), [query]);
|
|
104
105
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
|
105
106
|
|
|
106
107
|
const { pathname } = useLocation();
|
|
107
108
|
const { push } = useHistory();
|
|
108
109
|
const { formatMessage } = useIntl();
|
|
109
|
-
const hasDraftAndPublish = options?.draftAndPublish || false;
|
|
110
110
|
const fetchClient = useFetchClient();
|
|
111
|
+
|
|
112
|
+
const hasDraftAndPublish = options?.draftAndPublish ?? false;
|
|
113
|
+
const hasReviewWorkflows = options?.reviewWorkflows ?? false;
|
|
114
|
+
|
|
115
|
+
const reviewWorkflowColumns = useEnterprise(
|
|
116
|
+
REVIEW_WORKFLOW_COLUMNS_CE,
|
|
117
|
+
async () =>
|
|
118
|
+
(
|
|
119
|
+
await import(
|
|
120
|
+
'../../../../../ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants'
|
|
121
|
+
)
|
|
122
|
+
).REVIEW_WORKFLOW_COLUMNS_EE,
|
|
123
|
+
{
|
|
124
|
+
enabled: !!options?.reviewWorkflows,
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
|
|
111
128
|
const { post, del } = fetchClient;
|
|
112
129
|
|
|
113
130
|
const bulkPublishMutation = useMutation(
|
|
@@ -120,7 +137,7 @@ function ListView({
|
|
|
120
137
|
message: { id: 'content-manager.success.record.publish', defaultMessage: 'Published' },
|
|
121
138
|
});
|
|
122
139
|
|
|
123
|
-
fetchData(`/content-manager/collection-types/${slug}
|
|
140
|
+
fetchData(`/content-manager/collection-types/${slug}`, { params });
|
|
124
141
|
},
|
|
125
142
|
onError(error) {
|
|
126
143
|
toggleNotification({
|
|
@@ -143,7 +160,7 @@ function ListView({
|
|
|
143
160
|
},
|
|
144
161
|
});
|
|
145
162
|
|
|
146
|
-
fetchData(`/content-manager/collection-types/${slug}
|
|
163
|
+
fetchData(`/content-manager/collection-types/${slug}`, { params });
|
|
147
164
|
},
|
|
148
165
|
onError(error) {
|
|
149
166
|
toggleNotification({
|
|
@@ -158,19 +175,17 @@ function ListView({
|
|
|
158
175
|
// Using a ref to avoid requests being fired multiple times on slug on change
|
|
159
176
|
// We need it because the hook as mulitple dependencies so it may run before the permissions have checked
|
|
160
177
|
const requestUrlRef = React.useRef('');
|
|
161
|
-
|
|
162
178
|
/**
|
|
163
179
|
* TODO: re-write all of this, it's a mess.
|
|
164
180
|
*/
|
|
165
181
|
const fetchData = React.useCallback(
|
|
166
|
-
async (endPoint,
|
|
182
|
+
async (endPoint, options) => {
|
|
167
183
|
getData();
|
|
168
184
|
|
|
169
185
|
try {
|
|
170
|
-
const opts = source ? { cancelToken: source.token } : null;
|
|
171
186
|
const {
|
|
172
187
|
data: { results, pagination: paginationResult },
|
|
173
|
-
} = await fetchClient.get(endPoint,
|
|
188
|
+
} = await fetchClient.get(endPoint, options);
|
|
174
189
|
|
|
175
190
|
notifyStatus(
|
|
176
191
|
formatMessage(
|
|
@@ -217,12 +232,12 @@ function ListView({
|
|
|
217
232
|
const handleConfirmDeleteAllData = React.useCallback(
|
|
218
233
|
async (ids) => {
|
|
219
234
|
try {
|
|
220
|
-
await post(
|
|
235
|
+
await post(`/content-manager/collection-types/${slug}/actions/bulkDelete`, {
|
|
221
236
|
ids,
|
|
222
237
|
});
|
|
223
238
|
|
|
224
|
-
|
|
225
|
-
|
|
239
|
+
fetchData(`/content-manager/collection-types/${slug}`, { params });
|
|
240
|
+
|
|
226
241
|
trackUsageRef.current('didBulkDeleteEntries');
|
|
227
242
|
} catch (err) {
|
|
228
243
|
toggleNotification({
|
|
@@ -231,16 +246,16 @@ function ListView({
|
|
|
231
246
|
});
|
|
232
247
|
}
|
|
233
248
|
},
|
|
234
|
-
[
|
|
249
|
+
[slug, toggleNotification, formatAPIError, post, fetchData, params]
|
|
235
250
|
);
|
|
236
251
|
|
|
237
252
|
const handleConfirmDeleteData = React.useCallback(
|
|
238
253
|
async (idToDelete) => {
|
|
239
254
|
try {
|
|
240
|
-
await del(
|
|
255
|
+
await del(`/content-manager/collection-types/${slug}/${idToDelete}`);
|
|
241
256
|
|
|
242
|
-
const requestUrl = getRequestUrl(`collection-types/${slug}
|
|
243
|
-
fetchData(requestUrl);
|
|
257
|
+
const requestUrl = getRequestUrl(`collection-types/${slug}`);
|
|
258
|
+
fetchData(requestUrl, { params });
|
|
244
259
|
|
|
245
260
|
toggleNotification({
|
|
246
261
|
type: 'success',
|
|
@@ -253,7 +268,7 @@ function ListView({
|
|
|
253
268
|
});
|
|
254
269
|
}
|
|
255
270
|
},
|
|
256
|
-
[slug,
|
|
271
|
+
[slug, toggleNotification, formatAPIError, del, fetchData, params]
|
|
257
272
|
);
|
|
258
273
|
|
|
259
274
|
/**
|
|
@@ -325,10 +340,10 @@ function ListView({
|
|
|
325
340
|
const source = CancelToken.source();
|
|
326
341
|
|
|
327
342
|
const shouldSendRequest = canRead;
|
|
328
|
-
const requestUrl = getRequestUrl(`collection-types/${slug}
|
|
343
|
+
const requestUrl = getRequestUrl(`collection-types/${slug}`);
|
|
329
344
|
|
|
330
345
|
if (shouldSendRequest && requestUrl.includes(requestUrlRef.current)) {
|
|
331
|
-
fetchData(requestUrl, source);
|
|
346
|
+
fetchData(requestUrl, { cancelToken: source.token, params });
|
|
332
347
|
}
|
|
333
348
|
|
|
334
349
|
return () => {
|
|
@@ -387,13 +402,8 @@ function ListView({
|
|
|
387
402
|
};
|
|
388
403
|
});
|
|
389
404
|
|
|
390
|
-
if (
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
return [
|
|
395
|
-
...formattedHeaders,
|
|
396
|
-
{
|
|
405
|
+
if (hasDraftAndPublish) {
|
|
406
|
+
formattedHeaders.push({
|
|
397
407
|
key: '__published_at_temp_key__',
|
|
398
408
|
name: 'publishedAt',
|
|
399
409
|
fieldSchema: {
|
|
@@ -407,25 +417,29 @@ function ListView({
|
|
|
407
417
|
searchable: false,
|
|
408
418
|
sortable: true,
|
|
409
419
|
},
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (reviewWorkflowColumns) {
|
|
424
|
+
// Make sure the column header label is translated
|
|
425
|
+
if (typeof reviewWorkflowColumns.metadatas.label !== 'string') {
|
|
426
|
+
reviewWorkflowColumns.metadatas.label = formatMessage(
|
|
427
|
+
reviewWorkflowColumns.metadatas.label
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
formattedHeaders.push(reviewWorkflowColumns);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return formattedHeaders;
|
|
435
|
+
}, [
|
|
436
|
+
runHookWaterfall,
|
|
437
|
+
displayedHeaders,
|
|
438
|
+
layout,
|
|
439
|
+
reviewWorkflowColumns,
|
|
440
|
+
hasDraftAndPublish,
|
|
441
|
+
formatMessage,
|
|
442
|
+
]);
|
|
429
443
|
|
|
430
444
|
const subtitle = canRead
|
|
431
445
|
? formatMessage(
|
|
@@ -568,6 +582,10 @@ function ListView({
|
|
|
568
582
|
canCreate={canCreate}
|
|
569
583
|
canDelete={canDelete}
|
|
570
584
|
contentType={contentType}
|
|
585
|
+
features={{
|
|
586
|
+
hasDraftAndPublish,
|
|
587
|
+
hasReviewWorkflows,
|
|
588
|
+
}}
|
|
571
589
|
headers={tableHeaders}
|
|
572
590
|
rows={data}
|
|
573
591
|
withBulkActions
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const createPluginsFilter = (obj = {}) =>
|
|
2
|
+
Object.values(obj).reduce((acc, current) => Object.assign(acc, current), {});
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* Creates a valid query params object for get requests
|
|
7
|
+
* ie. plugins[18n][locale]=en becomes locale=en
|
|
8
|
+
* @param {object} [query={}] - The query params
|
|
9
|
+
* @returns {object} - The modified query params
|
|
10
|
+
*/
|
|
11
|
+
const buildValidGetParams = (query = {}) => {
|
|
12
|
+
// Extract pluginOptions from the query, they shouldn't be part of the URL
|
|
13
|
+
const {
|
|
14
|
+
plugins: _,
|
|
15
|
+
_q: searchQuery,
|
|
16
|
+
...validQueryParams
|
|
17
|
+
} = {
|
|
18
|
+
...query,
|
|
19
|
+
...createPluginsFilter(query.plugins),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (searchQuery) {
|
|
23
|
+
// Encode the search query here since the paramsSerializer will not
|
|
24
|
+
validQueryParams._q = encodeURIComponent(searchQuery);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return validQueryParams;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default buildValidGetParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as buildValidGetParams } from './buildValidGetParams';
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { useFetchClient } from '@strapi/helper-plugin';
|
|
2
|
-
import { stringify } from 'qs';
|
|
3
2
|
import { useQuery } from 'react-query';
|
|
4
3
|
|
|
5
4
|
export function useAdminUsers(params = {}, queryOptions = {}) {
|
|
6
5
|
const { id = '', ...queryParams } = params;
|
|
7
|
-
const queryString = stringify(queryParams, { encode: false });
|
|
8
6
|
|
|
9
7
|
const { get } = useFetchClient();
|
|
10
8
|
|
|
@@ -13,7 +11,9 @@ export function useAdminUsers(params = {}, queryOptions = {}) {
|
|
|
13
11
|
async () => {
|
|
14
12
|
const {
|
|
15
13
|
data: { data },
|
|
16
|
-
} = await get(`/admin/users/${id}
|
|
14
|
+
} = await get(`/admin/users/${id}`, {
|
|
15
|
+
params: queryParams,
|
|
16
|
+
});
|
|
17
17
|
|
|
18
18
|
return data;
|
|
19
19
|
},
|