@strapi/admin 4.11.4 → 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.
Files changed (68) hide show
  1. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +8 -5
  2. package/admin/src/content-manager/components/Inputs/index.js +3 -47
  3. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +34 -37
  4. package/admin/src/content-manager/pages/EditSettingsView/components/ModalForm.js +0 -27
  5. package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +93 -14
  6. package/admin/src/content-manager/pages/ListView/index.js +65 -59
  7. package/admin/src/content-manager/pages/ListView/utils/buildValidGetParams.js +30 -0
  8. package/admin/src/content-manager/pages/ListView/utils/index.js +1 -1
  9. package/admin/src/hooks/useAdminUsers/useAdminUsers.js +3 -3
  10. package/admin/src/hooks/useEnterprise/useEnterprise.js +4 -4
  11. package/admin/src/hooks/useSettingsMenu/index.js +35 -21
  12. package/admin/src/pages/App/index.js +0 -3
  13. package/admin/src/pages/AuthPage/components/Register/index.js +5 -1
  14. package/admin/src/pages/ProfilePage/index.js +12 -12
  15. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +13 -11
  16. package/admin/src/pages/SettingsPage/components/Tokens/TokenBox/index.js +1 -1
  17. package/admin/src/translations/zh-Hans.json +1 -1
  18. package/build/2799.cf9b491f.chunk.js +1 -0
  19. package/build/539.865446c0.chunk.js +1 -0
  20. package/build/{5563.86f9aa9c.chunk.js → 5563.27e2de0c.chunk.js} +3 -3
  21. package/build/5932.f8be7e31.chunk.js +1 -0
  22. package/build/7259.0e25ab5d.chunk.js +1 -0
  23. package/build/{9932.7e2b71de.chunk.js → 9932.9f3790a5.chunk.js} +81 -81
  24. package/build/9944.29289a16.chunk.js +26 -0
  25. package/build/{Admin-authenticatedApp.cb649fc1.chunk.js → Admin-authenticatedApp.7f04c595.chunk.js} +2 -2
  26. package/build/{Admin_profilePage.2131eb68.chunk.js → Admin_profilePage.0adb571e.chunk.js} +2 -2
  27. package/build/{Admin_settingsPage.4069bb8a.chunk.js → Admin_settingsPage.36152558.chunk.js} +9 -9
  28. package/build/admin-app.3ea6009c.chunk.js +61 -0
  29. package/build/admin-edit-users.78552758.chunk.js +10 -0
  30. package/build/admin-users.c23322fc.chunk.js +11 -0
  31. package/build/audit-logs-settings-page.37fe915c.chunk.js +1 -0
  32. package/build/content-manager.552c7418.chunk.js +1094 -0
  33. package/build/{content-type-builder-list-view.a200a358.chunk.js → content-type-builder-list-view.82cfadc0.chunk.js} +7 -7
  34. package/build/content-type-builder.238687f9.chunk.js +166 -0
  35. package/build/index.html +1 -1
  36. package/build/main.3d752c03.js +2927 -0
  37. package/build/runtime~main.87232977.js +2 -0
  38. package/build/{users-roles-settings-page.1f505119.chunk.js → users-roles-settings-page.d286426a.chunk.js} +1 -1
  39. package/build/{zh-Hans-json.4cfef87d.chunk.js → zh-Hans-json.fada6f40.chunk.js} +1 -1
  40. package/ee/admin/content-manager/{components/DynamicTable/CellContent/ReviewWorkflowsStage → pages/ListView/ReviewWorkflowsColumn}/ReviewWorkflowsStageEE.js +7 -2
  41. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants.js +24 -0
  42. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/index.js +1 -0
  43. package/ee/admin/hooks/useLicenseLimitNotification/index.js +17 -6
  44. package/ee/admin/hooks/useLicenseLimits/index.js +1 -32
  45. package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +44 -0
  46. package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +6 -4
  47. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +6 -4
  48. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +3 -5
  49. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +9 -2
  50. package/package.json +11 -12
  51. package/admin/src/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -2
  52. package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +0 -36
  53. package/admin/src/content-manager/pages/ListView/utils/createPluginsFilter.js +0 -4
  54. package/admin/src/pages/App/utils/index.js +0 -3
  55. package/admin/src/pages/App/utils/unique-identifier.js +0 -12
  56. package/build/1799.44d2e264.chunk.js +0 -33
  57. package/build/5932.6a23b88c.chunk.js +0 -1
  58. package/build/7259.fb69d4bf.chunk.js +0 -1
  59. package/build/admin-app.fea867af.chunk.js +0 -61
  60. package/build/admin-edit-users.200551e3.chunk.js +0 -10
  61. package/build/admin-users.3b12dca2.chunk.js +0 -11
  62. package/build/audit-logs-settings-page.f538490f.chunk.js +0 -1
  63. package/build/content-manager.c40f5ff9.chunk.js +0 -1088
  64. package/build/content-type-builder.bd1bbff1.chunk.js +0 -166
  65. package/build/main.ee36abd9.js +0 -2927
  66. package/build/runtime~main.efd966f6.js +0 -2
  67. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -58
  68. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/index.js +0 -3
@@ -43,7 +43,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
43
43
  const { setCurrentStep } = useGuidedTour();
44
44
  const { trackUsage } = useTracking();
45
45
  const { push, replace } = useHistory();
46
- const [{ rawQuery }] = useQueryParams();
46
+ const [{ query, rawQuery }] = useQueryParams();
47
47
  const dispatch = useDispatch();
48
48
  const { componentsDataStructure, contentTypeDataStructure, data, isLoading, status } =
