Merge branch 'feature/review-workflow' into review-workflow/stage-one-way-relation

This commit is contained in:
Marc-Roig 2023-04-17 17:09:37 +02:00
commit 113cf4e1a2
14 changed files with 62 additions and 44 deletions

View File

@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18]
node: [18]
steps:
- uses: actions/checkout@v3
with:

View File

@ -21,5 +21,5 @@ Alternatively, you can use [`yarn link`](https://classic.yarnpkg.com/lang/en/doc
Once the link is setup, run the following command from the root of the monorepo
```
yarn lerna clean && yarn setup
yarn clean && yarn setup
```

View File

@ -1,23 +0,0 @@
---
title: How to install packages
slug: /how-to-install-packages
tags:
- lerna
- packages
---
# Best practices for installing packages in Strapi
When working with the Strapi monorepo, it's important to follow best practices for installing packages to avoid potential issues and ensure consistent results. Instead of using the standard **`yarn add`** command, we recommend using **`yarn lerna add <package_name> --scope @strapi/<module_name>`** for installing packages. Actually, you may encounter the following error using `yarn add`:
`An unexpected error occurred: "expected workspace package to exist for \"@typescript-eslint/typescript-estree\'`
This approach uses Lerna, a tool for managing JavaScript projects with multiple packages, to ensure that the package is installed in the correct location(s) and version across all modules that include it. The **`--scope`** flag specifies the specific module(s) that the package should be installed in, ensuring that it's only installed where it's needed.
By using this method, Strapi developers can avoid issues with mismatched package versions or unnecessary dependencies in certain modules. This can help to keep the codebase clean and maintainable, and reduce the potential for conflicts or issues in the future.
Overall, we recommend using **`yarn lerna add`** with the **`--scope`** flag for installing packages in the Strapi mono repo, to ensure consistent and reliable results.
## Resources
- [Lerna Docs](https://futurestud.io/tutorials/lerna-install-dependencies-for-a-specific-package)

View File

@ -188,15 +188,6 @@ const sidebars = {
},
items: [],
},
{
type: 'category',
label: 'How to install packages in a module',
link: {
type: 'doc',
id: 'how-to-install-packages',
},
items: [],
},
],
api: [{ type: 'autogenerated', dirName: 'api' }],
community: [{ type: 'autogenerated', dirName: 'community' }],

View File

