diff --git a/api-tests/core/admin/ee/review-workflows.test.api.js b/api-tests/core/admin/ee/review-workflows.test.api.js
index 4246c9aec9..d76f174816 100644
--- a/api-tests/core/admin/ee/review-workflows.test.api.js
+++ b/api-tests/core/admin/ee/review-workflows.test.api.js
@@ -279,10 +279,25 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
];
});
+ test("It should assign a default color to stages if they don't have one", async () => {
+ await requests.admin.put(`/admin/review-workflows/workflows/${testWorkflow.id}/stages`, {
+ body: {
+ data: [defaultStage, { id: secondStage.id, name: secondStage.name, color: '#000000' }],
+ },
+ });
+
+ const workflowRes = await requests.admin.get(
+ `/admin/review-workflows/workflows/${testWorkflow.id}?populate=*`
+ );
+
+ expect(workflowRes.status).toBe(200);
+ expect(workflowRes.body.data.stages[0].color).toBe('#4945FF');
+ expect(workflowRes.body.data.stages[1].color).toBe('#000000');
+ });
test("It shouldn't be available for public", async () => {
const stagesRes = await requests.public.put(
`/admin/review-workflows/workflows/${testWorkflow.id}/stages`,
- stagesUpdateData
+ { body: { data: stagesUpdateData } }
);
const workflowRes = await requests.public.get(
`/admin/review-workflows/workflows/${testWorkflow.id}`
@@ -353,6 +368,19 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
expect(workflowRes.body.data).toBeUndefined();
}
});
+ test('It should throw an error if trying to create more than 200 stages', async () => {
+ const stagesRes = await requests.admin.put(
+ `/admin/review-workflows/workflows/${testWorkflow.id}/stages`,
+ { body: { data: Array(201).fill({ name: 'new stage' }) } }
+ );
+
+ if (hasRW) {
+ expect(stagesRes.status).toBe(400);
+ expect(stagesRes.body.error).toBeDefined();
+ expect(stagesRes.body.error.name).toEqual('ValidationError');
+ expect(stagesRes.body.error.message).toBeDefined();
+ }
+ });
});
describe('Enabling/Disabling review workflows on a content type', () => {
@@ -416,7 +444,7 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
});
});
- describe('update a stage on an entity', () => {
+ describe('Update a stage on an entity', () => {
describe('Review Workflow is enabled', () => {
beforeAll(async () => {
await updateContentType(productUID, {
diff --git a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/ReviewWorkflowsStageEE.js b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/ReviewWorkflowsStageEE.js
index 28683acf4c..7904b05f0d 100644
--- a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/ReviewWorkflowsStageEE.js
+++ b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/ReviewWorkflowsStageEE.js
@@ -1,15 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Typography } from '@strapi/design-system';
+import { Box, Flex, Typography } from '@strapi/design-system';
+import { pxToRem } from '@strapi/helper-plugin';
-export function ReviewWorkflowsStageEE({ name }) {
+export function ReviewWorkflowsStageEE({ color, name }) {
return (
-
- {name}
-
+
+
+
+
+ {name}
+
+
);
}
ReviewWorkflowsStageEE.propTypes = {
+ color: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
};
diff --git a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js
index 1390d99bb9..1f52c0af40 100644
--- a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js
+++ b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js
@@ -4,6 +4,7 @@ import { Typography } from '@strapi/design-system';
import ReviewWorkflowsStage from '.';
import getTrad from '../../../../../../../admin/src/content-manager/utils/getTrad';
+import { STAGE_COLOR_DEFAULT } from '../../../../../pages/SettingsPage/pages/ReviewWorkflows/constants';
export default (layout) => {
const { formatMessage } = useIntl();
@@ -24,7 +25,7 @@ export default (layout) => {
key: '__strapi_reviewWorkflows_stage_temp_key__',
name: 'strapi_reviewWorkflows_stage',
fieldSchema: {
- type: 'custom',
+ type: 'relation',
},
metadatas: {
label: formatMessage({
@@ -32,7 +33,8 @@ export default (layout) => {
defaultMessage: 'Review stage',
}),
searchable: false,
- sortable: false,
+ sortable: true,
+ mainField: 'name',
},
cellFormatter({ strapi_reviewWorkflows_stage }) {
// if entities are created e.g. through lifecycle methods
@@ -41,7 +43,9 @@ export default (layout) => {
return -;
}
- return ;
+ const { color, name } = strapi_reviewWorkflows_stage;
+
+ return ;
},
};
};
diff --git a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/tests/ReviewWorkflowsStage.test.js b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/tests/ReviewWorkflowsStage.test.js
index 8d17245507..36a9e30e59 100644
--- a/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/tests/ReviewWorkflowsStage.test.js
+++ b/packages/core/admin/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/tests/ReviewWorkflowsStage.test.js
@@ -17,7 +17,7 @@ const setup = (props) => render();
describe('DynamicTable | ReviewWorkflowsStage', () => {
test('render stage name', () => {
- const { getByText } = setup({ name: 'reviewed' });
+ const { getByText } = setup({ color: 'red', name: 'reviewed' });
expect(getByText('reviewed')).toBeInTheDocument();
});
diff --git a/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js b/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js
index c5235c0862..b6440c9742 100644
--- a/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js
+++ b/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js
@@ -11,6 +11,8 @@ import { useIntl } from 'react-intl';
import { useMutation } from 'react-query';
import { useReviewWorkflows } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows';
+import { OptionColor } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/components/OptionColor';
+import { SingleValueColor } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/components/SingleValueColor';
import Information from '../../../../../../admin/src/content-manager/pages/EditView/Information';
const ATTRIBUTE_NAME = 'strapi_reviewWorkflows_stage';
@@ -113,6 +115,8 @@ export function InformationBoxEE() {
,
+ Option: OptionColor,
+ SingleValue: SingleValueColor,
}}
error={formattedError}
inputId={ATTRIBUTE_NAME}
@@ -122,9 +126,19 @@ export function InformationBoxEE() {
name={ATTRIBUTE_NAME}
onChange={handleStageChange}
options={
- workflow ? workflow.stages.map(({ id, name }) => ({ value: id, label: name })) : []
+ workflow
+ ? workflow.stages.map(({ id, color, name }) => ({
+ value: id,
+ label: name,
+ color,
+ }))
+ : []
}
- value={{ value: activeWorkflowStage?.id, label: activeWorkflowStage?.name }}
+ value={{
+ value: activeWorkflowStage?.id,
+ label: activeWorkflowStage?.name,
+ color: activeWorkflowStage?.color,
+ }}
/>
diff --git a/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/tests/InformationBoxEE.test.js b/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/tests/InformationBoxEE.test.js
index c480d80817..f433fcafa0 100644
--- a/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/tests/InformationBoxEE.test.js
+++ b/packages/core/admin/ee/admin/content-manager/pages/EditView/InformationBox/tests/InformationBoxEE.test.js
@@ -12,6 +12,7 @@ import { InformationBoxEE } from '../InformationBoxEE';
const STAGE_ATTRIBUTE_NAME = 'strapi_reviewWorkflows_stage';
const STAGE_FIXTURE = {
id: 1,
+ color: 'red',
name: 'Stage 1',
worklow: 1,
};
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js
index 44e729e23b..af6419b078 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js
@@ -18,12 +18,24 @@ import { Check } from '@strapi/icons';
import { Stages } from './components/Stages';
import { reducer, initialState } from './reducer';
-import { REDUX_NAMESPACE } from './constants';
+import { REDUX_NAMESPACE, DRAG_DROP_TYPES } from './constants';
import { useInjectReducer } from '../../../../../../admin/src/hooks/useInjectReducer';
import { useReviewWorkflows } from './hooks/useReviewWorkflows';
import { setWorkflows } from './actions';
import { getWorkflowValidationSchema } from './utils/getWorkflowValidationSchema';
import adminPermissions from '../../../../../../admin/src/permissions';
+import { StageDragPreview } from './components/StageDragPreview';
+import { DragLayer } from '../../../../../../admin/src/components/DragLayer';
+
+function renderDragLayerItem({ type, item }) {
+ switch (type) {
+ case DRAG_DROP_TYPES.STAGE:
+ return ;
+
+ default:
+ return null;
+ }
+}
export function ReviewWorkflowsPage() {
const { trackUsage } = useTracking();
@@ -47,31 +59,15 @@ export function ReviewWorkflowsPage() {
const { mutateAsync, isLoading } = useMutation(
async ({ workflowId, stages }) => {
- try {
- const {
- data: { data },
- } = await put(`/admin/review-workflows/workflows/${workflowId}/stages`, {
- data: stages,
- });
+ const {
+ data: { data },
+ } = await put(`/admin/review-workflows/workflows/${workflowId}/stages`, {
+ data: stages,
+ });
- return data;
- } catch (error) {
- toggleNotification({
- type: 'warning',
- message: formatAPIError(error),
- });
- }
-
- return null;
+ return data;
},
{
- onError(error) {
- toggleNotification({
- type: 'warning',
- message: formatAPIError(error),
- });
- },
-
onSuccess() {
toggleNotification({
type: 'success',
@@ -81,8 +77,19 @@ export function ReviewWorkflowsPage() {
}
);
- const updateWorkflowStages = (workflowId, stages) => {
- return mutateAsync({ workflowId, stages });
+ const updateWorkflowStages = async (workflowId, stages) => {
+ try {
+ const res = await mutateAsync({ workflowId, stages });
+
+ return res;
+ } catch (error) {
+ toggleNotification({
+ type: 'warning',
+ message: formatAPIError(error),
+ });
+
+ return null;
+ }
};
const submitForm = async () => {
@@ -135,6 +142,8 @@ export function ReviewWorkflowsPage() {
})}
/>
+
+