diff --git a/packages/core/admin/ee/admin/constants.js b/packages/core/admin/ee/admin/constants.js
index adef94a42c..058bea99bc 100644
--- a/packages/core/admin/ee/admin/constants.js
+++ b/packages/core/admin/ee/admin/constants.js
@@ -6,6 +6,9 @@ export const ADMIN_PERMISSIONS_EE = {
},
'review-workflows': {
main: [{ action: 'admin::review-workflows.read', subject: null }],
+ create: [{ action: 'admin::review-workflows.create', subject: null }],
+ delete: [{ action: 'admin::review-workflows.delete', subject: null }],
+ update: [{ action: 'admin::review-workflows.update', subject: null }],
},
sso: {
main: [{ action: 'admin::provider-login.read', subject: null }],
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js
deleted file mode 100644
index 632c6a38c5..0000000000
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-import { CheckPagePermissions } from '@strapi/helper-plugin';
-import PropTypes from 'prop-types';
-import { useSelector } from 'react-redux';
-
-import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
-
-export function ProtectedPage({ children }) {
- const permissions = useSelector(selectAdminPermissions);
-
- return (
-
- {children}
-
- );
-}
-
-ProtectedPage.propTypes = {
- children: PropTypes.node.isRequired,
-};
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js
deleted file mode 100644
index fa65144a38..0000000000
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from './ProtectedPage';
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js
index 87f82885da..9b584d0dd8 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js
@@ -50,6 +50,7 @@ export function Stage({
index,
canDelete,
canReorder,
+ canUpdate,
isOpen: isOpenDefault = false,
stagesCount,
}) {
@@ -216,6 +217,7 @@ export function Stage({
{
expect(getByRole('textbox').value).toBe('something');
});
+
+ it('disables all input fields, if canUpdate = false', async () => {
+ const { container, getByRole } = setup({ canUpdate: false });
+
+ await user.click(container.querySelector('button[aria-expanded]'));
+
+ expect(getByRole('textbox')).toHaveAttribute('disabled');
+ expect(getByRole('combobox')).toHaveAttribute('data-disabled');
+ });
});
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js
index da7cfffb02..215d20cf79 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js
@@ -12,26 +12,27 @@ import { AddStage } from '../AddStage';
import { Stage } from './Stage';
-const StagesContainer = styled(Box)`
- position: relative;
-`;
-
const Background = styled(Box)`
- left: 50%;
- position: absolute;
- top: 0;
transform: translateX(-50%);
`;
-function Stages({ stages }) {
+export function Stages({ canDelete, canUpdate, stages }) {
const { formatMessage } = useIntl();
const dispatch = useDispatch();
const { trackUsage } = useTracking();
return (
-
-
+
+
1}
isOpen={!stage.id}
+ canDelete={stages.length > 1 && canDelete}
canReorder={stages.length > 1}
+ canUpdate={canUpdate}
stagesCount={stages.length}
/>
);
})}
-
+
-
+ {canUpdate && (
{
@@ -73,18 +75,20 @@ function Stages({ stages }) {
defaultMessage: 'Add new stage',
})}
-
+ )}
);
}
-export { Stages };
-
Stages.defaultProps = {
+ canDelete: true,
+ canUpdate: true,
stages: [],
};
Stages.propTypes = {
+ canDelete: PropTypes.bool,
+ canUpdate: PropTypes.bool,
stages: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number,
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/tests/Stages.test.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/tests/Stages.test.js
index 01f9fc1045..07f6286491 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/tests/Stages.test.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/tests/Stages.test.js
@@ -122,4 +122,10 @@ describe('Admin | Settings | Review Workflow | Stages', () => {
name: 'New name',
});
});
+
+ it('should not render the "add stage" button if canUpdate = false', () => {
+ const { queryByText } = setup({ canUpdate: false });
+
+ expect(queryByText('Add new stage')).not.toBeInTheDocument();
+ });
});
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js
index 4bfa1358b1..bd01101b51 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js
@@ -9,7 +9,7 @@ import { useDispatch } from 'react-redux';
import { updateWorkflow } from '../../actions';
-export function WorkflowAttributes({ contentTypes: { collectionTypes, singleTypes } }) {
+export function WorkflowAttributes({ canUpdate, contentTypes: { collectionTypes, singleTypes } }) {
const { formatMessage, locale } = useIntl();
const dispatch = useDispatch();
const [nameField, nameMeta, nameHelper] = useField('name');
@@ -24,6 +24,7 @@ export function WorkflowAttributes({ contentTypes: { collectionTypes, singleType
{
expect(getByRole('textbox')).toHaveValue('workflow name');
expect(getByText(/2 content types selected/i)).toBeInTheDocument();
+ expect(getByRole('textbox')).not.toHaveAttribute('disabled');
+ expect(getByRole('combobox', { name: /associated to/i })).not.toHaveAttribute('data-disabled');
+
await user.click(contentTypesSelect);
await waitFor(() => {
@@ -81,4 +84,13 @@ describe('Admin | Settings | Review Workflow | WorkflowAttributes', () => {
expect(getByRole('option', { name: /content type 2/i })).toBeInTheDocument();
});
});
+
+ it('should disabled fields if canUpdate = false', async () => {
+ const { getByRole } = setup({ canUpdate: false });
+
+ await waitFor(() => {
+ expect(getByRole('textbox')).toHaveAttribute('disabled');
+ expect(getByRole('combobox', { name: /associated to/i })).toHaveAttribute('data-disabled');
+ });
+ });
});
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js
index 64d917aa6c..1de06b6946 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js
@@ -1,7 +1,12 @@
import * as React from 'react';
import { Button, Flex, Loader } from '@strapi/design-system';
-import { useAPIErrorHandler, useFetchClient, useNotification } from '@strapi/helper-plugin';
+import {
+ useAPIErrorHandler,
+ useFetchClient,
+ useNotification,
+ useRBAC,
+} from '@strapi/helper-plugin';
import { Check } from '@strapi/icons';
import { useFormik, Form, FormikProvider } from 'formik';
import set from 'lodash/set';
@@ -12,6 +17,7 @@ import { useHistory } from 'react-router-dom';
import { useContentTypes } from '../../../../../../../../admin/src/hooks/useContentTypes';
import { useInjectReducer } from '../../../../../../../../admin/src/hooks/useInjectReducer';
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { useLicenseLimits } from '../../../../../../hooks';
import { resetWorkflow } from '../../actions';
import * as Layout from '../../components/Layout';
@@ -29,6 +35,7 @@ export function ReviewWorkflowsCreateView() {
const { push } = useHistory();
const { formatAPIError } = useAPIErrorHandler();
const dispatch = useDispatch();
+ const permissions = useSelector(selectAdminPermissions);
const toggleNotification = useNotification();
const { collectionTypes, singleTypes, isLoading: isLoadingModels } = useContentTypes();
const {
@@ -36,6 +43,9 @@ export function ReviewWorkflowsCreateView() {
currentWorkflow: { data: currentWorkflow, isDirty: currentWorkflowIsDirty },
},
} = useSelector((state) => state?.[REDUX_NAMESPACE] ?? initialState);
+ const {
+ allowedActions: { canCreate },
+ } = useRBAC(permissions.settings['review-workflows']);
const [showLimitModal, setShowLimitModal] = React.useState(false);
const { isLoading: isLicenseLoading, getFeature } = useLicenseLimits();
const { meta, isLoading: isWorkflowLoading } = useReviewWorkflows();
@@ -191,7 +201,7 @@ export function ReviewWorkflowsCreateView() {
startIcon={}
type="submit"
size="M"
- disabled={!currentWorkflowIsDirty}
+ disabled={!currentWorkflowIsDirty || !canCreate}
isLoading={isLoading}
>
{formatMessage({
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js
index 1568576e19..1be523f91c 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js
@@ -1,13 +1,18 @@
import React from 'react';
-import { ProtectedPage } from '../../components/ProtectedPage';
+import { CheckPagePermissions } from '@strapi/helper-plugin';
+import { useSelector } from 'react-redux';
+
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { ReviewWorkflowsCreateView } from './CreateView';
export default function () {
+ const permissions = useSelector(selectAdminPermissions);
+
return (
-
+
-
+
);
}
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js
index 5f8b2681bb..63b9509995 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js
@@ -6,6 +6,7 @@ import {
useAPIErrorHandler,
useFetchClient,
useNotification,
+ useRBAC,
} from '@strapi/helper-plugin';
import { Check } from '@strapi/icons';
import { useFormik, Form, FormikProvider } from 'formik';
@@ -17,6 +18,7 @@ import { useParams } from 'react-router-dom';
import { useContentTypes } from '../../../../../../../../admin/src/hooks/useContentTypes';
import { useInjectReducer } from '../../../../../../../../admin/src/hooks/useInjectReducer';
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { useLicenseLimits } from '../../../../../../hooks';
import { setWorkflow } from '../../actions';
import * as Layout from '../../components/Layout';
@@ -30,6 +32,7 @@ import { validateWorkflow } from '../../utils/validateWorkflow';
export function ReviewWorkflowsEditView() {
const { workflowId } = useParams();
+ const permissions = useSelector(selectAdminPermissions);
const { formatMessage } = useIntl();
const dispatch = useDispatch();
const { put } = useFetchClient();
@@ -53,6 +56,9 @@ export function ReviewWorkflowsEditView() {
},
},
} = useSelector((state) => state?.[REDUX_NAMESPACE] ?? initialState);
+ const {
+ allowedActions: { canDelete, canUpdate },
+ } = useRBAC(permissions.settings['review-workflows']);
const [isConfirmDeleteDialogOpen, setIsConfirmDeleteDialogOpen] = React.useState(false);
const { getFeature, isLoading: isLicenseLoading } = useLicenseLimits();
const [showLimitModal, setShowLimitModal] = React.useState(false);
@@ -225,7 +231,7 @@ export function ReviewWorkflowsEditView() {
startIcon={}
type="submit"
size="M"
- disabled={!currentWorkflowIsDirty}
+ disabled={!currentWorkflowIsDirty || !canUpdate}
// if the confirm dialog is open the loading state is on
// the confirm button already
loading={!isConfirmDeleteDialogOpen && isLoading}
@@ -256,8 +262,15 @@ export function ReviewWorkflowsEditView() {
) : (
-
-
+
+
)}
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js
index 25ac6151a4..60749ae8c8 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js
@@ -1,13 +1,18 @@
import React from 'react';
-import { ProtectedPage } from '../../components/ProtectedPage';
+import { CheckPagePermissions } from '@strapi/helper-plugin';
+import { useSelector } from 'react-redux';
+
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { ReviewWorkflowsEditView } from './EditView';
export default function () {
+ const permissions = useSelector(selectAdminPermissions);
+
return (
-
+
-
+
);
}
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js
index 467db14acf..1c619bf32e 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js
@@ -23,15 +23,18 @@ import {
useAPIErrorHandler,
useFetchClient,
useNotification,
+ useRBAC,
useTracking,
} from '@strapi/helper-plugin';
import { Pencil, Plus, Trash } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useMutation } from 'react-query';
+import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import styled from 'styled-components';
import { useContentTypes } from '../../../../../../../../admin/src/hooks/useContentTypes';
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { useLicenseLimits } from '../../../../../../hooks';
import * as Layout from '../../components/Layout';
import * as LimitsModal from '../../components/LimitsModal';
@@ -76,6 +79,10 @@ export function ReviewWorkflowsListView() {
const toggleNotification = useNotification();
const { getFeature, isLoading: isLicenseLoading } = useLicenseLimits();
const { trackUsage } = useTracking();
+ const permissions = useSelector(selectAdminPermissions);
+ const {
+ allowedActions: { canCreate, canDelete },
+ } = useRBAC(permissions.settings['review-workflows']);
const limits = getFeature('review-workflows');
@@ -166,6 +173,7 @@ export function ReviewWorkflowsListView() {
}
size="S"
to="/settings/review-workflows/create"
@@ -218,31 +226,36 @@ export function ReviewWorkflowsListView() {
colCount={3}
footer={
// TODO: we should be able to use a link here instead of an (inaccessible onClick) handler
- }
- onClick={() => {
- /**
- * If the current license has a workflow limit:
- * check if the total count of workflows exceeds that limit
- *
- * If the current license does not have a limit (e.g. offline license):
- * allow the user to navigate to the create-view. In case they exceed the
- * current hard-limit of 200 they will see an error thrown by the API.
- */
+ canCreate && (
+ }
+ onClick={() => {
+ /**
+ * If the current license has a workflow limit:
+ * check if the total count of workflows exceeds that limit
+ *
+ * If the current license does not have a limit (e.g. offline license):
+ * allow the user to navigate to the create-view. In case they exceed the
+ * current hard-limit of 200 they will see an error thrown by the API.
+ */
- if (limits?.workflows && meta?.workflowCount >= parseInt(limits.workflows, 10)) {
- setShowLimitModal(true);
- } else {
- push('/settings/review-workflows/create');
- trackUsage('willCreateWorkflow');
- }
- }}
- >
- {formatMessage({
- id: 'Settings.review-workflows.list.page.create',
- defaultMessage: 'Create new workflow',
- })}
-
+ if (
+ limits?.workflows &&
+ meta?.workflowCount >= parseInt(limits.workflows, 10)
+ ) {
+ setShowLimitModal(true);
+ } else {
+ push('/settings/review-workflows/create');
+ trackUsage('willCreateWorkflow');
+ }
+ }}
+ >
+ {formatMessage({
+ id: 'Settings.review-workflows.list.page.create',
+ defaultMessage: 'Create new workflow',
+ })}
+
+ )
}
rowCount={1}
>
@@ -334,7 +347,7 @@ export function ReviewWorkflowsListView() {
},
{ name: 'Default workflow' }
)}
- disabled={workflows.length === 1}
+ disabled={workflows.length === 1 || !canDelete}
icon={}
noBorder
onClick={() => {
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js
index 64f1cacc8d..a5c55f2eac 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js
@@ -1,13 +1,18 @@
import React from 'react';
-import { ProtectedPage } from '../../components/ProtectedPage';
+import { CheckPagePermissions } from '@strapi/helper-plugin';
+import { useSelector } from 'react-redux';
+
+import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
import { ReviewWorkflowsListView } from './ListView';
export default function () {
+ const permissions = useSelector(selectAdminPermissions);
+
return (
-
+
-
+
);
}