49
49
  useSelector(selectCrudReducer);
@@ -244,13 +244,15 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
244
244
  */
245
245
  const endPoint =
246
246
  typeof origin === 'string'
247
- ? `${getRequestUrl(`collection-types/${slug}/clone/${origin}`)}${rawQuery}`
248
- : `${getRequestUrl(`collection-types/${slug}`)}${rawQuery}`;
247
+ ? getRequestUrl(`collection-types/${slug}/clone/${origin}`)
248
+ : getRequestUrl(`collection-types/${slug}`);
249
249
  try {
250
250
  // Show a loading button in the EditView/Header.js && lock the app => no navigation
251
251
  dispatch(setStatus('submit-pending'));
252
252
 
253
- const { data } = await post(endPoint, body);
253
+ const { data } = await post(endPoint, body, {
254
+ params: query,
255
+ });
254
256
 
255
257
  trackUsageRef.current('didCreateEntry', trackerProperty);
256
258
  toggleNotification({
@@ -286,11 +288,12 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
286
288
  replace,
287
289
  slug,
288
290
  dispatch,
289
- rawQuery,
291
+ query,
290
292
  toggleNotification,
291
293
  setCurrentStep,
292
294
  queryClient,
293
295
  post,
296
+ rawQuery,
294
297
  ]
295
298
  );
296
299
 
@@ -75,20 +75,9 @@ function Inputs({
75
75
  return foundAttributeType === 'dynamiczone';
76
76
  }, [currentContentTypeLayout, fieldName]);
77
77
 
78
- const inputType = useMemo(() => {
79
- return getInputType(type);
80
- }, [type]);
81
-
82
- const inputValue = useMemo(() => {
83
- // Fix for input file multipe
84
- if (type === 'media' && !value) {
85
- return [];
86
- }
87
-
88
- return value;
89
- }, [type, value]);
78
+ const inputType = getInputType(type);
90
79
 
91
- const step = getStep(type);
80
+ const inputValue = type === 'media' && !value ? [] : value;
92
81
 
93
82
  const isUserAllowedToEditField = useMemo(() => {
94
83
  const joinedName = fieldName.join('.');
@@ -159,36 +148,6 @@ function Inputs({
159
148
 
160
149
  const { label, description, placeholder, visible } = metadatas;
161
150
 
162
- /**
163
- * It decides whether using the default `step` accoding to its `inputType` or the one
164
- * obtained from `metadatas`.
165
- *
166
- * The `metadatas.step` is returned when the `inputValue` is divisible by it or when the
167
- * `inputValue` is empty, otherwise the default `step` is returned.
168
- */
169
- const inputStep = useMemo(() => {
170
- if (!metadatas.step || (inputType !== 'datetime' && inputType !== 'time')) {
171
- return step;
172
- }
173
-
174
- if (!inputValue) {
175
- return metadatas.step;
176
- }
177
-
178
- let minutes;
179
-
180
- /**
181
- * Wtf is this?
182
- */
183
- if (inputType === 'datetime') {
184
- minutes = parseInt(inputValue.substr(14, 2), 10);
185
- } else if (inputType === 'time') {
186
- minutes = parseInt(inputValue.slice(-2), 10);
187
- }
188
-
189
- return minutes % metadatas.step === 0 ? metadatas.step : step;
190
- }, [inputType, inputValue, metadatas.step, step]);
191
-
192
151
  if (visible === false) {
193
152
  return null;
194
153
  }
@@ -271,7 +230,7 @@ function Inputs({
271
230
  options={options}
272
231
  placeholder={placeholder ? { id: placeholder, defaultMessage: placeholder } : null}
273
232
  required={fieldSchema.required || false}
274
- step={inputStep}
233
+ step={getStep(type)}
275
234
  type={customFieldUid || inputType}
276
235
  // validations={validations}
277
236
  value={inputValue}
@@ -317,9 +276,6 @@ const getStep = (type) => {
317
276
  case 'float':
318
277
  case 'decimal':
319
278
  return 0.01;
320
- case 'time':
321
- case 'datetime':
322
- return 15;
323
279
  default:
324
280
  return 1;
325
281
  }
@@ -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 buildQueryString from '../../pages/ListView/utils/buildQueryString';
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 searchToSend = buildQueryString(query);
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(`${slug}${searchToSend}`), {
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(`${slug}${searchToSend}`));
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, searchToSend, dispatch, rawQuery]
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(`${slug}${rawQuery}`);
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
- rawQuery,
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${searchToSend}`);
260
+ const endPoint = getRequestUrl(`${slug}/actions/publish`);
267
261
 
268
262
  dispatch(setStatus('publish-pending'));
269
263
 
270
- const { data } = await post(endPoint);
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, searchToSend, dispatch, toggleNotification]);
290
+ }, [post, cleanReceivedData, displayErrors, slug, query, dispatch, toggleNotification]);
291
291
 
292
292
  const onPut = useCallback(
293
293
  async (body, trackerProperty) => {
294
- const endPoint = getRequestUrl(`${slug}${rawQuery}`);
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${searchToSend}`);
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(endPoint);
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, searchToSend]);
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 { BaseCheckbox, IconButton, Tbody, Td, Tr, Flex } from '@strapi/design-system';
4
- import { useTracking, useFetchClient, useAPIErrorHandler } from '@strapi/helper-plugin';
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}?${pluginsQueryParams}`
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
- {typeof cellFormatter === 'function' ? (
120
- cellFormatter(data, { key, name, ...rest })
121
- ) : (
122
- <CellContent
123
- content={data[name.split('.')[0]]}
124
- name={name}
125
- contentType={contentType}
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,