mirror of
https://github.com/strapi/strapi.git
synced 2025-09-20 22:10:06 +00:00
Merge pull request #15818 from strapi/feat/relations-diffing-fe
This commit is contained in:
commit
14d5597a8f
@ -75,7 +75,7 @@ module.exports = {
|
||||
'<rootDir>/fileTransformer.js',
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(react-dnd|dnd-core|react-dnd-html5-backend|@strapi/design-system|@strapi/icons)/)',
|
||||
'node_modules/(?!(react-dnd|dnd-core|react-dnd-html5-backend|@strapi/design-system|@strapi/icons|fractional-indexing)/)',
|
||||
],
|
||||
testMatch: ['/**/tests/**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
testEnvironmentOptions: {
|
||||
|
@ -8,6 +8,7 @@ import uniqBy from 'lodash/uniqBy';
|
||||
import merge from 'lodash/merge';
|
||||
import castArray from 'lodash/castArray';
|
||||
import isNil from 'lodash/isNil';
|
||||
import { generateNKeysBetween } from 'fractional-indexing';
|
||||
|
||||
import {
|
||||
findLeafByPathAndReplace,
|
||||
@ -155,17 +156,33 @@ const reducer = (state, action) =>
|
||||
const initialDataRelations = get(state, initialDataPath);
|
||||
const modifiedDataRelations = get(state, modifiedDataPath);
|
||||
|
||||
/**
|
||||
* Check if the values we're loading are already in initial
|
||||
* data if they are then we don't need to load them at all
|
||||
*/
|
||||
const valuesToLoad = value.filter((relation) => {
|
||||
return !initialDataRelations.some((initialDataRelation) => {
|
||||
return initialDataRelation.id === relation.id;
|
||||
});
|
||||
});
|
||||
|
||||
set(draftState, initialDataPath, uniqBy([...valuesToLoad, ...initialDataRelations], 'id'));
|
||||
const keys = generateNKeysBetween(
|
||||
null,
|
||||
modifiedDataRelations[0]?.__temp_key__,
|
||||
valuesToLoad.length
|
||||
);
|
||||
|
||||
/**
|
||||
* Check if the values we're loading are already in initial
|
||||
* data if they are then we don't need to load them at all
|
||||
*/
|
||||
|
||||
const valuesWithKeys = valuesToLoad.map((relation, index) => ({
|
||||
...relation,
|
||||
__temp_key__: keys[index],
|
||||
}));
|
||||
|
||||
set(
|
||||
draftState,
|
||||
initialDataPath,
|
||||
uniqBy([...valuesWithKeys, ...initialDataRelations], 'id')
|
||||
);
|
||||
|
||||
/**
|
||||
* We need to set the value also on modifiedData, because initialData
|
||||
@ -175,7 +192,7 @@ const reducer = (state, action) =>
|
||||
set(
|
||||
draftState,
|
||||
modifiedDataPath,
|
||||
uniqBy([...valuesToLoad, ...modifiedDataRelations], 'id')
|
||||
uniqBy([...valuesWithKeys, ...modifiedDataRelations], 'id')
|
||||
);
|
||||
|
||||
break;
|
||||
@ -192,7 +209,9 @@ const reducer = (state, action) =>
|
||||
set(draftState, path, [value]);
|
||||
} else {
|
||||
const modifiedDataRelations = get(state, path);
|
||||
const newRelations = [...modifiedDataRelations, value];
|
||||
const [key] = generateNKeysBetween(modifiedDataRelations.at(-1)?.__temp_key__, null, 1);
|
||||
|
||||
const newRelations = [...modifiedDataRelations, { ...value, __temp_key__: key }];
|
||||
set(draftState, path, newRelations);
|
||||
}
|
||||
|
||||
@ -219,8 +238,19 @@ const reducer = (state, action) =>
|
||||
|
||||
const newRelations = [...modifiedDataRelations];
|
||||
|
||||
newRelations.splice(oldIndex, 1);
|
||||
newRelations.splice(newIndex, 0, currentItem);
|
||||
if (action.type === 'REORDER_RELATION') {
|
||||
const [newKey] = generateNKeysBetween(
|
||||
modifiedDataRelations[newIndex - 1]?.__temp_key__,
|
||||
modifiedDataRelations[newIndex]?.__temp_key__,
|
||||
1
|
||||
);
|
||||
|
||||
newRelations.splice(oldIndex, 1);
|
||||
newRelations.splice(newIndex, 0, { ...currentItem, __temp_key__: newKey });
|
||||
} else {
|
||||
newRelations.splice(oldIndex, 1);
|
||||
newRelations.splice(newIndex, 0, currentItem);
|
||||
}
|
||||
|
||||
set(draftState, path, newRelations);
|
||||
|
||||
|
@ -869,7 +869,7 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
componentsDataStructure: {},
|
||||
initialData: {},
|
||||
modifiedData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
};
|
||||
|
||||
@ -882,6 +882,74 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should set a temp key every time a relation is connected', () => {
|
||||
const state = {
|
||||
...initialState,
|
||||
|
||||
initialData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const nextState = reducer(state, {
|
||||
type: 'CONNECT_RELATION',
|
||||
keys: ['relation'],
|
||||
value: { id: 3 },
|
||||
});
|
||||
|
||||
expect(nextState).toStrictEqual({
|
||||
...initialState,
|
||||
componentsDataStructure: {},
|
||||
initialData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
{ id: 3, __temp_key__: 'a2' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(nextState, {
|
||||
type: 'CONNECT_RELATION',
|
||||
keys: ['relation'],
|
||||
value: { id: 4 },
|
||||
})
|
||||
).toStrictEqual({
|
||||
...initialState,
|
||||
componentsDataStructure: {},
|
||||
initialData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
{ id: 3, __temp_key__: 'a2' },
|
||||
{ id: 4, __temp_key__: 'a3' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should overwrite existing data, when toOneRelation is set to true', () => {
|
||||
const state = {
|
||||
...initialState,
|
||||
@ -953,10 +1021,10 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
expect(nextState).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
});
|
||||
|
||||
@ -970,10 +1038,16 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [{ id: 2 }, { id: 1 }],
|
||||
relation: [
|
||||
{ id: 2, __temp_key__: 'Zz' },
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [{ id: 2 }, { id: 1 }],
|
||||
relation: [
|
||||
{ id: 2, __temp_key__: 'Zz' },
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -1002,10 +1076,10 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
expect(nextState).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
});
|
||||
|
||||
@ -1019,10 +1093,103 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a temp key for all the relations added', () => {
|
||||
const state = {
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [],
|
||||
},
|
||||
};
|
||||
|
||||
const initialDataPath = ['initialData', 'relation'];
|
||||
const modifiedDataPath = ['modifiedData', 'relation'];
|
||||
|
||||
let nextState = reducer(state, {
|
||||
type: 'LOAD_RELATION',
|
||||
initialDataPath,
|
||||
modifiedDataPath,
|
||||
value: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
|
||||
});
|
||||
|
||||
expect(nextState).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
{ id: 3, __temp_key__: 'a2' },
|
||||
{ id: 4, __temp_key__: 'a3' },
|
||||
{ id: 5, __temp_key__: 'a4' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
{ id: 3, __temp_key__: 'a2' },
|
||||
{ id: 4, __temp_key__: 'a3' },
|
||||
{ id: 5, __temp_key__: 'a4' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a temp key working backwards on every new load because of how relations are shown in the UI', () => {
|
||||
const state = {
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [],
|
||||
},
|
||||
};
|
||||
|
||||
const initialDataPath = ['initialData', 'relation'];
|
||||
const modifiedDataPath = ['modifiedData', 'relation'];
|
||||
|
||||
let nextState = reducer(state, {
|
||||
type: 'LOAD_RELATION',
|
||||
initialDataPath,
|
||||
modifiedDataPath,
|
||||
value: [{ id: 1 }, { id: 2 }],
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(nextState, {
|
||||
type: 'LOAD_RELATION',
|
||||
initialDataPath,
|
||||
modifiedDataPath,
|
||||
value: [{ id: 3 }, { id: 4 }],
|
||||
})
|
||||
).toStrictEqual({
|
||||
...initialState,
|
||||
initialData: {
|
||||
relation: [
|
||||
{ id: 3, __temp_key__: 'Zy' },
|
||||
{ id: 4, __temp_key__: 'Zz' },
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ id: 3, __temp_key__: 'Zy' },
|
||||
{ id: 4, __temp_key__: 'Zz' },
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -2397,10 +2564,10 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
field1: {
|
||||
field2: {
|
||||
relation: [
|
||||
{ name: 'first' },
|
||||
{ name: 'second' },
|
||||
{ name: 'third' },
|
||||
{ name: 'fourth' },
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'second', __temp_key__: 'a1' },
|
||||
{ name: 'third', __temp_key__: 'a2' },
|
||||
{ name: 'fourth', __temp_key__: 'a3' },
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -2421,10 +2588,10 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
field1: {
|
||||
field2: {
|
||||
relation: [
|
||||
{ name: 'first' },
|
||||
{ name: 'fourth' },
|
||||
{ name: 'second' },
|
||||
{ name: 'third' },
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'fourth', __temp_key__: 'a0V' },
|
||||
{ name: 'second', __temp_key__: 'a1' },
|
||||
{ name: 'third', __temp_key__: 'a2' },
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -2433,6 +2600,89 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer',
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should move many components many times and have the correct temp keys', () => {
|
||||
const state = {
|
||||
...initialState,
|
||||
modifiedData: {
|
||||
relation: [
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'second', __temp_key__: 'a1' },
|
||||
{ name: 'third', __temp_key__: 'a2' },
|
||||
{ name: 'fourth', __temp_key__: 'a3' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const generateAction = (newIndex, oldIndex) => ({
|
||||
type: 'REORDER_RELATION',
|
||||
newIndex,
|
||||
oldIndex,
|
||||
keys: ['relation'],
|
||||
});
|
||||
|
||||
const generateExpected = (relation = []) => ({
|
||||
...initialState,
|
||||
modifiedData: {
|
||||
relation,
|
||||
},
|
||||
});
|
||||
|
||||
const nextState1 = reducer(state, generateAction(1, 3));
|
||||
|
||||
expect(nextState1).toEqual(
|
||||
generateExpected([
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'fourth', __temp_key__: 'a0V' },
|
||||
{ name: 'second', __temp_key__: 'a1' },
|
||||
{ name: 'third', __temp_key__: 'a2' },
|
||||
])
|
||||
);
|
||||
|
||||
const nextState2 = reducer(nextState1, generateAction(1, 2));
|
||||
|
||||
expect(nextState2).toEqual(
|
||||
generateExpected([
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'second', __temp_key__: 'a0G' },
|
||||
{ name: 'fourth', __temp_key__: 'a0V' },
|
||||
{ name: 'third', __temp_key__: 'a2' },
|
||||
])
|
||||
);
|
||||
|
||||
const nextState3 = reducer(nextState2, generateAction(0, 3));
|
||||
|
||||
expect(nextState3).toEqual(
|
||||
generateExpected([
|
||||
{ name: 'third', __temp_key__: 'Zz' },
|
||||
{ name: 'first', __temp_key__: 'a0' },
|
||||
{ name: 'second', __temp_key__: 'a0G' },
|
||||
{ name: 'fourth', __temp_key__: 'a0V' },
|
||||
])
|
||||
);
|
||||
|
||||
const nextState4 = reducer(nextState3, generateAction(3, 1));
|
||||
|
||||
expect(nextState4).toEqual(
|
||||
generateExpected([
|
||||
{ name: 'third', __temp_key__: 'Zz' },
|
||||
{ name: 'second', __temp_key__: 'a0G' },
|
||||
{ name: 'fourth', __temp_key__: 'a0V' },
|
||||
{ name: 'first', __temp_key__: 'a0O' },
|
||||
])
|
||||
);
|
||||
|
||||
const nextState5 = reducer(nextState4, generateAction(1, 2));
|
||||
|
||||
expect(nextState5).toEqual(
|
||||
generateExpected([
|
||||
{ name: 'third', __temp_key__: 'Zz' },
|
||||
{ name: 'fourth', __temp_key__: 'a0' },
|
||||
{ name: 'second', __temp_key__: 'a0G' },
|
||||
{ name: 'first', __temp_key__: 'a0O' },
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_DEFAULT_DATA_STRUCTURES', () => {
|
||||
|
@ -95,28 +95,22 @@ const cleanData = ({ browserState, serverState }, currentSchema, componentsSchem
|
||||
*/
|
||||
let actualOldValue = get(rootServerState, trueInitialDataPath, []);
|
||||
|
||||
const valuesWithPositions = value.map((relation, index, allRelations) => {
|
||||
const nextRelation = allRelations[index + 1];
|
||||
|
||||
if (nextRelation) {
|
||||
return { ...relation, position: { before: nextRelation.id } };
|
||||
}
|
||||
|
||||
return { ...relation, position: { end: true } };
|
||||
});
|
||||
|
||||
/**
|
||||
* Instead of the full relation object, we only want to send its ID
|
||||
* connectedRelations are the items that are in the browserState
|
||||
* array but not in the serverState
|
||||
*/
|
||||
const connectedRelations = valuesWithPositions.reduce((acc, relation, currentIndex) => {
|
||||
const indexOfRelationOnServer = actualOldValue.findIndex(
|
||||
const connectedRelations = value.reduce((acc, relation, currentIndex, array) => {
|
||||
const relationOnServer = actualOldValue.find(
|
||||
(oldRelation) => oldRelation.id === relation.id
|
||||
);
|
||||
|
||||
if (indexOfRelationOnServer === -1 || indexOfRelationOnServer !== currentIndex) {
|
||||
return [...acc, { id: relation.id, position: relation.position }];
|
||||
const relationInFront = array[currentIndex + 1];
|
||||
|
||||
if (!relationOnServer || relationOnServer.__temp_key__ !== relation.__temp_key__) {
|
||||
const position = relationInFront ? { before: relationInFront.id } : { end: true };
|
||||
|
||||
return [...acc, { id: relation.id, position }];
|
||||
}
|
||||
|
||||
return acc;
|
||||
@ -127,7 +121,7 @@ const cleanData = ({ browserState, serverState }, currentSchema, componentsSchem
|
||||
* are no longer in the browserState
|
||||
*/
|
||||
const disconnectedRelations = actualOldValue.reduce((acc, relation) => {
|
||||
if (!valuesWithPositions.find((newRelation) => newRelation.id === relation.id)) {
|
||||
if (!value.find((newRelation) => newRelation.id === relation.id)) {
|
||||
return [...acc, { id: relation.id }];
|
||||
}
|
||||
|
||||
|
@ -407,10 +407,10 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [{ id: 1, something: true }],
|
||||
relation: [{ id: 1, __temp_key__: 'a1', something: true }],
|
||||
},
|
||||
serverState: {
|
||||
relation: [{ id: 2, something: true }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0', something: true }],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
@ -429,7 +429,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [{ id: 1, something: true }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0', something: true }],
|
||||
},
|
||||
serverState: {
|
||||
relation: [],
|
||||
@ -454,7 +454,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
relation: [],
|
||||
},
|
||||
serverState: {
|
||||
relation: [{ id: 1, something: true }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0', something: true }],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
@ -477,13 +477,13 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
id: 1,
|
||||
relation_component: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
relation_component: {
|
||||
relation: [{ id: 2 }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -541,7 +541,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
id: 2,
|
||||
relation_component: {
|
||||
relation: [{ id: 2 }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -551,13 +551,13 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
id: 1,
|
||||
relation_component: {
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
relation_component: {
|
||||
relation: [{ id: 2 }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -599,13 +599,13 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 1,
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
{
|
||||
__component: 'basic.nested-relation',
|
||||
id: 2,
|
||||
relation_component: {
|
||||
relation: [{ id: 2 }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -615,7 +615,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 1,
|
||||
relation: [{ id: 3 }],
|
||||
relation: [{ id: 3, __temp_key__: 'a0' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -715,7 +715,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 1,
|
||||
relation: [{ id: 3 }],
|
||||
relation: [{ id: 3, __temp_key__: 'a0' }],
|
||||
},
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
@ -731,13 +731,13 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 1,
|
||||
relation: [{ id: 1 }],
|
||||
relation: [{ id: 1, __temp_key__: 'a0' }],
|
||||
},
|
||||
{
|
||||
__component: 'basic.nested-relation',
|
||||
id: 2,
|
||||
relation_component: {
|
||||
relation: [{ id: 2 }],
|
||||
relation: [{ id: 2, __temp_key__: 'a0' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -747,12 +747,12 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 1,
|
||||
relation: [{ id: 3 }],
|
||||
relation: [{ id: 3, __temp_key__: 'a0' }],
|
||||
},
|
||||
{
|
||||
__component: 'basic.relation',
|
||||
id: 2,
|
||||
relation: [{ id: 4 }],
|
||||
relation: [{ id: 4, __temp_key__: 'a0' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -813,10 +813,16 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [{ id: 1 }, { id: 2 }],
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'Zz' },
|
||||
{ id: 2, __temp_key__: 'a0' },
|
||||
],
|
||||
},
|
||||
serverState: {
|
||||
relation: [{ id: 2 }, { id: 1 }],
|
||||
relation: [
|
||||
{ id: 2, __temp_key__: 'a0' },
|
||||
{ id: 1, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
@ -825,10 +831,7 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
relation: {
|
||||
connect: [
|
||||
{ id: 2, position: { end: true } },
|
||||
{ id: 1, position: { before: 2 } },
|
||||
],
|
||||
connect: [{ id: 1, position: { before: 2 } }],
|
||||
disconnect: [],
|
||||
},
|
||||
});
|
||||
@ -838,10 +841,17 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [{ id: 3 }, { id: 1 }, { id: 2 }],
|
||||
relation: [
|
||||
{ id: 3, __temp_key__: 'Zz' },
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
serverState: {
|
||||
relation: [{ id: 1 }, { id: 2 }],
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
@ -851,8 +861,6 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
expect(result).toStrictEqual({
|
||||
relation: {
|
||||
connect: [
|
||||
{ id: 2, position: { end: true } },
|
||||
{ id: 1, position: { before: 2 } },
|
||||
{
|
||||
id: 3,
|
||||
position: { before: 1 },
|
||||
@ -867,10 +875,18 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }],
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
{ id: 3, __temp_key__: 'a2' },
|
||||
{ id: 4, __temp_key__: 'a3' },
|
||||
],
|
||||
},
|
||||
serverState: {
|
||||
relation: [{ id: 1 }, { id: 2 }],
|
||||
relation: [
|
||||
{ id: 1, __temp_key__: 'a0' },
|
||||
{ id: 2, __temp_key__: 'a1' },
|
||||
],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
@ -893,5 +909,255 @@ describe('CM || components || EditViewDataManagerProvider || utils || cleanData'
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('given a complicated list of reorderd relations it should only contain the items that moved', () => {
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [
|
||||
{
|
||||
id: 3,
|
||||
__temp_key__: 'Zw',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
__temp_key__: 'Zx',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
__temp_key__: 'Zwl',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
__temp_key__: 'ZwV',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
__temp_key__: 'Zy',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
__temp_key__: 'Zz',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
__temp_key__: 'ZzV',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
__temp_key__: 'a0',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
__temp_key__: 'a0G',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
__temp_key__: 'a0V',
|
||||
},
|
||||
],
|
||||
},
|
||||
serverState: {
|
||||
relation: [
|
||||
{
|
||||
id: 1,
|
||||
__temp_key__: 'Zv',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
__temp_key__: 'Zw',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
__temp_key__: 'Zx',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
__temp_key__: 'Zy',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
__temp_key__: 'Zz',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
__temp_key__: 'a0',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
__temp_key__: 'a1',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
__temp_key__: 'a2',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
__temp_key__: 'a3',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
__temp_key__: 'a4',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
componentsSchema
|
||||
);
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
relation: {
|
||||
connect: [
|
||||
{
|
||||
id: 8,
|
||||
position: {
|
||||
end: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
position: {
|
||||
before: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
position: {
|
||||
before: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
position: {
|
||||
before: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
position: {
|
||||
before: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
position: {
|
||||
before: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
disconnect: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('given a long list of relations and i move the first to the last, only that item should be in the payload', () => {
|
||||
const result = cleanData(
|
||||
{
|
||||
browserState: {
|
||||
relation: [
|
||||
{
|
||||
id: 10,
|
||||
__temp_key__: 'Zu',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
__temp_key__: 'Zv',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
__temp_key__: 'Zw',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
__temp_key__: 'Zx',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
__temp_key__: 'Zy',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
__temp_key__: 'Zz',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
__temp_key__: 'a0',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
__temp_key__: 'a1',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
__temp_key__: 'a2',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
__temp_key__: 'a3',
|
||||
},
|
||||
],
|
||||
},
|
||||
serverState: {
|
||||
relation: [
|
||||
{
|
||||
id: 1,
|
||||
__temp_key__: 'Zv',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
__temp_key__: 'Zw',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
__temp_key__: 'Zx',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
__temp_key__: 'Zy',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
__temp_key__: 'Zz',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
__temp_key__: 'a0',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
__temp_key__: 'a1',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
__temp_key__: 'a2',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
__temp_key__: 'a3',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
__temp_key__: 'a4',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
schema,
|
||||
componentsSchema
|
||||
);
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
relation: {
|
||||
connect: [
|
||||
{
|
||||
id: 10,
|
||||
position: { before: 1 },
|
||||
},
|
||||
],
|
||||
disconnect: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -73,6 +73,7 @@
|
||||
"find-root": "1.1.0",
|
||||
"fork-ts-checker-webpack-plugin": "7.2.1",
|
||||
"formik": "^2.2.6",
|
||||
"fractional-indexing": "3.2.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"highlight.js": "^10.4.1",
|
||||
"history": "^4.9.0",
|
||||
|
@ -12013,6 +12013,11 @@ forwarded@0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||
|
||||
fractional-indexing@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fractional-indexing/-/fractional-indexing-3.2.0.tgz#1193e63d54ff4e0cbe0c79a9ed6cfbab25d91628"
|
||||
integrity sha512-PcOxmqwYCW7O2ovKRU8OoQQj2yqTfEB/yeTYk4gPid6dN5ODRfU1hXd9tTVZzax/0NkO7AxpHykvZnT1aYp/BQ==
|
||||
|
||||
fragment-cache@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
|
||||
@ -17862,6 +17867,8 @@ path-case@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
|
||||
integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=
|
||||
dependencies:
|
||||
no-case "^2.2.0"
|
||||
|
||||
path-dirname@^1.0.0:
|
||||
version "1.0.2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user