@ -2,6 +2,7 @@ import {
GET_DATA,
GET_DATA_SUCCEEDED,
INIT_FORM,
UPDATE_PARTIAL_DATA,
RESET_PROPS,
SET_DATA_STRUCTURES,
SET_STATUS,
@ -47,3 +48,8 @@ export const submitSucceeded = (data) => ({
export const clearSetModifiedDataOnly = () => ({
type: CLEAR_SET_MODIFIED_DATA_ONLY,
});
export const updatePartialData = (data) => ({
type: UPDATE_PARTIAL_DATA,
data,
});

View File

@ -7,3 +7,4 @@ export const SET_STATUS = 'ContentManager/CrudReducer/SET_STATUS';
export const SUBMIT_SUCCEEDED = 'ContentManager/CrudReducer/SUBMIT_SUCCEEDED';
export const CLEAR_SET_MODIFIED_DATA_ONLY =
'ContentManager/CrudReducer/CLEAR_SET_MODIFIED_DATA_ONLY';
export const UPDATE_PARTIAL_DATA = 'ContentManager/CrudReducer/PARTIAL_DATA_UPDATE';

View File

@ -12,6 +12,7 @@ import {
GET_DATA,
GET_DATA_SUCCEEDED,
INIT_FORM,
UPDATE_PARTIAL_DATA,
RESET_PROPS,
SET_DATA_STRUCTURES,
SET_STATUS,
@ -53,6 +54,10 @@ const crudReducer = (state = crudInitialState, action) =>
draftState.data = state.contentTypeDataStructure;
break;
}
case UPDATE_PARTIAL_DATA: {
draftState.data = { ...state.data, ...action.data };
break;
}
case RESET_PROPS: {
return crudInitialState;
}

View File

@ -3,6 +3,7 @@ import {
GET_DATA,
GET_DATA_SUCCEEDED,
INIT_FORM,
UPDATE_PARTIAL_DATA,
SET_DATA_STRUCTURES,
SET_STATUS,
SUBMIT_SUCCEEDED,
@ -95,7 +96,7 @@ describe('CONTENT MANAGER | sharedReducers | crudReducer', () => {
expect(crudReducer(state, action)).toEqual(expected);
});
it('should handle the SUBMIt_SUCCEEDED action correctly', () => {
it('should handle the SUBMIT_SUCCEEDED action correctly', () => {
const action = { type: SUBMIT_SUCCEEDED, data: 'test' };
const expected = produce(state, (draft) => {
@ -104,4 +105,40 @@ describe('CONTENT MANAGER | sharedReducers | crudReducer', () => {
expect(crudReducer(state, action)).toEqual(expected);
});
it('should set data using the UPDATE_PARTIAL_DATA action', () => {
const action = { type: UPDATE_PARTIAL_DATA, data: { new: true } };
expect(crudReducer(state, action)).toEqual(
expect.objectContaining({
data: expect.objectContaining({
new: true,
}),
})
);
});
it('should merge data using the UPDATE_PARTIAL_DATA action', () => {
const setupAction = {
type: GET_DATA_SUCCEEDED,
data: {
something: true,
},
};
state = crudReducer(state, setupAction);
const action = { type: UPDATE_PARTIAL_DATA, data: { new: true } };
state = crudReducer(state, action);
expect(state).toEqual(
expect.objectContaining({
data: expect.objectContaining({
something: true,
new: true,
}),
})
);
});
});

View File

@ -187,7 +187,7 @@ const SocialLinks = () => {
<GridGap>
{socialLinksExtended.map(({ icon, link, name }) => {
return (
<GridItem col={6} s={12} key={name}>
<GridItem col={6} s={12} key={name.id}>
<LinkCustom size="L" startIcon={icon} variant="tertiary" href={link} isExternal>
{formatMessage(name)}
</LinkCustom>

View File

@ -13,7 +13,7 @@ import { useDispatch } from 'react-redux';
import { useReviewWorkflows } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows';
import Information from '../../../../../../admin/src/content-manager/pages/EditView/Information';
import { submitSucceeded } from '../../../../../../admin/src/content-manager/sharedReducers/crudReducer/actions';
import { updatePartialData } from '../../../../../../admin/src/content-manager/sharedReducers/crudReducer/actions';
const ATTRIBUTE_NAME = 'strapi_reviewWorkflows_stage';
@ -50,7 +50,7 @@ export function InformationBoxEE() {
data: { id: stageId },
});
dispatch(submitSucceeded(createdEntity));
dispatch(updatePartialData({ [ATTRIBUTE_NAME]: createdEntity[ATTRIBUTE_NAME] }));
return createdEntity;
},
@ -111,7 +111,6 @@ export function InformationBoxEE() {
components={{
LoadingIndicator: () => <Loader small />,
}}
defaultValue={{ value: activeWorkflowStage?.id, label: activeWorkflowStage?.name }}
error={formattedError}
inputId={ATTRIBUTE_NAME}
isLoading={isLoading}
@ -122,6 +121,7 @@ export function InformationBoxEE() {
options={
workflow ? workflow.stages.map(({ id, name }) => ({ value: id, label: name })) : []
}
value={{ value: activeWorkflowStage?.id, label: activeWorkflowStage?.name }}
/>
<FieldError />

View File

@ -122,7 +122,8 @@ export function ReviewWorkflowsPage() {
useEffect(() => {
trackUsage('didViewWorkflow');
}, [trackUsage]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<CheckPagePermissions permissions={adminPermissions.settings['review-workflows'].main}>

View File

@ -62,7 +62,7 @@
"error.contentTypeName.reserved-name": "This name cannot be used in your project as it might break other functionalities",
"error.validation.enum-duplicate": "Duplicate values are not allowed (only alphanumeric characters are taken into account).",
"error.validation.enum-empty-string": "Empty strings are not allowed",
"error.validation.enum-regex": "At least one value is invalid. Values should have at least one alphabetical character preceeding the first occurence of a number.",
"error.validation.enum-regex": "At least one value is invalid. Values should have at least one alphabetical character preceding the first occurence of a number.",
"error.validation.minSupMax": "Can't be superior",
"error.validation.positive": "Must be a positive number",
"error.validation.regex": "Regex pattern is invalid",

View File

@ -57,15 +57,15 @@ class Database {
async function commit() {
if (notNestedTransaction) {
await trx.commit();
transactionCtx.clear();
await trx.commit();
}
}
async function rollback() {
if (notNestedTransaction) {
await trx.rollback();
transactionCtx.clear();
await trx.rollback();
}
}

View File

@ -61,7 +61,7 @@ const contentTypeSchemaValidator = yup.object().shape({
// should match the GraphQL regex
if (!regressedValues.every((value) => GRAPHQL_ENUM_REGEX.test(value))) {
const message = `Invalid enumeration value. Values should have at least one alphabetical character preceeding the first occurence of a number. Update your enumeration '${attrName}'.`;
const message = `Invalid enumeration value. Values should have at least one alphabetical character preceding the first occurence of a number. Update your enumeration '${attrName}'.`;
return this.createError({ message });
}