Undo FormModal reducer to create the error

Signed-off-by: HichamELBSI <elabbassih@gmail.com>
This commit is contained in:
HichamELBSI 2021-01-25 10:22:17 +01:00
parent 95ed2ee412
commit c4131b07e5
22 changed files with 355 additions and 553 deletions

View File

@ -19,8 +19,8 @@
"type": "string"
},
"categories": {
"collection": "category",
"via": "addresses",
"collection": "category",
"dominant": true
},
"cover": {

View File

@ -16,8 +16,8 @@
"type": "string"
},
"addresses": {
"via": "categories",
"collection": "address"
"collection": "address",
"via": "categories"
}
}
}

View File

@ -1,52 +0,0 @@
{
"routes": [
{
"method": "GET",
"path": "/newcollections",
"handler": "newcollection.find",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/newcollections/count",
"handler": "newcollection.count",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/newcollections/:id",
"handler": "newcollection.findOne",
"config": {
"policies": []
}
},
{
"method": "POST",
"path": "/newcollections",
"handler": "newcollection.create",
"config": {
"policies": []
}
},
{
"method": "PUT",
"path": "/newcollections/:id",
"handler": "newcollection.update",
"config": {
"policies": []
}
},
{
"method": "DELETE",
"path": "/newcollections/:id",
"handler": "newcollection.delete",
"config": {
"policies": []
}
}
]
}

View File

@ -1,8 +0,0 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
* to customize this controller
*/
module.exports = {};

View File

@ -1,8 +0,0 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
* to customize this model
*/
module.exports = {};

View File

@ -1,24 +0,0 @@
{
"kind": "collectionType",
"collectionName": "newcollections",
"info": {
"name": "newcollection"
},
"options": {
"increments": true,
"timestamps": true,
"draftAndPublish": false
},
"attributes": {
"title": {
"default": "dazdazdzad",
"private": true,
"regex": "dzadaz",
"maxLength": 120,
"unique": true,
"minLength": 10,
"type": "text",
"required": true
}
}
}

View File

@ -1,8 +0,0 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
* to customize this service
*/
module.exports = {};

View File

