@strapi/admin 4.12.0-beta.3 → 4.12.0-beta.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/content-manager/components/CollectionTypeFormWrapper/index.js +13 -35
- package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +304 -0
- package/admin/src/pages/AuthPage/components/Register/index.js +4 -0
- package/build/2379.0ca87a89.chunk.js +1 -0
- package/build/2395.df7a044a.chunk.js +26 -0
- package/build/2801.b1140c9b.chunk.js +1 -0
- package/build/{3100.21c343fa.chunk.js → 3100.2ba4df95.chunk.js} +1 -1
- package/build/{3483.ddd2d6df.chunk.js → 3483.e2ee2547.chunk.js} +1 -1
- package/build/3984.dda474f7.chunk.js +1 -0
- package/build/502.8ae8ef60.chunk.js +1 -0
- package/build/5483.6dd2e776.chunk.js +6 -0
- package/build/7065.ec811562.chunk.js +114 -0
- package/build/7464.8a6c1e6c.chunk.js +1 -0
- package/build/8276.6c7b8e6e.chunk.js +26 -0
- package/build/{9806.91360bb6.chunk.js → 9806.aa25371d.chunk.js} +10 -10
- package/build/{Admin-authenticatedApp.36b3826c.chunk.js → Admin-authenticatedApp.6b8dfa45.chunk.js} +1 -1
- package/build/{admin-app.1c3f7fd6.chunk.js → admin-app.c2e4e128.chunk.js} +8 -8
- package/build/content-manager.8772445b.chunk.js +1103 -0
- package/build/index.html +1 -1
- package/build/{main.a12c4c0f.js → main.af84ad9c.js} +281 -281
- package/build/review-workflows-settings-create-view.05758184.chunk.js +1 -0
- package/build/review-workflows-settings-edit-view.c33f7c58.chunk.js +1 -0
- package/build/review-workflows-settings-list-view.3ee9190d.chunk.js +56 -0
- package/build/{runtime~main.d197f488.js → runtime~main.a65ca6fb.js} +2 -2
- package/build/sso-settings-page.7c9b2fd9.chunk.js +1 -0
- package/ee/admin/constants.js +3 -0
- package/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js +12 -4
- package/ee/admin/hooks/index.js +1 -1
- package/ee/admin/hooks/useLicenseLimitNotification/index.js +1 -1
- package/ee/admin/hooks/useLicenseLimits/__mocks__/index.js +8 -0
- package/ee/admin/hooks/useLicenseLimits/index.js +1 -3
- package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +3 -13
- package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +19 -4
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js +7 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js +20 -16
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js +120 -29
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/constants.js +3 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js +108 -31
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js +8 -3
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js +138 -61
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js +8 -3
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js +72 -55
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js +8 -3
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/reducer/index.js +2 -8
- package/ee/admin/pages/SettingsPage/pages/SingleSignOn/index.js +2 -8
- package/ee/admin/pages/SettingsPage/pages/SingleSignOn/utils/schema.js +8 -5
- package/ee/server/services/review-workflows/review-workflows.js +1 -1
- package/ee/server/services/review-workflows/validation.js +6 -4
- package/ee/server/services/review-workflows/workflows/content-types.js +28 -19
- package/ee/server/services/review-workflows/workflows/index.js +14 -2
- package/ee/server/validation/authentication.js +20 -9
- package/package.json +9 -9
- package/build/2379.d33a2e16.chunk.js +0 -1
- package/build/2395.b0419a54.chunk.js +0 -26
- package/build/2801.18f38baf.chunk.js +0 -1
- package/build/3984.ea7b8036.chunk.js +0 -1
- package/build/502.ccb38223.chunk.js +0 -1
- package/build/5483.ed2c7efa.chunk.js +0 -6
- package/build/7464.c6d0565c.chunk.js +0 -1
- package/build/8276.23e0763b.chunk.js +0 -26
- package/build/8298.fd253c9f.chunk.js +0 -117
- package/build/content-manager.b8d593d4.chunk.js +0 -1103
- package/build/review-workflows-settings-create-view.dfd87e1f.chunk.js +0 -1
- package/build/review-workflows-settings-edit-view.53c00afe.chunk.js +0 -1
- package/build/review-workflows-settings-list-view.a34be805.chunk.js +0 -56
- package/build/sso-settings-page.ed6f3f15.chunk.js +0 -1
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js +0 -21
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js +0 -1
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Grid,
|
|
5
|
+
GridItem,
|
|
6
|
+
MultiSelect,
|
|
7
|
+
MultiSelectGroup,
|
|
8
|
+
MultiSelectOption,
|
|
9
|
+
TextInput,
|
|
10
|
+
Typography,
|
|
11
|
+
} from '@strapi/design-system';
|
|
4
12
|
import { useCollator } from '@strapi/helper-plugin';
|
|
5
13
|
import { useField } from 'formik';
|
|
6
14
|
import PropTypes from 'prop-types';
|
|
7
15
|
import { useIntl } from 'react-intl';
|
|
8
16
|
import { useDispatch } from 'react-redux';
|
|
17
|
+
import styled from 'styled-components';
|
|
9
18
|
|
|
10
19
|
import { updateWorkflow } from '../../actions';
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
const NestedOption = styled(MultiSelectOption)`
|
|
22
|
+
padding-left: ${({ theme }) => theme.spaces[7]};
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const ContentTypeTakeNotice = styled(Typography)`
|
|
26
|
+
font-style: italic;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export function WorkflowAttributes({
|
|
30
|
+
canUpdate,
|
|
31
|
+
contentTypes: { collectionTypes, singleTypes },
|
|
32
|
+
currentWorkflow,
|
|
33
|
+
workflows,
|
|
34
|
+
}) {
|
|
13
35
|
const { formatMessage, locale } = useIntl();
|
|
14
36
|
const dispatch = useDispatch();
|
|
15
37
|
const [nameField, nameMeta, nameHelper] = useField('name');
|
|
@@ -24,6 +46,7 @@ export function WorkflowAttributes({ contentTypes: { collectionTypes, singleType
|
|
|
24
46
|
<TextInput
|
|
25
47
|
{...nameField}
|
|
26
48
|
id={nameField.name}
|
|
49
|
+
disabled={!canUpdate}
|
|
27
50
|
label={formatMessage({
|
|
28
51
|
id: 'Settings.review-workflows.workflow.name.label',
|
|
29
52
|
defaultMessage: 'Workflow Name',
|
|
@@ -38,7 +61,7 @@ export function WorkflowAttributes({ contentTypes: { collectionTypes, singleType
|
|
|
38
61
|
</GridItem>
|
|
39
62
|
|
|
40
63
|
<GridItem col={6}>
|
|
41
|
-
<
|
|
64
|
+
<MultiSelect
|
|
42
65
|
{...contentTypesField}
|
|
43
66
|
customizeContent={(value) =>
|
|
44
67
|
formatMessage(
|
|
@@ -50,6 +73,7 @@ export function WorkflowAttributes({ contentTypes: { collectionTypes, singleType
|
|
|
50
73
|
{ count: value.length }
|
|
51
74
|
)
|
|
52
75
|
}
|
|
76
|
+
disabled={!canUpdate}
|
|
53
77
|
error={contentTypesMeta.error ?? false}
|
|
54
78
|
id={contentTypesField.name}
|
|
55
79
|
label={formatMessage({
|
|
@@ -60,36 +84,95 @@ export function WorkflowAttributes({ contentTypes: { collectionTypes, singleType
|
|
|
60
84
|
dispatch(updateWorkflow({ contentTypes: values }));
|
|
61
85
|
contentTypesHelper.setValue(values);
|
|
62
86
|
}}
|
|
63
|
-
options={[
|
|
64
|
-
{
|
|
65
|
-
label: formatMessage({
|
|
66
|
-
id: 'Settings.review-workflows.workflow.contentTypes.collectionTypes.label',
|
|
67
|
-
defaultMessage: 'Collection Types',
|
|
68
|
-
}),
|
|
69
|
-
children: collectionTypes
|
|
70
|
-
.sort((a, b) => formatter.compare(a.info.displayName, b.info.displayName))
|
|
71
|
-
.map((contentType) => ({
|
|
72
|
-
label: contentType.info.displayName,
|
|
73
|
-
value: contentType.uid,
|
|
74
|
-
})),
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
{
|
|
78
|
-
label: formatMessage({
|
|
79
|
-
id: 'Settings.review-workflows.workflow.contentTypes.singleTypes.label',
|
|
80
|
-
defaultMessage: 'Single Types',
|
|
81
|
-
}),
|
|
82
|
-
children: singleTypes.map((contentType) => ({
|
|
83
|
-
label: contentType.info.displayName,
|
|
84
|
-
value: contentType.uid,
|
|
85
|
-
})),
|
|
86
|
-
},
|
|
87
|
-
]}
|
|
88
87
|
placeholder={formatMessage({
|
|
89
88
|
id: 'Settings.review-workflows.workflow.contentTypes.placeholder',
|
|
90
89
|
defaultMessage: 'Select',
|
|
91
90
|
})}
|
|
92
|
-
|
|
91
|
+
>
|
|
92
|
+
{[
|
|
93
|
+
...(collectionTypes.length > 0
|
|
94
|
+
? [
|
|
95
|
+
{
|
|
96
|
+
label: formatMessage({
|
|
97
|
+
id: 'Settings.review-workflows.workflow.contentTypes.collectionTypes.label',
|
|
98
|
+
defaultMessage: 'Collection Types',
|
|
99
|
+
}),
|
|
100
|
+
children: collectionTypes
|
|
101
|
+
.sort((a, b) => formatter.compare(a.info.displayName, b.info.displayName))
|
|
102
|
+
.map((contentType) => ({
|
|
103
|
+
label: contentType.info.displayName,
|
|
104
|
+
value: contentType.uid,
|
|
105
|
+
})),
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
: []),
|
|
109
|
+
|
|
110
|
+
...(singleTypes.length > 0
|
|
111
|
+
? [
|
|
112
|
+
{
|
|
113
|
+
label: formatMessage({
|
|
114
|
+
id: 'Settings.review-workflows.workflow.contentTypes.singleTypes.label',
|
|
115
|
+
defaultMessage: 'Single Types',
|
|
116
|
+
}),
|
|
117
|
+
children: singleTypes.map((contentType) => ({
|
|
118
|
+
label: contentType.info.displayName,
|
|
119
|
+
value: contentType.uid,
|
|
120
|
+
})),
|
|
121
|
+
},
|
|
122
|
+
]
|
|
123
|
+
: []),
|
|
124
|
+
].map((opt) => {
|
|
125
|
+
if ('children' in opt) {
|
|
126
|
+
return (
|
|
127
|
+
<MultiSelectGroup
|
|
128
|
+
key={opt.label}
|
|
129
|
+
label={opt.label}
|
|
130
|
+
values={opt.children.map((child) => child.value.toString())}
|
|
131
|
+
>
|
|
132
|
+
{opt.children.map((child) => {
|
|
133
|
+
const { name: assignedWorkflowName } =
|
|
134
|
+
workflows.find(
|
|
135
|
+
(workflow) =>
|
|
136
|
+
((currentWorkflow && workflow.id !== currentWorkflow.id) ||
|
|
137
|
+
!currentWorkflow) &&
|
|
138
|
+
workflow.contentTypes.includes(child.value)
|
|
139
|
+
) ?? {};
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<NestedOption key={child.value} value={child.value}>
|
|
143
|
+
{formatMessage(
|
|
144
|
+
{
|
|
145
|
+
id: 'Settings.review-workflows.workflow.contentTypes.assigned.notice',
|
|
146
|
+
defaultMessage:
|
|
147
|
+
'{label} {name, select, undefined {} other {<i>(assigned to <em>{name}</em> workflow)</i>}}',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
label: child.label,
|
|
151
|
+
name: assignedWorkflowName,
|
|
152
|
+
em: (...children) => (
|
|
153
|
+
<Typography as="em" fontWeight="bold">
|
|
154
|
+
{children}
|
|
155
|
+
</Typography>
|
|
156
|
+
),
|
|
157
|
+
i: (...children) => (
|
|
158
|
+
<ContentTypeTakeNotice>{children}</ContentTypeTakeNotice>
|
|
159
|
+
),
|
|
160
|
+
}
|
|
161
|
+
)}
|
|
162
|
+
</NestedOption>
|
|
163
|
+
);
|
|
164
|
+
})}
|
|
165
|
+
</MultiSelectGroup>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<MultiSelectOption key={opt.value} value={opt.value}>
|
|
171
|
+
{opt.label}
|
|
172
|
+
</MultiSelectOption>
|
|
173
|
+
);
|
|
174
|
+
})}
|
|
175
|
+
</MultiSelect>
|
|
93
176
|
</GridItem>
|
|
94
177
|
</Grid>
|
|
95
178
|
);
|
|
@@ -102,9 +185,17 @@ const ContentTypeType = PropTypes.shape({
|
|
|
102
185
|
}).isRequired,
|
|
103
186
|
});
|
|
104
187
|
|
|
188
|
+
WorkflowAttributes.defaultProps = {
|
|
189
|
+
canUpdate: true,
|
|
190
|
+
currentWorkflow: undefined,
|
|
191
|
+
};
|
|
192
|
+
|
|
105
193
|
WorkflowAttributes.propTypes = {
|
|
194
|
+
canUpdate: PropTypes.bool,
|
|
106
195
|
contentTypes: PropTypes.shape({
|
|
107
196
|
collectionTypes: PropTypes.arrayOf(ContentTypeType).isRequired,
|
|
108
197
|
singleTypes: PropTypes.arrayOf(ContentTypeType).isRequired,
|
|
109
198
|
}).isRequired,
|
|
199
|
+
currentWorkflow: PropTypes.object,
|
|
200
|
+
workflows: PropTypes.array.isRequired,
|
|
110
201
|
};
|
|
@@ -32,3 +32,6 @@ export const STAGE_COLOR_DEFAULT = lightTheme.colors.primary600;
|
|
|
32
32
|
export const DRAG_DROP_TYPES = {
|
|
33
33
|
STAGE: 'stage',
|
|
34
34
|
};
|
|
35
|
+
|
|
36
|
+
export const CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME = 'numberOfWorkflows';
|
|
37
|
+
export const CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME = 'stagesPerWorkflow';
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Button, Flex, Loader } from '@strapi/design-system';
|
|
4
|
-
import {
|
|
3
|
+
import { Button, Flex, Loader, Typography } from '@strapi/design-system';
|
|
4
|
+
import {
|
|
5
|
+
ConfirmDialog,
|
|
6
|
+
useAPIErrorHandler,
|
|
7
|
+
useFetchClient,
|
|
8
|
+
useNotification,
|
|
9
|
+
useRBAC,
|
|
10
|
+
} from '@strapi/helper-plugin';
|
|
5
11
|
import { Check } from '@strapi/icons';
|
|
6
12
|
import { useFormik, Form, FormikProvider } from 'formik';
|
|
7
13
|
import set from 'lodash/set';
|
|
@@ -12,13 +18,18 @@ import { useHistory } from 'react-router-dom';
|
|
|
12
18
|
|
|
13
19
|
import { useContentTypes } from '../../../../../../../../admin/src/hooks/useContentTypes';
|
|
14
20
|
import { useInjectReducer } from '../../../../../../../../admin/src/hooks/useInjectReducer';
|
|
21
|
+
import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
|
|
15
22
|
import { useLicenseLimits } from '../../../../../../hooks';
|
|
16
|
-
import { resetWorkflow } from '../../actions';
|
|
23
|
+
import { addStage, resetWorkflow } from '../../actions';
|
|
17
24
|
import * as Layout from '../../components/Layout';
|
|
18
25
|
import * as LimitsModal from '../../components/LimitsModal';
|
|
19
26
|
import { Stages } from '../../components/Stages';
|
|
20
27
|
import { WorkflowAttributes } from '../../components/WorkflowAttributes';
|
|
21
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME,
|
|
30
|
+
CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME,
|
|
31
|
+
REDUX_NAMESPACE,
|
|
32
|
+
} from '../../constants';
|
|
22
33
|
import { useReviewWorkflows } from '../../hooks/useReviewWorkflows';
|
|
23
34
|
import { reducer, initialState } from '../../reducer';
|
|
24
35
|
import { validateWorkflow } from '../../utils/validateWorkflow';
|
|
@@ -29,17 +40,25 @@ export function ReviewWorkflowsCreateView() {
|
|
|
29
40
|
const { push } = useHistory();
|
|
30
41
|
const { formatAPIError } = useAPIErrorHandler();
|
|
31
42
|
const dispatch = useDispatch();
|
|
43
|
+
const permissions = useSelector(selectAdminPermissions);
|
|
32
44
|
const toggleNotification = useNotification();
|
|
33
45
|
const { collectionTypes, singleTypes, isLoading: isLoadingModels } = useContentTypes();
|
|
46
|
+
const { isLoading: isWorkflowLoading, meta, workflows } = useReviewWorkflows();
|
|
34
47
|
const {
|
|
35
48
|
clientState: {
|
|
36
49
|
currentWorkflow: { data: currentWorkflow, isDirty: currentWorkflowIsDirty },
|
|
37
50
|
},
|
|
38
51
|
} = useSelector((state) => state?.[REDUX_NAMESPACE] ?? initialState);
|
|
52
|
+
const {
|
|
53
|
+
allowedActions: { canCreate },
|
|
54
|
+
} = useRBAC(permissions.settings['review-workflows']);
|
|
39
55
|
const [showLimitModal, setShowLimitModal] = React.useState(false);
|
|
40
56
|
const { isLoading: isLicenseLoading, getFeature } = useLicenseLimits();
|
|
41
|
-
const { meta, isLoading: isWorkflowLoading } = useReviewWorkflows();
|
|
42
57
|
const [initialErrors, setInitialErrors] = React.useState(null);
|
|
58
|
+
const [savePrompts, setSavePrompts] = React.useState({});
|
|
59
|
+
|
|
60
|
+
const limits = getFeature('review-workflows');
|
|
61
|
+
const contentTypesFromOtherWorkflows = workflows.flatMap((workflow) => workflow.contentTypes);
|
|
43
62
|
|
|
44
63
|
const { mutateAsync, isLoading } = useMutation(
|
|
45
64
|
async ({ workflow }) => {
|
|
@@ -65,6 +84,8 @@ export function ReviewWorkflowsCreateView() {
|
|
|
65
84
|
);
|
|
66
85
|
|
|
67
86
|
const submitForm = async () => {
|
|
87
|
+
setSavePrompts({});
|
|
88
|
+
|
|
68
89
|
try {
|
|
69
90
|
const workflow = await mutateAsync({ workflow: currentWorkflow });
|
|
70
91
|
|
|
@@ -72,20 +93,12 @@ export function ReviewWorkflowsCreateView() {
|
|
|
72
93
|
|
|
73
94
|
return workflow;
|
|
74
95
|
} catch (error) {
|
|
75
|
-
// TODO:
|
|
76
|
-
//
|
|
77
|
-
// several times. What we want instead in these scenarios is to print only the error summary and
|
|
78
|
-
// display the individual error messages for each field. This is a workaround, until we change the
|
|
79
|
-
// implementation of `formatAPIError`.
|
|
96
|
+
// TODO: this would benefit from a utility to get a formik error
|
|
97
|
+
// representation from an API error
|
|
80
98
|
if (
|
|
81
99
|
error.response.data?.error?.name === 'ValidationError' &&
|
|
82
100
|
error.response.data?.error?.details?.errors?.length > 0
|
|
83
101
|
) {
|
|
84
|
-
toggleNotification({
|
|
85
|
-
type: 'warning',
|
|
86
|
-
message: error.response.data.error.message,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
102
|
setInitialErrors(
|
|
90
103
|
error.response.data?.error?.details?.errors.reduce((acc, error) => {
|
|
91
104
|
set(acc, error.path, error.message);
|
|
@@ -93,31 +106,44 @@ export function ReviewWorkflowsCreateView() {
|
|
|
93
106
|
return acc;
|
|
94
107
|
}, {})
|
|
95
108
|
);
|
|
96
|
-
} else {
|
|
97
|
-
toggleNotification({
|
|
98
|
-
type: 'warning',
|
|
99
|
-
message: formatAPIError(error),
|
|
100
|
-
});
|
|
101
109
|
}
|
|
102
110
|
|
|
111
|
+
toggleNotification({
|
|
112
|
+
type: 'warning',
|
|
113
|
+
message: formatAPIError(error),
|
|
114
|
+
});
|
|
115
|
+
|
|
103
116
|
return null;
|
|
104
117
|
}
|
|
105
118
|
};
|
|
106
119
|
|
|
107
|
-
const
|
|
120
|
+
const handleConfirmDeleteDialog = async () => {
|
|
121
|
+
await submitForm();
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const handleConfirmClose = () => {
|
|
125
|
+
setSavePrompts({});
|
|
126
|
+
};
|
|
108
127
|
|
|
109
128
|
const formik = useFormik({
|
|
110
129
|
enableReinitialize: true,
|
|
111
130
|
initialErrors,
|
|
112
131
|
initialValues: currentWorkflow,
|
|
113
132
|
async onSubmit() {
|
|
133
|
+
const isContentTypeReassignment = currentWorkflow.contentTypes.some((contentType) =>
|
|
134
|
+
contentTypesFromOtherWorkflows.includes(contentType)
|
|
135
|
+
);
|
|
136
|
+
|
|
114
137
|
/**
|
|
115
138
|
* If the current license has a limit, check if the total count of workflows
|
|
116
139
|
* exceeds that limit and display the limits modal instead of sending the
|
|
117
140
|
* update, because it would throw an API error.
|
|
118
141
|
*/
|
|
119
142
|
|
|
120
|
-
if (
|
|
143
|
+
if (
|
|
144
|
+
limits?.[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME] &&
|
|
145
|
+
meta?.workflowCount >= parseInt(limits[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME], 10)
|
|
146
|
+
) {
|
|
121
147
|
setShowLimitModal('workflow');
|
|
122
148
|
|
|
123
149
|
/**
|
|
@@ -126,10 +152,13 @@ export function ReviewWorkflowsCreateView() {
|
|
|
126
152
|
* update, because it would throw an API error.
|
|
127
153
|
*/
|
|
128
154
|
} else if (
|
|
129
|
-
limits?.
|
|
130
|
-
currentWorkflow.stages.length >=
|
|
155
|
+
limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME] &&
|
|
156
|
+
currentWorkflow.stages.length >=
|
|
157
|
+
parseInt(limits[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME], 10)
|
|
131
158
|
) {
|
|
132
159
|
setShowLimitModal('stage');
|
|
160
|
+
} else if (isContentTypeReassignment) {
|
|
161
|
+
setSavePrompts((prev) => ({ ...prev, hasReassignedContentTypes: true }));
|
|
133
162
|
} else {
|
|
134
163
|
submitForm();
|
|
135
164
|
}
|
|
@@ -143,6 +172,13 @@ export function ReviewWorkflowsCreateView() {
|
|
|
143
172
|
|
|
144
173
|
React.useEffect(() => {
|
|
145
174
|
dispatch(resetWorkflow());
|
|
175
|
+
|
|
176
|
+
// Create an empty default stage
|
|
177
|
+
dispatch(
|
|
178
|
+
addStage({
|
|
179
|
+
name: '',
|
|
180
|
+
})
|
|
181
|
+
);
|
|
146
182
|
}, [dispatch]);
|
|
147
183
|
|
|
148
184
|
/**
|
|
@@ -160,11 +196,15 @@ export function ReviewWorkflowsCreateView() {
|
|
|
160
196
|
|
|
161
197
|
React.useEffect(() => {
|
|
162
198
|
if (!isWorkflowLoading && !isLicenseLoading) {
|
|
163
|
-
if (
|
|
199
|
+
if (
|
|
200
|
+
limits?.[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME] &&
|
|
201
|
+
meta?.workflowsTotal >= parseInt(limits[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME], 10)
|
|
202
|
+
) {
|
|
164
203
|
setShowLimitModal('workflow');
|
|
165
204
|
} else if (
|
|
166
|
-
limits
|
|
167
|
-
currentWorkflow.stages.length >=
|
|
205
|
+
limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME] &&
|
|
206
|
+
currentWorkflow.stages.length >=
|
|
207
|
+
parseInt(limits[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME], 10)
|
|
168
208
|
) {
|
|
169
209
|
setShowLimitModal('stage');
|
|
170
210
|
}
|
|
@@ -172,8 +212,7 @@ export function ReviewWorkflowsCreateView() {
|
|
|
172
212
|
}, [
|
|
173
213
|
isLicenseLoading,
|
|
174
214
|
isWorkflowLoading,
|
|
175
|
-
limits
|
|
176
|
-
limits?.workflows,
|
|
215
|
+
limits,
|
|
177
216
|
meta?.workflowsTotal,
|
|
178
217
|
currentWorkflow.stages.length,
|
|
179
218
|
]);
|
|
@@ -191,7 +230,7 @@ export function ReviewWorkflowsCreateView() {
|
|
|
191
230
|
startIcon={<Check />}
|
|
192
231
|
type="submit"
|
|
193
232
|
size="M"
|
|
194
|
-
disabled={!currentWorkflowIsDirty}
|
|
233
|
+
disabled={!currentWorkflowIsDirty || !canCreate}
|
|
195
234
|
isLoading={isLoading}
|
|
196
235
|
>
|
|
197
236
|
{formatMessage({
|
|
@@ -223,7 +262,10 @@ export function ReviewWorkflowsCreateView() {
|
|
|
223
262
|
</Loader>
|
|
224
263
|
) : (
|
|
225
264
|
<Flex alignItems="stretch" direction="column" gap={7}>
|
|
226
|
-
<WorkflowAttributes
|
|
265
|
+
<WorkflowAttributes
|
|
266
|
+
contentTypes={{ collectionTypes, singleTypes }}
|
|
267
|
+
workflows={workflows}
|
|
268
|
+
/>
|
|
227
269
|
<Stages stages={formik.values?.stages} />
|
|
228
270
|
</Flex>
|
|
229
271
|
)}
|
|
@@ -232,6 +274,41 @@ export function ReviewWorkflowsCreateView() {
|
|
|
232
274
|
</Form>
|
|
233
275
|
</FormikProvider>
|
|
234
276
|
|
|
277
|
+
<ConfirmDialog.Root
|
|
278
|
+
isConfirmButtonLoading={isLoading}
|
|
279
|
+
isOpen={Object.keys(savePrompts).length > 0}
|
|
280
|
+
onToggleDialog={handleConfirmClose}
|
|
281
|
+
onConfirm={handleConfirmDeleteDialog}
|
|
282
|
+
>
|
|
283
|
+
<ConfirmDialog.Body>
|
|
284
|
+
<Flex direction="column" gap={5}>
|
|
285
|
+
{savePrompts.hasReassignedContentTypes && (
|
|
286
|
+
<Typography textAlign="center" variant="omega">
|
|
287
|
+
{formatMessage(
|
|
288
|
+
{
|
|
289
|
+
id: 'Settings.review-workflows.page.delete.confirm.contentType.body',
|
|
290
|
+
defaultMessage:
|
|
291
|
+
'{count} {count, plural, one {content-type} other {content-types}} {count, plural, one {is} other {are}} already mapped to {count, plural, one {another workflow} other {other workflows}}. If you save changes, {count, plural, one {this} other {these}} {count, plural, one {content-type} other {{count} content-types}} will no more be mapped to the {count, plural, one {another workflow} other {other workflows}} and all corresponding information will be removed.',
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
count: contentTypesFromOtherWorkflows.filter((contentType) =>
|
|
295
|
+
currentWorkflow.contentTypes.includes(contentType)
|
|
296
|
+
).length,
|
|
297
|
+
}
|
|
298
|
+
)}
|
|
299
|
+
</Typography>
|
|
300
|
+
)}
|
|
301
|
+
|
|
302
|
+
<Typography textAlign="center" variant="omega">
|
|
303
|
+
{formatMessage({
|
|
304
|
+
id: 'Settings.review-workflows.page.delete.confirm.confirm',
|
|
305
|
+
defaultMessage: 'Are you sure you want to save?',
|
|
306
|
+
})}
|
|
307
|
+
</Typography>
|
|
308
|
+
</Flex>
|
|
309
|
+
</ConfirmDialog.Body>
|
|
310
|
+
</ConfirmDialog.Root>
|
|
311
|
+
|
|
235
312
|
<LimitsModal.Root
|
|
236
313
|
isOpen={showLimitModal === 'workflow'}
|
|
237
314
|
onClose={() => setShowLimitModal(false)}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CheckPagePermissions } from '@strapi/helper-plugin';
|
|
4
|
+
import { useSelector } from 'react-redux';
|
|
5
|
+
|
|
6
|
+
import { selectAdminPermissions } from '../../../../../../../../admin/src/pages/App/selectors';
|
|
4
7
|
|
|
5
8
|
import { ReviewWorkflowsCreateView } from './CreateView';
|
|
6
9
|
|
|
7
10
|
export default function () {
|
|
11
|
+
const permissions = useSelector(selectAdminPermissions);
|
|
12
|
+
|
|
8
13
|
return (
|
|
9
|
-
<
|
|
14
|
+
<CheckPagePermissions permissions={permissions.settings['review-workflows'].create}>
|
|
10
15
|
<ReviewWorkflowsCreateView />
|
|
11
|
-
</
|
|
16
|
+
</CheckPagePermissions>
|
|
12
17
|
);
|
|
13
18
|
}
|