mirror of
https://github.com/strapi/strapi.git
synced 2025-08-27 10:15:59 +00:00
Handle edit relation
This commit is contained in:
parent
d9ca6451d7
commit
b9ffe9de46
@ -18,6 +18,14 @@
|
|||||||
"review": {
|
"review": {
|
||||||
"model": "review",
|
"model": "review",
|
||||||
"via": "likes"
|
"via": "likes"
|
||||||
|
},
|
||||||
|
"like_left": {
|
||||||
|
"collection": "like",
|
||||||
|
"via": "like_right"
|
||||||
|
},
|
||||||
|
"like_right": {
|
||||||
|
"model": "like",
|
||||||
|
"via": "like_left"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,21 @@ const DataManagerProvider = ({ children }) => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isLoading, pathname]);
|
}, [isLoading, pathname]);
|
||||||
|
|
||||||
const addAttribute = (attributeToSet, forTarget, targetUid) => {
|
const addAttribute = (
|
||||||
|
attributeToSet,
|
||||||
|
forTarget,
|
||||||
|
targetUid,
|
||||||
|
isEditing = false,
|
||||||
|
initialAttribute
|
||||||
|
) => {
|
||||||
|
const actionType = isEditing ? 'EDIT_ATTRIBUTE' : 'ADD_ATTRIBUTE';
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ADD_ATTRIBUTE',
|
type: actionType,
|
||||||
attributeToSet,
|
attributeToSet,
|
||||||
forTarget,
|
forTarget,
|
||||||
targetUid,
|
targetUid,
|
||||||
|
initialAttribute,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,7 +147,7 @@ const DataManagerProvider = ({ children }) => {
|
|||||||
return <Redirect to={`/plugins/${pluginId}/content-types/${firstCTUid}`} />;
|
return <Redirect to={`/plugins/${pluginId}/content-types/${firstCTUid}`} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log({ modifiedData, contentTypes });
|
console.log({ modifiedData: modifiedData.contentType });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataManagerContext.Provider
|
<DataManagerContext.Provider
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { fromJS } from 'immutable';
|
import { fromJS, OrderedMap } from 'immutable';
|
||||||
import { get } from 'lodash';
|
import { get, has } from 'lodash';
|
||||||
const initialState = fromJS({
|
const initialState = fromJS({
|
||||||
components: {},
|
components: {},
|
||||||
contentTypes: {},
|
contentTypes: {},
|
||||||
@ -9,6 +9,17 @@ const initialState = fromJS({
|
|||||||
isLoadingForDataToBeSet: true,
|
isLoadingForDataToBeSet: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ONE_SIDE_RELATIONS = ['oneWay', 'manyWay'];
|
||||||
|
const getOppositeNature = originalNature => {
|
||||||
|
if (originalNature === 'manyToOne') {
|
||||||
|
return 'oneToMany';
|
||||||
|
} else if (originalNature === 'oneToMany') {
|
||||||
|
return 'manyToOne';
|
||||||
|
} else {
|
||||||
|
return originalNature;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_ATTRIBUTE': {
|
case 'ADD_ATTRIBUTE': {
|
||||||
@ -49,13 +60,14 @@ const reducer = (state, action) => {
|
|||||||
target === currentUid
|
target === currentUid
|
||||||
) {
|
) {
|
||||||
const oppositeAttribute = {
|
const oppositeAttribute = {
|
||||||
nature,
|
nature: getOppositeNature(nature),
|
||||||
target,
|
target,
|
||||||
type,
|
|
||||||
unique: rest.unique,
|
unique: rest.unique,
|
||||||
required: rest.required,
|
required: rest.required,
|
||||||
dominant: nature === 'manyToMany' ? !rest.dominant : null,
|
dominant: nature === 'manyToMany' ? !rest.dominant : null,
|
||||||
targetAttribute: name,
|
targetAttribute: name,
|
||||||
|
columnName: rest.targetColumnName,
|
||||||
|
targetColumnName: rest.columnName,
|
||||||
};
|
};
|
||||||
|
|
||||||
return obj.update(rest.targetAttribute, () => {
|
return obj.update(rest.targetAttribute, () => {
|
||||||
@ -67,6 +79,150 @@ const reducer = (state, action) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case 'EDIT_ATTRIBUTE': {
|
||||||
|
const {
|
||||||
|
attributeToSet: { name, ...rest },
|
||||||
|
forTarget,
|
||||||
|
targetUid,
|
||||||
|
initialAttribute,
|
||||||
|
} = action;
|
||||||
|
const initialAttributeName = get(initialAttribute, ['name'], '');
|
||||||
|
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||||
|
? [forTarget]
|
||||||
|
: [forTarget, targetUid];
|
||||||
|
|
||||||
|
return state.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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
) {
|
||||||
|
oppositeAttributeNameToUpdate =
|
||||||
|
initialAttribute.targetAttribute;
|
||||||
|
oppositeAttributeNameToCreateBecauseOfNatureChange =
|
||||||
|
rest.targetAttribute;
|
||||||
|
|
||||||
|
oppositeAttributeToCreate = {
|
||||||
|
nature: getOppositeNature(rest.nature),
|
||||||
|
target: rest.target,
|
||||||
|
unique: rest.unique,
|
||||||
|
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) {
|
||||||
|
acc[
|
||||||
|
oppositeAttributeNameToCreateBecauseOfNatureChange
|
||||||
|
] = fromJS(oppositeAttributeToCreate);
|
||||||
|
|
||||||
|
oppositeAttributeToCreate = null;
|
||||||
|
oppositeAttributeNameToCreateBecauseOfNatureChange = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[name] = fromJS(rest);
|
||||||
|
} else if (current === oppositeAttributeNameToUpdate) {
|
||||||
|
acc[
|
||||||
|
oppositeAttributeNameToCreateBecauseOfNatureChange
|
||||||
|
] = fromJS(oppositeAttributeToCreate);
|
||||||
|
} else {
|
||||||
|
acc[current] = obj.getIn(['attributes', current]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
|
||||||
|
let updatedObj;
|
||||||
|
|
||||||
|
// Remove the opposite attribute
|
||||||
|
if (oppositeAttributeNameToRemove !== null) {
|
||||||
|
console.log('ppppp');
|
||||||
|
updatedObj = newObj.remove(oppositeAttributeNameToRemove);
|
||||||
|
} else {
|
||||||
|
updatedObj = newObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj.set('attributes', updatedObj);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
case 'GET_DATA_SUCCEEDED':
|
case 'GET_DATA_SUCCEEDED':
|
||||||
return state
|
return state
|
||||||
.update('components', () => fromJS(action.components))
|
.update('components', () => fromJS(action.components))
|
||||||
|
@ -285,7 +285,13 @@ const FormModal = () => {
|
|||||||
search: nextSearch,
|
search: nextSearch,
|
||||||
});
|
});
|
||||||
} else if (state.modalType === 'attribute') {
|
} else if (state.modalType === 'attribute') {
|
||||||
addAttribute(modifiedData, state.forTarget, state.targetUid);
|
addAttribute(
|
||||||
|
modifiedData,
|
||||||
|
state.forTarget,
|
||||||
|
state.targetUid,
|
||||||
|
state.actionType === 'edit',
|
||||||
|
initialData
|
||||||
|
);
|
||||||
push({ search: nextSearch });
|
push({ search: nextSearch });
|
||||||
} else {
|
} else {
|
||||||
console.log('Do something with component later');
|
console.log('Do something with component later');
|
||||||
|
@ -47,6 +47,13 @@ const reducer = (state, action) => {
|
|||||||
: oldValue,
|
: oldValue,
|
||||||
shouldPluralizeTargetAttribute(value)
|
shouldPluralizeTargetAttribute(value)
|
||||||
);
|
);
|
||||||
|
})
|
||||||
|
.update('targetColumnName', oldValue => {
|
||||||
|
if (['oneWay', 'manyWay'].includes(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldValue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +117,8 @@ const reducer = (state, action) => {
|
|||||||
unique: false,
|
unique: false,
|
||||||
required: false,
|
required: false,
|
||||||
dominant: null,
|
dominant: null,
|
||||||
|
columnName: null,
|
||||||
|
targetColumnName: null,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
dataToSet = { type: attributeType, default: null };
|
dataToSet = { type: attributeType, default: null };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user