@ -2,8 +2,7 @@
"collectionName": "components_blog_test_comos",
"info": {
"name": "test comp",
"icon": "ad",
"description": ""
"icon": "ad"
},
"options": {},
"attributes": {

View File

@ -60,10 +60,9 @@ import plugins from './plugins';
const strapi = Strapi();
const initialState = {};
const MOUNT_NODE = document.getElementById('app') || document.createElement('div');
const store = configureStore(initialState, strapi);
const store = configureStore(initialState);
const { dispatch } = store;
const MOUNT_NODE = document.getElementById('app') || document.createElement('div');
Object.keys(plugins).forEach(current => {
const registerPlugin = plugin => {
@ -79,7 +78,6 @@ Object.keys(plugins).forEach(current => {
registerField: strapi.fieldApi.registerField,
registerPlugin,
settingsBaseURL: SETTINGS_BASE_URL || '/settings',
middlewares: strapi.middlewares,
});
const pluginTradsPrefixed = languages.reduce((acc, lang) => {
@ -107,7 +105,7 @@ Object.keys(plugins).forEach(current => {
try {
merge(translationMessages, pluginTradsPrefixed);
// dispatch(pluginLoaded(plugin));
dispatch(pluginLoaded(plugin));
} catch (err) {
console.log({ err });
}

View File

@ -6,26 +6,17 @@ import { createStore, applyMiddleware, compose } from 'redux';
import { fromJS } from 'immutable';
// import { routerMiddleware } from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import thunkMiddleware from 'redux-thunk';
import createReducer from './reducers';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, strapi) {
export default function configureStore(initialState = {}) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [sagaMiddleware];
const thunkMiddlewares = [thunkMiddleware.withExtraArgument(initialState)];
// Add the plugins middlewares
console.log('loop')
for (let i in strapi.middlewares.middlewares) {
console.log(i);
// thunkMiddlewares.push(app.middlewares[i]());
}
const enhancers = [applyMiddleware(...middlewares, ...thunkMiddlewares)];
const enhancers = [applyMiddleware(...middlewares)];
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */

View File

@ -249,8 +249,6 @@ export class Admin extends React.Component {
updatePlugin,
} = this.props;
console.log(plugins);
// We need the admin data in order to make the initializers work
if (this.showLoader()) {
return (

View File

@ -1,16 +0,0 @@
import { cloneDeep } from 'lodash';
class MiddleWares {
middlewares = [];
add(middleware) {
console.log('add: ', middleware);
this.middlewares.push(middleware);
}
get middlewares() {
return cloneDeep(this.middlewares);
}
}
export default () => new MiddleWares();

View File

@ -1,12 +1,9 @@
import ComponentApi from './ComponentApi';
import FieldApi from './FieldApi';
import MiddleWares from './MiddleWares';
class Strapi {
componentApi = ComponentApi();
middlewares = MiddleWares();
fieldApi = FieldApi();
}

View File

@ -93,7 +93,6 @@
"redux": "^4.0.1",
"redux-immutable": "^4.0.0",
"redux-saga": "^0.16.0",
"redux-thunk": "2.3.0",
"reselect": "^4.0.0",
"sanitize.css": "^4.1.0",
"semver": "7.3.4",

View File

@ -109,18 +109,18 @@ const formatLayoutWithMetas = (contentTypeConfiguration, ctUid, models) => {
metadatas: get(contentTypeConfiguration, ['metadatas', attribute.name, 'edit'], {}),
};
// if (fieldSchema.type === 'relation') {
// const queryInfos = ctUid
// ? generateRelationQueryInfosForComponents(
// contentTypeConfiguration,
// attribute.name,
// ctUid,
// models
// )
// : generateRelationQueryInfos(contentTypeConfiguration, attribute.name, models);
if (fieldSchema.type === 'relation') {
const queryInfos = ctUid
? generateRelationQueryInfosForComponents(
contentTypeConfiguration,
attribute.name,
ctUid,
models
)
: generateRelationQueryInfos(contentTypeConfiguration, attribute.name, models);
// set(data, 'queryInfos', queryInfos);
// }
set(data, 'queryInfos', queryInfos);
}
return data;
});

View File

@ -8,7 +8,8 @@ import {
PopUpWarning,
} from 'strapi-helper-plugin';
import { useHistory, useLocation, useRouteMatch, Redirect } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { connect, useDispatch } from 'react-redux';
import { compose } from 'redux';
import DataManagerContext from '../../contexts/DataManagerContext';
import getTrad from '../../utils/getTrad';
import makeUnique from '../../utils/makeUnique';
@ -48,10 +49,18 @@ import {
} from './constants';
import makeSelectDataManagerProvider from './selectors';
const DataManagerProvider = ({ allIcons, children }) => {
const dataManagerProviderSelector = useMemo(makeSelectDataManagerProvider, []);
const DataManagerProvider = ({
allIcons,
children,
components,
contentTypes,
isLoading,
isLoadingForDataToBeSet,
initialData,
modifiedData,
reservedNames,
}) => {
const dispatch = useDispatch();
const reducerState = useSelector(state => dataManagerProviderSelector(state), []);
const [infoModals, toggleInfoModal] = useState({ cancel: false });
const {
autoReload,
@ -61,15 +70,6 @@ const DataManagerProvider = ({ allIcons, children }) => {
formatMessage,
menu,
} = useGlobalContext();
const {
components,
contentTypes,
isLoading,
isLoadingForDataToBeSet,
initialData,
modifiedData,
reservedNames,
} = reducerState;
const { pathname } = useLocation();
const { push } = useHistory();
const contentTypeMatch = useRouteMatch(`/plugins/${pluginId}/content-types/:uid`);
@ -595,9 +595,23 @@ const DataManagerProvider = ({ allIcons, children }) => {
);
};
DataManagerProvider.defaultProps = {
components: {},
};
DataManagerProvider.propTypes = {
allIcons: PropTypes.array.isRequired,
children: PropTypes.node.isRequired,
components: PropTypes.object,
contentTypes: PropTypes.object.isRequired,
isLoading: PropTypes.bool.isRequired,
isLoadingForDataToBeSet: PropTypes.bool.isRequired,
initialData: PropTypes.object.isRequired,
modifiedData: PropTypes.object.isRequired,
reservedNames: PropTypes.object.isRequired,
};
export default memo(DataManagerProvider);
const mapStateToProps = makeSelectDataManagerProvider();
const withConnect = connect(mapStateToProps, null);
export default compose(withConnect)(memo(DataManagerProvider));

View File

@ -2,26 +2,9 @@ import { fromJS, OrderedMap } from 'immutable';
import { get, has } from 'lodash';
import makeUnique from '../../utils/makeUnique';
import retrieveComponentsFromSchema from './utils/retrieveComponentsFromSchema';
import * as actions from './constants';
import {
ADD_ATTRIBUTE,
ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE,
CANCEL_CHANGES,
CHANGE_DYNAMIC_ZONE_COMPONENTS,
CREATE_SCHEMA,
CREATE_COMPONENT_SCHEMA,
DELETE_NOT_SAVED_TYPE,
EDIT_ATTRIBUTE,
GET_DATA_SUCCEEDED,
RELOAD_PLUGIN,
REMOVE_FIELD_FROM_DISPLAYED_COMPONENT,
REMOVE_COMPONENT_FROM_DYNAMIC_ZONE,
REMOVE_FIELD,
SET_MODIFIED_DATA,
UPDATE_SCHEMA,
} from './constants';
const initialState = {
const initialState = fromJS({
components: {},
contentTypes: {},
initialComponents: {},
@ -31,7 +14,7 @@ const initialState = {
reservedNames: {},
isLoading: true,
isLoadingForDataToBeSet: true,
};
});
const ONE_SIDE_RELATIONS = ['oneWay', 'manyWay'];
@ -83,11 +66,9 @@ const addComponentsToState = (state, componentToAddUid, objToUpdate) => {
return newObj;
};
const reducer = (jsonState = initialState, action) => {
const state = fromJS(jsonState);
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_ATTRIBUTE: {
case actions.ADD_ATTRIBUTE: {
const {
attributeToSet: { name, ...rest },
forTarget,
@ -142,28 +123,24 @@ const reducer = (jsonState = initialState, action) => {
}
return existingCompos;
})
.toJS();
});
}
case ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE: {
case actions.ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE: {
const { dynamicZoneTarget, componentsToAdd } = action;
return state
.updateIn(
['modifiedData', 'contentType', 'schema', 'attributes', dynamicZoneTarget, 'components'],
list => {
return list.concat(componentsToAdd);
}
)
.toJS();
return state.updateIn(
['modifiedData', 'contentType', 'schema', 'attributes', dynamicZoneTarget, 'components'],
list => {
return list.concat(componentsToAdd);
}
);
}
case CANCEL_CHANGES: {
case actions.CANCEL_CHANGES: {
return state
.update('modifiedData', () => state.get('initialData'))
.update('components', () => state.get('initialComponents'))
.toJS();
.update('components', () => state.get('initialComponents'));
}
case CHANGE_DYNAMIC_ZONE_COMPONENTS: {
case actions.CHANGE_DYNAMIC_ZONE_COMPONENTS: {
const { dynamicZoneTarget, newComponents } = action;
return state
@ -179,11 +156,10 @@ const reducer = (jsonState = initialState, action) => {
}, old);
return componentsSchema;
})
.toJS();
});
}
case CREATE_SCHEMA: {
case actions.CREATE_SCHEMA: {
const newSchema = {
uid: action.uid,
isTemporary: true,
@ -193,9 +169,9 @@ const reducer = (jsonState = initialState, action) => {
},
};
return state.updateIn(['contentTypes', action.uid], () => fromJS(newSchema)).toJS();
return state.updateIn(['contentTypes', action.uid], () => fromJS(newSchema));
}
case CREATE_COMPONENT_SCHEMA: {
case actions.CREATE_COMPONENT_SCHEMA: {
const newSchema = {
uid: action.uid,
isTemporary: true,
@ -209,20 +185,18 @@ const reducer = (jsonState = initialState, action) => {
if (action.shouldAddComponentToData) {
return state
.updateIn(['components', action.uid], () => fromJS(newSchema))
.updateIn(['modifiedData', 'components', action.uid], () => fromJS(newSchema))
.toJS();
.updateIn(['modifiedData', 'components', action.uid], () => fromJS(newSchema));
}
return state.updateIn(['components', action.uid], () => fromJS(newSchema)).toJS();
return state.updateIn(['components', action.uid], () => fromJS(newSchema));
}
case DELETE_NOT_SAVED_TYPE: {
case actions.DELETE_NOT_SAVED_TYPE: {
// Doing so will also reset the modified and the initial data
return state
.update('contentTypes', () => state.get('initialContentTypes'))
.update('components', () => state.get('initialComponents'))
.toJS();
.update('components', () => state.get('initialComponents'));
}
case EDIT_ATTRIBUTE: {
case actions.EDIT_ATTRIBUTE: {
const {
attributeToSet: { name, ...rest },
forTarget,
@ -236,134 +210,132 @@ const reducer = (jsonState = initialState, action) => {
? [forTarget]
: [forTarget, targetUid];
return newState
.updateIn(['modifiedData', ...pathToDataToEdit, 'schema'], obj => {
let oppositeAttributeNameToRemove = null;
let oppositeAttributeNameToUpdate = null;
let oppositeAttributeNameToCreateBecauseOfNatureChange = null;
let oppositeAttributeToCreate = null;
return newState.updateIn(['modifiedData', ...pathToDataToEdit, 'schema'], obj => {
let oppositeAttributeNameToRemove = null;
let oppositeAttributeNameToUpdate = null;
let oppositeAttributeNameToCreateBecauseOfNatureChange = null;
let oppositeAttributeToCreate = null;
const newObj = OrderedMap(
obj
.get('attributes')
.keySeq()
.reduce((acc, current) => {
const isEditingCurrentAttribute = current === initialAttributeName;
const newObj = OrderedMap(
obj
.get('attributes')
.keySeq()
.reduce((acc, current) => {
const isEditingCurrentAttribute = current === initialAttributeName;
if (isEditingCurrentAttribute) {
const currentUid = state.getIn(['modifiedData', ...pathToDataToEdit, 'uid']);
const isEditingRelation = has(initialAttribute, 'nature');
const didChangeTargetRelation = initialAttribute.target !== rest.target;
const didCreateInternalRelation = rest.target === currentUid;
const nature = rest.nature;
const initialNature = initialAttribute.nature;
const hadInternalRelation = initialAttribute.target === currentUid;
const didChangeRelationNature = initialAttribute.nature !== nature;
const shouldRemoveOppositeAttributeBecauseOfTargetChange =
didChangeTargetRelation &&
!didCreateInternalRelation &&
hadInternalRelation &&
isEditingRelation;
const shouldRemoveOppositeAttributeBecauseOfNatureChange =
didChangeRelationNature &&
hadInternalRelation &&
['oneWay', 'manyWay'].includes(nature) &&
isEditingRelation;
const shouldUpdateOppositeAttributeBecauseOfNatureChange =
!ONE_SIDE_RELATIONS.includes(initialNature) &&
!ONE_SIDE_RELATIONS.includes(nature) &&
hadInternalRelation &&
didCreateInternalRelation &&
isEditingRelation;
const shouldCreateOppositeAttributeBecauseOfNatureChange =
ONE_SIDE_RELATIONS.includes(initialNature) &&
!ONE_SIDE_RELATIONS.includes(nature) &&
hadInternalRelation &&
didCreateInternalRelation &&
isEditingRelation;
const shouldCreateOppositeAttributeBecauseOfTargetChange =
didChangeTargetRelation &&
didCreateInternalRelation &&
!ONE_SIDE_RELATIONS.includes(nature);
if (isEditingCurrentAttribute) {
const currentUid = state.getIn(['modifiedData', ...pathToDataToEdit, 'uid']);
const isEditingRelation = has(initialAttribute, 'nature');
const didChangeTargetRelation = initialAttribute.target !== rest.target;
const didCreateInternalRelation = rest.target === currentUid;
const nature = rest.nature;
const initialNature = initialAttribute.nature;
const hadInternalRelation = initialAttribute.target === currentUid;
const didChangeRelationNature = initialAttribute.nature !== nature;
const shouldRemoveOppositeAttributeBecauseOfTargetChange =
didChangeTargetRelation &&
!didCreateInternalRelation &&
hadInternalRelation &&
isEditingRelation;
const shouldRemoveOppositeAttributeBecauseOfNatureChange =
didChangeRelationNature &&
hadInternalRelation &&
['oneWay', 'manyWay'].includes(nature) &&
isEditingRelation;
const shouldUpdateOppositeAttributeBecauseOfNatureChange =
!ONE_SIDE_RELATIONS.includes(initialNature) &&
!ONE_SIDE_RELATIONS.includes(nature) &&
hadInternalRelation &&
didCreateInternalRelation &&
isEditingRelation;
const shouldCreateOppositeAttributeBecauseOfNatureChange =
ONE_SIDE_RELATIONS.includes(initialNature) &&
!ONE_SIDE_RELATIONS.includes(nature) &&
hadInternalRelation &&
didCreateInternalRelation &&
isEditingRelation;
const shouldCreateOppositeAttributeBecauseOfTargetChange =
didChangeTargetRelation &&
didCreateInternalRelation &&
!ONE_SIDE_RELATIONS.includes(nature);
// Update the opposite attribute name so it is removed at the end of the loop
// Update the opposite attribute name so it is removed at the end of the loop
if (
shouldRemoveOppositeAttributeBecauseOfTargetChange ||
shouldRemoveOppositeAttributeBecauseOfNatureChange
) {
oppositeAttributeNameToRemove = initialAttribute.targetAttribute;
}
// Set the opposite attribute that will be updated when the loop attribute matches the name
if (
shouldUpdateOppositeAttributeBecauseOfNatureChange ||
shouldCreateOppositeAttributeBecauseOfNatureChange ||
shouldCreateOppositeAttributeBecauseOfTargetChange
) {
oppositeAttributeNameToUpdate = initialAttribute.targetAttribute;
oppositeAttributeNameToCreateBecauseOfNatureChange = rest.targetAttribute;
oppositeAttributeToCreate = {
nature: getOppositeNature(rest.nature),
target: rest.target,
unique: rest.unique,
// Leave this if we allow the required on the relation
// required: rest.required,
dominant: rest.nature === 'manyToMany' ? !rest.dominant : null,
targetAttribute: name,
columnName: rest.targetColumnName,
targetColumnName: rest.columnName,
};
// First update the current attribute with the value
acc[name] = fromJS(rest);
// Then (if needed) create the opposite attribute the case is changing the relation from
// We do it here so keep the order of the attributes
// oneWay || manyWay to something another relation
if (
shouldRemoveOppositeAttributeBecauseOfTargetChange ||
shouldRemoveOppositeAttributeBecauseOfNatureChange
) {
oppositeAttributeNameToRemove = initialAttribute.targetAttribute;
}
// Set the opposite attribute that will be updated when the loop attribute matches the name
if (
shouldUpdateOppositeAttributeBecauseOfNatureChange ||
shouldCreateOppositeAttributeBecauseOfNatureChange ||
shouldCreateOppositeAttributeBecauseOfTargetChange
) {
oppositeAttributeNameToUpdate = initialAttribute.targetAttribute;
oppositeAttributeNameToCreateBecauseOfNatureChange = rest.targetAttribute;
acc[oppositeAttributeNameToCreateBecauseOfNatureChange] = fromJS(
oppositeAttributeToCreate
);
oppositeAttributeToCreate = {
nature: getOppositeNature(rest.nature),
target: rest.target,
unique: rest.unique,
// Leave this if we allow the required on the relation
// required: rest.required,
dominant: rest.nature === 'manyToMany' ? !rest.dominant : null,
targetAttribute: name,
columnName: rest.targetColumnName,
targetColumnName: rest.columnName,
};
// First update the current attribute with the value
acc[name] = fromJS(rest);
// Then (if needed) create the opposite attribute the case is changing the relation from
// We do it here so keep the order of the attributes
// oneWay || manyWay to something another relation
if (
shouldCreateOppositeAttributeBecauseOfNatureChange ||
shouldCreateOppositeAttributeBecauseOfTargetChange
) {
acc[oppositeAttributeNameToCreateBecauseOfNatureChange] = fromJS(
oppositeAttributeToCreate
);
oppositeAttributeToCreate = null;
oppositeAttributeNameToCreateBecauseOfNatureChange = null;
}
return acc;
oppositeAttributeToCreate = null;
oppositeAttributeNameToCreateBecauseOfNatureChange = null;
}
acc[name] = fromJS(rest);
} else if (current === oppositeAttributeNameToUpdate) {
acc[oppositeAttributeNameToCreateBecauseOfNatureChange] = fromJS(
oppositeAttributeToCreate
);
} else {
acc[current] = obj.getIn(['attributes', current]);
return acc;
}
return acc;
}, {})
);
acc[name] = fromJS(rest);
} else if (current === oppositeAttributeNameToUpdate) {
acc[oppositeAttributeNameToCreateBecauseOfNatureChange] = fromJS(
oppositeAttributeToCreate
);
} else {
acc[current] = obj.getIn(['attributes', current]);
}
let updatedObj;
return acc;
}, {})
);
// Remove the opposite attribute
if (oppositeAttributeNameToRemove !== null) {
updatedObj = newObj.remove(oppositeAttributeNameToRemove);
} else {
updatedObj = newObj;
}
let updatedObj;
return obj.set('attributes', updatedObj);
})
.toJS();
// Remove the opposite attribute
if (oppositeAttributeNameToRemove !== null) {
updatedObj = newObj.remove(oppositeAttributeNameToRemove);
} else {
updatedObj = newObj;
}
return obj.set('attributes', updatedObj);
});
}
case GET_DATA_SUCCEEDED: {
case actions.GET_DATA_SUCCEEDED: {
return state
.update('components', () => fromJS(action.components))
.update('initialComponents', () => fromJS(action.components))
@ -371,38 +343,33 @@ const reducer = (jsonState = initialState, action) => {
.update('contentTypes', () => fromJS(action.contentTypes))
.update('reservedNames', () => fromJS(action.reservedNames))
.update('isLoading', () => false)
.toJS();
.update('isLoading', () => false);
}
case RELOAD_PLUGIN:
case actions.RELOAD_PLUGIN:
return initialState;
case REMOVE_FIELD_FROM_DISPLAYED_COMPONENT: {
case actions.REMOVE_FIELD_FROM_DISPLAYED_COMPONENT: {
const { attributeToRemoveName, componentUid } = action;
return state
.removeIn([
'modifiedData',
'components',
componentUid,
'schema',
'attributes',
attributeToRemoveName,
])
.toJS();
return state.removeIn([
'modifiedData',
'components',
componentUid,
'schema',
'attributes',
attributeToRemoveName,
]);
}
case REMOVE_COMPONENT_FROM_DYNAMIC_ZONE:
return state
.removeIn([
'modifiedData',
'contentType',
'schema',
'attributes',
action.dzName,
'components',
action.componentToRemoveIndex,
])
.toJS();
case REMOVE_FIELD: {
case actions.REMOVE_COMPONENT_FROM_DYNAMIC_ZONE:
return state.removeIn([
'modifiedData',
'contentType',
'schema',
'attributes',
action.dzName,
'components',
action.componentToRemoveIndex,
]);
case actions.REMOVE_FIELD: {
const { mainDataKey, attributeToRemoveName } = action;
const pathToAttributes = ['modifiedData', mainDataKey, 'schema', 'attributes'];
const pathToAttributeToRemove = [...pathToAttributes, attributeToRemoveName];
@ -423,25 +390,21 @@ const reducer = (jsonState = initialState, action) => {
if (shouldRemoveOppositeAttribute) {
return state
.removeIn(pathToAttributeToRemove)
.removeIn([...pathToAttributes, targetAttribute])
.toJS();
.removeIn([...pathToAttributes, targetAttribute]);
}
}
return state
.removeIn(pathToAttributeToRemove)
.updateIn([...pathToAttributes], attributes => {
return attributes.keySeq().reduce((acc, current) => {
if (acc.getIn([current, 'targetField']) === attributeToRemoveName) {
return acc.removeIn([current, 'targetField']);
}
return state.removeIn(pathToAttributeToRemove).updateIn([...pathToAttributes], attributes => {
return attributes.keySeq().reduce((acc, current) => {
if (acc.getIn([current, 'targetField']) === attributeToRemoveName) {
return acc.removeIn([current, 'targetField']);
}
return acc;
}, attributes);
})
.toJS();
return acc;
}, attributes);
});
}
case SET_MODIFIED_DATA: {
case actions.SET_MODIFIED_DATA: {
let newState = state
.update('isLoadingForDataToBeSet', () => false)
.update('initialData', () => fromJS(action.schemaToSet))
@ -455,9 +418,9 @@ const reducer = (jsonState = initialState, action) => {
.update('contentTypes', () => state.get('initialContentTypes'));
}
return newState.toJS();
return newState;
}
case UPDATE_SCHEMA: {
case actions.UPDATE_SCHEMA: {
const {
data: { name, collectionName, category, icon, kind },
schemaType,
@ -487,10 +450,10 @@ const reducer = (jsonState = initialState, action) => {
});
}
return newState.toJS();
return newState;
}
default:
return state.toJS();
return state;
}
};

View File

@ -5,7 +5,8 @@ import { initialState } from './reducer';
/**
* Direct selector to the dataManagerProvider state domain
*/
const dataManagerProviderDomain = () => state => state.get(`${pluginId}_dataManagerProvider`) || initialState;
const dataManagerProviderDomain = () => state =>
state.get(`${pluginId}_dataManagerProvider`) || initialState;
/**
* Other specific selectors
@ -17,7 +18,7 @@ const dataManagerProviderDomain = () => state => state.get(`${pluginId}_dataMana
const makeSelectDataManagerProvider = () =>
createSelector(dataManagerProviderDomain(), substate => {
return substate;
return substate.toJS();
});
export default makeSelectDataManagerProvider;

View File

@ -98,7 +98,7 @@ const FormModal = () => {
initialData,
isCreatingComponentWhileAddingAField,
modifiedData,
} = reducerState;
} = reducerState.toJS();
useEffect(() => {
if (!isEmpty(search)) {

View File

@ -4,169 +4,149 @@ import { snakeCase } from 'lodash';
import makeUnique from '../../utils/makeUnique';
import { createComponentUid } from './utils/createUid';
import { shouldPluralizeName, shouldPluralizeTargetAttribute } from './utils/relations';
import {
ADD_COMPONENTS_TO_DYNAMIC_ZONE,
ON_CHANGE,
ON_CHANGE_ALLOWED_TYPE,
RESET_PROPS,
RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO,
RESET_PROPS_AND_SAVE_CURRENT_DATA,
RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ,
SET_DATA_TO_EDIT,
SET_ATTRIBUTE_DATA_SCHEMA,
SET_DYNAMIC_ZONE_DATA_SCHEMA,
SET_ERRORS,
} from './constants';
import * as actions from './constants';
const initialState = {
const initialState = fromJS({
formErrors: {},
modifiedData: {},
initialData: {},
componentToCreate: {},
isCreatingComponentWhileAddingAField: false,
};
const formModalReducer = (jsonState = initialState, action) => {
const state = fromJS(jsonState);
});
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_COMPONENTS_TO_DYNAMIC_ZONE: {
case actions.ADD_COMPONENTS_TO_DYNAMIC_ZONE: {
const { name, components, shouldAddComponents } = action;
return state
.updateIn(['modifiedData', name], list => {
let updatedList = list;
return state.updateIn(['modifiedData', name], list => {
let updatedList = list;
if (shouldAddComponents) {
updatedList = list.concat(components);
} else {
updatedList = list.filter(comp => {
return components.indexOf(comp) === -1;
});
}
if (shouldAddComponents) {
updatedList = list.concat(components);
} else {
updatedList = list.filter(comp => {
return components.indexOf(comp) === -1;
});
}
return List(makeUnique(updatedList.toJS()));
})
.toJS();
return List(makeUnique(updatedList.toJS()));
});
}
case ON_CHANGE:
return state
.update('modifiedData', obj => {
const {
selectedContentTypeFriendlyName,
keys,
value,
oneThatIsCreatingARelationWithAnother,
} = action;
const hasDefaultValue = Boolean(obj.getIn(['default']));
case actions.ON_CHANGE:
return state.update('modifiedData', obj => {
const {
selectedContentTypeFriendlyName,
keys,
value,
oneThatIsCreatingARelationWithAnother,
} = action;
const hasDefaultValue = Boolean(obj.getIn(['default']));
// There is no need to remove the default key if the default value isn't defined
if (hasDefaultValue && keys.length === 1 && keys.includes('type')) {
const previousType = obj.getIn(['type']);
// There is no need to remove the default key if the default value isn't defined
if (hasDefaultValue && keys.length === 1 && keys.includes('type')) {
const previousType = obj.getIn(['type']);
if (previousType && ['date', 'datetime', 'time'].includes(previousType)) {
return obj.updateIn(keys, () => value).remove('default');
}
if (previousType && ['date', 'datetime', 'time'].includes(previousType)) {
return obj.updateIn(keys, () => value).remove('default');
}
}
if (keys.length === 1 && keys.includes('nature')) {
return obj
.update('nature', () => value)
.update('dominant', () => {
if (value === 'manyToMany') {
return true;
}
if (keys.length === 1 && keys.includes('nature')) {
return obj
.update('nature', () => value)
.update('dominant', () => {
if (value === 'manyToMany') {
return true;
}
return null;
})
.update('name', oldValue => {
return pluralize(snakeCase(oldValue), shouldPluralizeName(value));
})
.update('targetAttribute', oldValue => {
if (['oneWay', 'manyWay'].includes(value)) {
return '-';
}
return pluralize(
oldValue === '-' ? snakeCase(oneThatIsCreatingARelationWithAnother) : oldValue,
shouldPluralizeTargetAttribute(value)
);
})
.update('targetColumnName', oldValue => {
if (['oneWay', 'manyWay'].includes(value)) {
return null;
})
.update('name', oldValue => {
return pluralize(snakeCase(oldValue), shouldPluralizeName(value));
})
.update('targetAttribute', oldValue => {
if (['oneWay', 'manyWay'].includes(value)) {
return '-';
}
}
return pluralize(
oldValue === '-' ? snakeCase(oneThatIsCreatingARelationWithAnother) : oldValue,
shouldPluralizeTargetAttribute(value)
);
})
.update('targetColumnName', oldValue => {
if (['oneWay', 'manyWay'].includes(value)) {
return null;
}
return oldValue;
});
}
return oldValue;
});
}
if (keys.length === 1 && keys.includes('target')) {
const { targetContentTypeAllowedRelations } = action;
let didChangeNatureBecauseOfRestrictedRelation = false;
return obj
.update('target', () => value)
.update('nature', currentNature => {
if (targetContentTypeAllowedRelations === null) {
return currentNature;
}
if (!targetContentTypeAllowedRelations.includes(currentNature)) {
didChangeNatureBecauseOfRestrictedRelation = true;
return targetContentTypeAllowedRelations[0];
}
if (keys.length === 1 && keys.includes('target')) {
const { targetContentTypeAllowedRelations } = action;
let didChangeNatureBecauseOfRestrictedRelation = false;
return obj
.update('target', () => value)
.update('nature', currentNature => {
if (targetContentTypeAllowedRelations === null) {
return currentNature;
})
.update('name', () => {
if (didChangeNatureBecauseOfRestrictedRelation) {
return pluralize(
snakeCase(selectedContentTypeFriendlyName),
shouldPluralizeName(targetContentTypeAllowedRelations[0])
);
}
}
if (!targetContentTypeAllowedRelations.includes(currentNature)) {
didChangeNatureBecauseOfRestrictedRelation = true;
return targetContentTypeAllowedRelations[0];
}
return currentNature;
})
.update('name', () => {
if (didChangeNatureBecauseOfRestrictedRelation) {
return pluralize(
snakeCase(selectedContentTypeFriendlyName),
shouldPluralizeName(obj.get('nature'))
shouldPluralizeName(targetContentTypeAllowedRelations[0])
);
})
.update('targetAttribute', () => {
if (['oneWay', 'manyWay'].includes(obj.get('nature'))) {
return '-';
}
}
if (
didChangeNatureBecauseOfRestrictedRelation &&
['oneWay', 'manyWay'].includes(targetContentTypeAllowedRelations[0])
) {
return '-';
}
return pluralize(
snakeCase(selectedContentTypeFriendlyName),
return pluralize(
snakeCase(oneThatIsCreatingARelationWithAnother),
shouldPluralizeTargetAttribute(obj.get('nature'))
);
});
shouldPluralizeName(obj.get('nature'))
);
})
.update('targetAttribute', () => {
if (['oneWay', 'manyWay'].includes(obj.get('nature'))) {
return '-';
}
if (
didChangeNatureBecauseOfRestrictedRelation &&
['oneWay', 'manyWay'].includes(targetContentTypeAllowedRelations[0])
) {
return '-';
}
return pluralize(
snakeCase(oneThatIsCreatingARelationWithAnother),
shouldPluralizeTargetAttribute(obj.get('nature'))
);
});
}
return obj.updateIn(keys, () => value);
});
case actions.ON_CHANGE_ALLOWED_TYPE: {
if (action.name === 'all') {
return state.updateIn(['modifiedData', 'allowedTypes'], () => {
if (action.value) {
return fromJS(['images', 'videos', 'files']);
}
return obj.updateIn(keys, () => value);
})
.toJS();
case ON_CHANGE_ALLOWED_TYPE: {
if (action.name === 'all') {
return state
.updateIn(['modifiedData', 'allowedTypes'], () => {
if (action.value) {
return fromJS(['images', 'videos', 'files']);
}
return null;
})
.toJS();
return null;
});
}
return state.updateIn(['modifiedData', 'allowedTypes'], currentList => {
@ -185,15 +165,15 @@ const formModalReducer = (jsonState = initialState, action) => {
return list.push(action.name);
});
}
case RESET_PROPS:
case actions.RESET_PROPS:
return initialState;
case RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO: {
case actions.RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO: {
// This is run when the user doesn't want to create a new component
return fromJS(initialState)
.update('modifiedData', () => fromJS({ type: 'component', repeatable: true }))
.toJS();
return initialState.update('modifiedData', () =>
fromJS({ type: 'component', repeatable: true })
);
}
case RESET_PROPS_AND_SAVE_CURRENT_DATA: {
case actions.RESET_PROPS_AND_SAVE_CURRENT_DATA: {
// This is run when the user has created a new component
const componentToCreate = state.getIn(['modifiedData', 'componentToCreate']);
const modifiedData = fromJS({
@ -206,31 +186,27 @@ const formModalReducer = (jsonState = initialState, action) => {
),
});
return fromJS(initialState)
return initialState
.update('componentToCreate', () => componentToCreate)
.update('modifiedData', () => modifiedData)
.update('isCreatingComponentWhileAddingAField', () =>
state.getIn(['modifiedData', 'createComponent'])
)
.toJS();
);
}
case RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ: {
case actions.RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ: {
const createdDZ = state.get('modifiedData');
const dataToSet = createdDZ
.set('createComponent', true)
.set('componentToCreate', fromJS({ type: 'component' }));
return fromJS(initialState)
.update('modifiedData', () => dataToSet)
.toJS();
return initialState.update('modifiedData', () => dataToSet);
}
case SET_DATA_TO_EDIT: {
case actions.SET_DATA_TO_EDIT: {
return state
.updateIn(['modifiedData'], () => fromJS(action.data))
.updateIn(['initialData'], () => fromJS(action.data))
.toJS();
.updateIn(['initialData'], () => fromJS(action.data));
}
case SET_ATTRIBUTE_DATA_SCHEMA: {
case actions.SET_ATTRIBUTE_DATA_SCHEMA: {
const {
attributeType,
isEditing,
@ -243,8 +219,7 @@ const formModalReducer = (jsonState = initialState, action) => {
if (isEditing) {
return state
.update('modifiedData', () => fromJS(modifiedDataToSetForEditing))
.update('initialData', () => fromJS(modifiedDataToSetForEditing))
.toJS();
.update('initialData', () => fromJS(modifiedDataToSetForEditing));
}
let dataToSet;
@ -294,21 +269,20 @@ const formModalReducer = (jsonState = initialState, action) => {
dataToSet = { type: attributeType, default: null };
}
return state.update('modifiedData', () => fromJS(dataToSet)).toJS();
return state.update('modifiedData', () => fromJS(dataToSet));
}
case SET_DYNAMIC_ZONE_DATA_SCHEMA: {
case actions.SET_DYNAMIC_ZONE_DATA_SCHEMA: {
return state
.update('modifiedData', () => fromJS(action.attributeToEdit))
.update('initialData', () => fromJS(action.attributeToEdit))
.toJS();
.update('initialData', () => fromJS(action.attributeToEdit));
}
case SET_ERRORS:
return state.update('formErrors', () => fromJS(action.errors)).toJS();
case actions.SET_ERRORS:
return state.update('formErrors', () => fromJS(action.errors));
default:
return state.toJS();
return state;
}
};
export default formModalReducer;
export default reducer;
export { initialState };

View File

@ -74,16 +74,5 @@ export default strapi => {
},
};
const modalOnChangeMiddleware = () => {
return ({ dispatch, getState }) => next => action => {
if (action.type === 'ContentTypeBuilder/FormModal/ON_CHANGE') {
console.log(action);
}
return next(action);
};
};
strapi.middlewares.add(modalOnChangeMiddleware);
return strapi.registerPlugin(plugin);
};

View File

@ -16202,11 +16202,6 @@ redux-saga@^0.16.0:
resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-0.16.2.tgz#993662e86bc945d8509ac2b8daba3a8c615cc971"
integrity sha512-iIjKnRThI5sKPEASpUvySemjzwqwI13e3qP7oLub+FycCRDysLSAOwt958niZW6LhxfmS6Qm1BzbU70w/Koc4w==
redux-thunk@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
redux@^4.0.1, redux@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"