mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 02:44:55 +00:00
Migrate CollectionTypeFormWrapper and SingleTypeFormWrapper to redux
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
6f29989e3b
commit
48da7db14e
@ -1,7 +1,8 @@
|
||||
import { memo, useCallback, useEffect, useMemo, useRef, useReducer } from 'react';
|
||||
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { get } from 'lodash';
|
||||
import { request, useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
createDefaultForm,
|
||||
@ -11,18 +12,31 @@ import {
|
||||
removeFieldsFromClonedData,
|
||||
} from '../../utils';
|
||||
import pluginId from '../../pluginId';
|
||||
import { crudInitialState, crudReducer } from '../../sharedReducers';
|
||||
import {
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
initForm,
|
||||
resetProps,
|
||||
setDataStructures,
|
||||
setStatus,
|
||||
submitSucceeded,
|
||||
} from '../../sharedReducers/crudReducer/actions';
|
||||
import selectCrudReducer from '../../sharedReducers/crudReducer/selectors';
|
||||
import { getRequestUrl } from './utils';
|
||||
|
||||
// This container is used to handle the CRUD
|
||||
const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, origin }) => {
|
||||
const { emitEvent } = useGlobalContext();
|
||||
const { push, replace } = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
componentsDataStructure,
|
||||
contentTypeDataStructure,
|
||||
data,
|
||||
isLoading,
|
||||
status,
|
||||
} = useSelector(selectCrudReducer);
|
||||
|
||||
const [
|
||||
{ componentsDataStructure, contentTypeDataStructure, data, isLoading, status },
|
||||
dispatch,
|
||||
] = useReducer(crudReducer, crudInitialState);
|
||||
const emitEventRef = useRef(emitEvent);
|
||||
|
||||
const isCreatingEntry = id === 'create';
|
||||
@ -87,31 +101,32 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
allLayoutData.components
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: 'SET_DATA_STRUCTURES',
|
||||
componentsDataStructure,
|
||||
contentTypeDataStructure: formatComponentData(
|
||||
contentTypeDataStructure,
|
||||
allLayoutData.contentType,
|
||||
allLayoutData.components
|
||||
),
|
||||
});
|
||||
}, [allLayoutData]);
|
||||
const contentTypeDataStructureFormatted = formatComponentData(
|
||||
contentTypeDataStructure,
|
||||
allLayoutData.contentType,
|
||||
allLayoutData.components
|
||||
);
|
||||
|
||||
dispatch(setDataStructures(componentsDataStructure, contentTypeDataStructureFormatted));
|
||||
}, [allLayoutData, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(resetProps());
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
const abortController = new AbortController();
|
||||
const { signal } = abortController;
|
||||
|
||||
const getData = async signal => {
|
||||
dispatch({ type: 'GET_DATA' });
|
||||
const fetchData = async signal => {
|
||||
dispatch(getData());
|
||||
|
||||
try {
|
||||
const data = await request(requestURL, { method: 'GET', signal });
|
||||
|
||||
dispatch({
|
||||
type: 'GET_DATA_SUCCEEDED',
|
||||
data: cleanReceivedData(cleanClonedData(data)),
|
||||
});
|
||||
dispatch(getDataSucceeded(cleanReceivedData(cleanClonedData(data))));
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') {
|
||||
return;
|
||||
@ -137,15 +152,15 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
};
|
||||
|
||||
if (requestURL) {
|
||||
getData(signal);
|
||||
fetchData(signal);
|
||||
} else {
|
||||
dispatch({ type: 'INIT_FORM' });
|
||||
dispatch(initForm());
|
||||
}
|
||||
|
||||
return () => {
|
||||
abortController.abort();
|
||||
};
|
||||
}, [requestURL, push, from, cleanReceivedData, cleanClonedData]);
|
||||
}, [requestURL, push, from, cleanReceivedData, cleanClonedData, dispatch]);
|
||||
|
||||
const displayErrors = useCallback(err => {
|
||||
const errorPayload = err.response.payload;
|
||||
@ -196,7 +211,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
|
||||
try {
|
||||
// Show a loading button in the EditView/Header.js && lock the app => no navigation
|
||||
dispatch({ type: 'SET_STATUS', status: 'submit-pending' });
|
||||
dispatch(setStatus('submit-pending'));
|
||||
|
||||
const response = await request(endPoint, { method: 'POST', body });
|
||||
|
||||
@ -206,18 +221,18 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
message: { id: getTrad('success.record.save') },
|
||||
});
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
// Enable navigation and remove loaders
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(setStatus('resolved'));
|
||||
|
||||
replace(`/plugins/${pluginId}/collectionType/${slug}/${response.id}`);
|
||||
} catch (err) {
|
||||
emitEventRef.current('didNotCreateEntry', { error: err, trackerProperty });
|
||||
displayErrors(err);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
},
|
||||
[cleanReceivedData, displayErrors, replace, slug]
|
||||
[cleanReceivedData, displayErrors, replace, slug, dispatch]
|
||||
);
|
||||
|
||||
const onPublish = useCallback(async () => {
|
||||
@ -225,14 +240,14 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
emitEventRef.current('willPublishEntry');
|
||||
const endPoint = getRequestUrl(`${slug}/${id}/actions/publish`);
|
||||
|
||||
dispatch({ type: 'SET_STATUS', status: 'publish-pending' });
|
||||
dispatch(setStatus('publish-pending'));
|
||||
|
||||
const data = await request(endPoint, { method: 'POST' });
|
||||
|
||||
emitEventRef.current('didPublishEntry');
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(data) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(data)));
|
||||
dispatch(setStatus('resolved'));
|
||||
|
||||
strapi.notification.toggle({
|
||||
type: 'success',
|
||||
@ -240,9 +255,9 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
});
|
||||
} catch (err) {
|
||||
displayErrors(err);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
}, [cleanReceivedData, displayErrors, id, slug]);
|
||||
}, [cleanReceivedData, displayErrors, id, slug, dispatch]);
|
||||
|
||||
const onPut = useCallback(
|
||||
async (body, trackerProperty) => {
|
||||
@ -251,7 +266,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
try {
|
||||
emitEventRef.current('willEditEntry', trackerProperty);
|
||||
|
||||
dispatch({ type: 'SET_STATUS', status: 'submit-pending' });
|
||||
dispatch(setStatus('submit-pending'));
|
||||
|
||||
const response = await request(endPoint, { method: 'PUT', body });
|
||||
|
||||
@ -261,21 +276,23 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
message: { id: getTrad('success.record.save') },
|
||||
});
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
emitEventRef.current('didNotEditEntry', { error: err, trackerProperty });
|
||||
displayErrors(err);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
},
|
||||
[cleanReceivedData, displayErrors, slug, id]
|
||||
[cleanReceivedData, displayErrors, slug, id, dispatch]
|
||||
);
|
||||
|
||||
const onUnpublish = useCallback(async () => {
|
||||
const endPoint = getRequestUrl(`${slug}/${id}/actions/unpublish`);
|
||||
|
||||
dispatch({ type: 'SET_STATUS', status: 'unpublish-pending' });
|
||||
dispatch(setStatus('unpublish-pending'));
|
||||
|
||||
try {
|
||||
emitEventRef.current('willUnpublishEntry');
|
||||
@ -285,13 +302,13 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, from, slug, id, or
|
||||
emitEventRef.current('didUnpublishEntry');
|
||||
strapi.notification.success(getTrad('success.record.unpublish'));
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(setStatus('resolved'));
|
||||
displayErrors(err);
|
||||
}
|
||||
}, [cleanReceivedData, displayErrors, id, slug]);
|
||||
}, [cleanReceivedData, displayErrors, id, slug, dispatch]);
|
||||
|
||||
return children({
|
||||
componentsDataStructure,
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { memo, useCallback, useEffect, useRef, useReducer, useState } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { get } from 'lodash';
|
||||
import { request, useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
createDefaultForm,
|
||||
@ -9,7 +10,16 @@ import {
|
||||
getTrad,
|
||||
removePasswordFieldsFromData,
|
||||
} from '../../utils';
|
||||
import { crudInitialState, crudReducer } from '../../sharedReducers';
|
||||
import {
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
initForm,
|
||||
resetProps,
|
||||
setDataStructures,
|
||||
setStatus,
|
||||
submitSucceeded,
|
||||
} from '../../sharedReducers/crudReducer/actions';
|
||||
import selectCrudReducer from '../../sharedReducers/crudReducer/selectors';
|
||||
import { getRequestUrl } from './utils';
|
||||
|
||||
// This container is used to handle the CRUD
|
||||
@ -19,10 +29,14 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
const emitEventRef = useRef(emitEvent);
|
||||
const [isCreatingEntry, setIsCreatingEntry] = useState(true);
|
||||
|
||||
const [
|
||||
{ componentsDataStructure, contentTypeDataStructure, data, isLoading, status },
|
||||
dispatch,
|
||||
] = useReducer(crudReducer, crudInitialState);
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
componentsDataStructure,
|
||||
contentTypeDataStructure,
|
||||
data,
|
||||
isLoading,
|
||||
status,
|
||||
} = useSelector(selectCrudReducer);
|
||||
|
||||
const cleanReceivedData = useCallback(
|
||||
data => {
|
||||
@ -38,6 +52,12 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
[allLayoutData]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
dispatch(resetProps());
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
const componentsDataStructure = Object.keys(allLayoutData.components).reduce((acc, current) => {
|
||||
const defaultComponentForm = createDefaultForm(
|
||||
@ -58,17 +78,14 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
allLayoutData.contentType.attributes,
|
||||
allLayoutData.components
|
||||
);
|
||||
const contentTypeDataStructureFormatted = formatComponentData(
|
||||
contentTypeDataStructure,
|
||||
allLayoutData.contentType,
|
||||
allLayoutData.components
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: 'SET_DATA_STRUCTURES',
|
||||
componentsDataStructure,
|
||||
contentTypeDataStructure: formatComponentData(
|
||||
contentTypeDataStructure,
|
||||
allLayoutData.contentType,
|
||||
allLayoutData.components
|
||||
),
|
||||
});
|
||||
}, [allLayoutData]);
|
||||
dispatch(setDataStructures(componentsDataStructure, contentTypeDataStructureFormatted));
|
||||
}, [allLayoutData, dispatch]);
|
||||
|
||||
// Check if creation mode or editing mode
|
||||
useEffect(() => {
|
||||
@ -76,17 +93,15 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
const { signal } = abortController;
|
||||
|
||||
const fetchData = async signal => {
|
||||
dispatch({ type: 'GET_DATA' });
|
||||
dispatch(getData());
|
||||
|
||||
setIsCreatingEntry(true);
|
||||
|
||||
try {
|
||||
const data = await request(getRequestUrl(slug), { method: 'GET', signal });
|
||||
|
||||
dispatch({
|
||||
type: 'GET_DATA_SUCCEEDED',
|
||||
data: cleanReceivedData(data),
|
||||
});
|
||||
dispatch(getDataSucceeded(cleanReceivedData(data)));
|
||||
|
||||
setIsCreatingEntry(false);
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') {
|
||||
@ -97,7 +112,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
|
||||
// Creating a single type
|
||||
if (responseStatus === 404) {
|
||||
dispatch({ type: 'INIT_FORM' });
|
||||
dispatch(initForm());
|
||||
}
|
||||
|
||||
if (responseStatus === 403) {
|
||||
@ -111,7 +126,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
fetchData(signal);
|
||||
|
||||
return () => abortController.abort();
|
||||
}, [cleanReceivedData, from, push, slug]);
|
||||
}, [cleanReceivedData, from, push, slug, dispatch]);
|
||||
|
||||
const displayErrors = useCallback(err => {
|
||||
const errorPayload = err.response.payload;
|
||||
@ -155,15 +170,15 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
const onDeleteSucceeded = useCallback(() => {
|
||||
setIsCreatingEntry(true);
|
||||
|
||||
dispatch({ type: 'INIT_FORM' });
|
||||
}, []);
|
||||
dispatch(initForm());
|
||||
}, [dispatch]);
|
||||
|
||||
const onPost = useCallback(
|
||||
async (body, trackerProperty) => {
|
||||
const endPoint = getRequestUrl(slug);
|
||||
|
||||
try {
|
||||
dispatch({ type: 'SET_STATUS', status: 'submit-pending' });
|
||||
dispatch(setStatus('submit-pending'));
|
||||
|
||||
const response = await request(endPoint, { method: 'PUT', body });
|
||||
|
||||
@ -173,24 +188,26 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
message: { id: getTrad('success.record.save') },
|
||||
});
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
setIsCreatingEntry(false);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
emitEventRef.current('didNotCreateEntry', { error: err, trackerProperty });
|
||||
|
||||
displayErrors(err);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
},
|
||||
[cleanReceivedData, displayErrors, slug]
|
||||
[cleanReceivedData, displayErrors, slug, dispatch]
|
||||
);
|
||||
const onPublish = useCallback(async () => {
|
||||
try {
|
||||
emitEventRef.current('willPublishEntry');
|
||||
const endPoint = getRequestUrl(`${slug}/actions/publish`);
|
||||
|
||||
dispatch({ type: 'SET_STATUS', status: 'publish-pending' });
|
||||
dispatch(setStatus('publish-pending'));
|
||||
|
||||
const data = await request(endPoint, { method: 'POST' });
|
||||
|
||||
@ -200,13 +217,15 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
message: { id: getTrad('success.record.publish') },
|
||||
});
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(data) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(data)));
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
displayErrors(err);
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
}, [cleanReceivedData, displayErrors, slug]);
|
||||
}, [cleanReceivedData, displayErrors, slug, dispatch]);
|
||||
|
||||
const onPut = useCallback(
|
||||
async (body, trackerProperty) => {
|
||||
@ -215,7 +234,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
try {
|
||||
emitEventRef.current('willEditEntry', trackerProperty);
|
||||
|
||||
dispatch({ type: 'SET_STATUS', status: 'submit-pending' });
|
||||
dispatch(setStatus('submit-pending'));
|
||||
|
||||
const response = await request(endPoint, { method: 'PUT', body });
|
||||
|
||||
@ -226,22 +245,25 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
|
||||
emitEventRef.current('didEditEntry', { trackerProperty });
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
displayErrors(err);
|
||||
|
||||
emitEventRef.current('didNotEditEntry', { error: err, trackerProperty });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
}
|
||||
},
|
||||
[cleanReceivedData, displayErrors, slug]
|
||||
[cleanReceivedData, displayErrors, slug, dispatch]
|
||||
);
|
||||
|
||||
// The publish and unpublish method could be refactored but let's leave the duplication for now
|
||||
const onUnpublish = useCallback(async () => {
|
||||
const endPoint = getRequestUrl(`${slug}/actions/unpublish`);
|
||||
dispatch({ type: 'SET_STATUS', status: 'unpublish-pending' });
|
||||
|
||||
dispatch(setStatus('unpublish-pending'));
|
||||
|
||||
try {
|
||||
emitEventRef.current('willUnpublishEntry');
|
||||
@ -251,13 +273,14 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, from, slug }) => {
|
||||
emitEventRef.current('didUnpublishEntry');
|
||||
strapi.notification.success(getTrad('success.record.unpublish'));
|
||||
|
||||
dispatch({ type: 'SUBMIT_SUCCEEDED', data: cleanReceivedData(response) });
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(submitSucceeded(cleanReceivedData(response)));
|
||||
|
||||
dispatch(setStatus('resolved'));
|
||||
} catch (err) {
|
||||
dispatch({ type: 'SET_STATUS', status: 'resolved' });
|
||||
dispatch(setStatus('resolved'));
|
||||
displayErrors(err);
|
||||
}
|
||||
}, [cleanReceivedData, displayErrors, slug]);
|
||||
}, [cleanReceivedData, displayErrors, slug, dispatch]);
|
||||
|
||||
return children({
|
||||
componentsDataStructure,
|
||||
|
||||
@ -2,6 +2,7 @@ import mainReducer from './containers/Main/reducer';
|
||||
import editViewLayoutManagerReducer from './containers/EditViewLayoutManager/reducer';
|
||||
import listViewReducer from './containers/ListView/reducer';
|
||||
import rbacManagerReducer from './containers/RBACManager/reducer';
|
||||
import editViewCrudReducer from './sharedReducers/crudReducer/reducer';
|
||||
import pluginId from './pluginId';
|
||||
|
||||
const reducers = {
|
||||
@ -9,6 +10,7 @@ const reducers = {
|
||||
[`${pluginId}_listView`]: listViewReducer,
|
||||
[`${pluginId}_rbacManager`]: rbacManagerReducer,
|
||||
[`${pluginId}_editViewLayoutManager`]: editViewLayoutManagerReducer,
|
||||
[`${pluginId}_editViewCrudReducer`]: editViewCrudReducer,
|
||||
};
|
||||
|
||||
export default reducers;
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
import {
|
||||
GET_DATA,
|
||||
GET_DATA_SUCCEEDED,
|
||||
INIT_FORM,
|
||||
RESET_PROPS,
|
||||
SET_DATA_STRUCTURES,
|
||||
SET_STATUS,
|
||||
SUBMIT_SUCCEEDED,
|
||||
} from './constants';
|
||||
|
||||
export const getData = () => {
|
||||
return {
|
||||
type: GET_DATA,
|
||||
};
|
||||
};
|
||||
|
||||
export const getDataSucceeded = data => ({
|
||||
type: GET_DATA_SUCCEEDED,
|
||||
data,
|
||||
});
|
||||
|
||||
export const initForm = () => ({
|
||||
type: INIT_FORM,
|
||||
});
|
||||
|
||||
export const resetProps = () => ({ type: RESET_PROPS });
|
||||
|
||||
export const setDataStructures = (componentsDataStructure, contentTypeDataStructure) => ({
|
||||
type: SET_DATA_STRUCTURES,
|
||||
componentsDataStructure,
|
||||
contentTypeDataStructure,
|
||||
});
|
||||
|
||||
export const setStatus = status => ({
|
||||
type: SET_STATUS,
|
||||
status,
|
||||
});
|
||||
|
||||
export const submitSucceeded = data => ({
|
||||
type: SUBMIT_SUCCEEDED,
|
||||
data,
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
export const GET_DATA = 'ContentManager/CrudReducer/GET_DATA';
|
||||
export const GET_DATA_SUCCEEDED = 'ContentManager/CrudReducer/GET_DATA_SUCCEEDED';
|
||||
export const INIT_FORM = 'ContentManager/CrudReducer/INIT_FORM';
|
||||
export const RESET_PROPS = 'ContentManager/CrudReducer/RESET_PROPS';
|
||||
export const SET_DATA_STRUCTURES = 'ContentManager/CrudReducer/SET_DATA_STRUCTURES';
|
||||
export const SET_STATUS = 'ContentManager/CrudReducer/SET_STATUS';
|
||||
export const SUBMIT_SUCCEEDED = 'ContentManager/CrudReducer/SUBMIT_SUCCEEDED';
|
||||
@ -7,6 +7,16 @@ import produce from 'immer';
|
||||
// require us to add the dispatch to the array wich is not wanted. This refacto does not require us to
|
||||
// to do any of this.
|
||||
|
||||
import {
|
||||
GET_DATA,
|
||||
GET_DATA_SUCCEEDED,
|
||||
INIT_FORM,
|
||||
RESET_PROPS,
|
||||
SET_DATA_STRUCTURES,
|
||||
SET_STATUS,
|
||||
SUBMIT_SUCCEEDED,
|
||||
} from './constants';
|
||||
|
||||
const crudInitialState = {
|
||||
componentsDataStructure: {},
|
||||
contentTypeDataStructure: {},
|
||||
@ -15,34 +25,37 @@ const crudInitialState = {
|
||||
status: 'resolved',
|
||||
};
|
||||
|
||||
const crudReducer = (state, action) =>
|
||||
const crudReducer = (state = crudInitialState, action) =>
|
||||
produce(state, draftState => {
|
||||
switch (action.type) {
|
||||
case 'GET_DATA': {
|
||||
case GET_DATA: {
|
||||
draftState.isLoading = true;
|
||||
draftState.data = {};
|
||||
break;
|
||||
}
|
||||
case 'GET_DATA_SUCCEEDED': {
|
||||
case GET_DATA_SUCCEEDED: {
|
||||
draftState.isLoading = false;
|
||||
draftState.data = action.data;
|
||||
break;
|
||||
}
|
||||
case 'INIT_FORM': {
|
||||
case INIT_FORM: {
|
||||
draftState.isLoading = false;
|
||||
draftState.data = state.contentTypeDataStructure;
|
||||
break;
|
||||
}
|
||||
case 'SET_DATA_STRUCTURES': {
|
||||
case RESET_PROPS: {
|
||||
return crudInitialState;
|
||||
}
|
||||
case SET_DATA_STRUCTURES: {
|
||||
draftState.componentsDataStructure = action.componentsDataStructure;
|
||||
draftState.contentTypeDataStructure = action.contentTypeDataStructure;
|
||||
break;
|
||||
}
|
||||
case 'SET_STATUS': {
|
||||
case SET_STATUS: {
|
||||
draftState.status = action.status;
|
||||
break;
|
||||
}
|
||||
case 'SUBMIT_SUCCEEDED': {
|
||||
case SUBMIT_SUCCEEDED: {
|
||||
draftState.data = action.data;
|
||||
break;
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/* eslint-disable consistent-return */
|
||||
import produce from 'immer';
|
||||
|
||||
// NOTE: instead of creating a shared reducer here, we could also create a hook
|
||||
// that returns the dispatch and the state, however it will mess with the linter
|
||||
// and force us to either disable the linter for the hooks dependencies array rule or
|
||||
// require us to add the dispatch to the array wich is not wanted. This refacto does not require us to
|
||||
// to do any of this.
|
||||
|
||||
import {
|
||||
GET_DATA,
|
||||
GET_DATA_SUCCEEDED,
|
||||
INIT_FORM,
|
||||
RESET_PROPS,
|
||||
SET_DATA_STRUCTURES,
|
||||
SET_STATUS,
|
||||
SUBMIT_SUCCEEDED,
|
||||
} from './constants';
|
||||
|
||||
const crudInitialState = {
|
||||
componentsDataStructure: {},
|
||||
contentTypeDataStructure: {},
|
||||
isLoading: true,
|
||||
data: {},
|
||||
status: 'resolved',
|
||||
};
|
||||
|
||||
const crudReducer = (state = crudInitialState, action) =>
|
||||
produce(state, draftState => {
|
||||
switch (action.type) {
|
||||
case GET_DATA: {
|
||||
draftState.isLoading = true;
|
||||
draftState.data = {};
|
||||
break;
|
||||
}
|
||||
case GET_DATA_SUCCEEDED: {
|
||||
draftState.isLoading = false;
|
||||
draftState.data = action.data;
|
||||
break;
|
||||
}
|
||||
case INIT_FORM: {
|
||||
draftState.isLoading = false;
|
||||
draftState.data = state.contentTypeDataStructure;
|
||||
break;
|
||||
}
|
||||
case RESET_PROPS: {
|
||||
return crudInitialState;
|
||||
}
|
||||
case SET_DATA_STRUCTURES: {
|
||||
draftState.componentsDataStructure = action.componentsDataStructure;
|
||||
draftState.contentTypeDataStructure = action.contentTypeDataStructure;
|
||||
break;
|
||||
}
|
||||
case SET_STATUS: {
|
||||
draftState.status = action.status;
|
||||
break;
|
||||
}
|
||||
case SUBMIT_SUCCEEDED: {
|
||||
draftState.data = action.data;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return draftState;
|
||||
}
|
||||
});
|
||||
|
||||
export default crudReducer;
|
||||
export { crudInitialState };
|
||||
@ -0,0 +1,5 @@
|
||||
import pluginId from '../../pluginId';
|
||||
|
||||
const selectCrudReducer = state => state.get(`${pluginId}_editViewCrudReducer`);
|
||||
|
||||
export default selectCrudReducer;
|
||||
@ -1,5 +1,5 @@
|
||||
import produce from 'immer';
|
||||
import crudReducer from '../crudReducer';
|
||||
import crudReducer from '../reducer';
|
||||
|
||||
describe('CONTENT MANAGER | sharedReducers | crudReducer', () => {
|
||||
let state;
|
||||
Loading…
x
Reference in New Issue
Block a user