mirror of
https://github.com/strapi/strapi.git
synced 2025-09-27 01:09:49 +00:00
Merge branch 'main' into chore/tracking-access-CTB
This commit is contained in:
commit
f62da9d4a4
@ -311,6 +311,10 @@ const reducer = (state = initialState, action) =>
|
|||||||
toSet.private = rest.private;
|
toSet.private = rest.private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rest.pluginOptions) {
|
||||||
|
toSet.pluginOptions = rest.pluginOptions;
|
||||||
|
}
|
||||||
|
|
||||||
const currentAttributeIndex = updatedAttributes.findIndex(
|
const currentAttributeIndex = updatedAttributes.findIndex(
|
||||||
({ name }) => name === initialAttribute.name
|
({ name }) => name === initialAttribute.name
|
||||||
);
|
);
|
||||||
@ -323,6 +327,7 @@ const reducer = (state = initialState, action) =>
|
|||||||
let oppositeAttributeNameToRemove = null;
|
let oppositeAttributeNameToRemove = null;
|
||||||
let oppositeAttributeNameToUpdate = null;
|
let oppositeAttributeNameToUpdate = null;
|
||||||
let oppositeAttributeToCreate = null;
|
let oppositeAttributeToCreate = null;
|
||||||
|
let initialOppositeAttribute = null;
|
||||||
|
|
||||||
const currentUid = get(state, ['modifiedData', ...pathToDataToEdit, 'uid']);
|
const currentUid = get(state, ['modifiedData', ...pathToDataToEdit, 'uid']);
|
||||||
const didChangeTargetRelation = initialAttribute.target !== rest.target;
|
const didChangeTargetRelation = initialAttribute.target !== rest.target;
|
||||||
@ -378,6 +383,29 @@ const reducer = (state = initialState, action) =>
|
|||||||
updatedAttributes.splice(indexToRemove, 1);
|
updatedAttributes.splice(indexToRemove, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In order to preserve plugin options need to get the initial opposite attribute settings
|
||||||
|
if (!shouldRemoveOppositeAttributeBecauseOfTargetChange) {
|
||||||
|
const initialTargetContentType = get(state, [
|
||||||
|
'initialContentTypes',
|
||||||
|
initialAttribute.target,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (initialTargetContentType) {
|
||||||
|
const oppositeAttributeIndex = findAttributeIndex(
|
||||||
|
initialTargetContentType,
|
||||||
|
initialAttribute.targetAttribute
|
||||||
|
);
|
||||||
|
|
||||||
|
initialOppositeAttribute = get(state, [
|
||||||
|
'initialContentTypes',
|
||||||
|
initialAttribute.target,
|
||||||
|
'schema',
|
||||||
|
'attributes',
|
||||||
|
oppositeAttributeIndex,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the opposite attribute
|
// Create the opposite attribute
|
||||||
if (
|
if (
|
||||||
shouldCreateOppositeAttributeBecauseOfRelationTypeChange ||
|
shouldCreateOppositeAttributeBecauseOfRelationTypeChange ||
|
||||||
@ -395,6 +423,10 @@ const reducer = (state = initialState, action) =>
|
|||||||
oppositeAttributeToCreate.private = rest.private;
|
oppositeAttributeToCreate.private = rest.private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initialOppositeAttribute && initialOppositeAttribute.pluginOptions) {
|
||||||
|
oppositeAttributeToCreate.pluginOptions = initialOppositeAttribute.pluginOptions;
|
||||||
|
}
|
||||||
|
|
||||||
const indexOfInitialAttribute = updatedAttributes.findIndex(
|
const indexOfInitialAttribute = updatedAttributes.findIndex(
|
||||||
({ name }) => name === initialAttribute.name
|
({ name }) => name === initialAttribute.name
|
||||||
);
|
);
|
||||||
@ -424,6 +456,10 @@ const reducer = (state = initialState, action) =>
|
|||||||
oppositeAttributeToCreate.private = rest.private;
|
oppositeAttributeToCreate.private = rest.private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initialOppositeAttribute && initialOppositeAttribute.pluginOptions) {
|
||||||
|
oppositeAttributeToCreate.pluginOptions = initialOppositeAttribute.pluginOptions;
|
||||||
|
}
|
||||||
|
|
||||||
if (oppositeAttributeNameToUpdate) {
|
if (oppositeAttributeNameToUpdate) {
|
||||||
const indexToUpdate = updatedAttributes.findIndex(
|
const indexToUpdate = updatedAttributes.findIndex(
|
||||||
({ name }) => name === oppositeAttributeNameToUpdate
|
({ name }) => name === oppositeAttributeNameToUpdate
|
||||||
|
@ -1366,5 +1366,851 @@ describe('CTB | components | DataManagerProvider | reducer | EDIT_ATTRIBUTE', ()
|
|||||||
expect(reducer(state, action)).toEqual(expected);
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Editing a relation and preserve plugin options', () => {
|
||||||
|
it('Should save pluginOptions if the relation is a one side relation (oneWay, manyWay)', () => {
|
||||||
|
const contentTypeUID = 'api::category.category';
|
||||||
|
const updatedTargetUID = 'api::address.address';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [
|
||||||
|
{ name: 'postal_code', type: 'string' },
|
||||||
|
{
|
||||||
|
name: 'one_way',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
targetAttribute: null,
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cover',
|
||||||
|
type: 'media',
|
||||||
|
multiple: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: {},
|
||||||
|
initialComponents: {},
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
relation: 'oneToOne',
|
||||||
|
targetAttribute: null,
|
||||||
|
target: updatedTargetUID,
|
||||||
|
type: 'relation',
|
||||||
|
name: 'one_way',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'contentType',
|
||||||
|
targetUid: contentTypeUID,
|
||||||
|
initialAttribute: {
|
||||||
|
relation: 'oneToOne',
|
||||||
|
targetAttribute: null,
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
name: 'one_way',
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: {},
|
||||||
|
initialComponents: {},
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {},
|
||||||
|
contentType: {
|
||||||
|
...contentType,
|
||||||
|
schema: {
|
||||||
|
...contentType.schema,
|
||||||
|
attributes: [
|
||||||
|
{ name: 'postal_code', type: 'string' },
|
||||||
|
{
|
||||||
|
name: 'one_way',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
targetAttribute: null,
|
||||||
|
target: updatedTargetUID,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cover',
|
||||||
|
type: 'media',
|
||||||
|
multiple: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should preserve plugin options on the opposite attribute if the target is a the same content type and the nature is not a one side relation (oneToOne, ...)', () => {
|
||||||
|
const contentTypeUID = 'api::address.address';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [
|
||||||
|
{ name: 'postal_code', type: 'string' },
|
||||||
|
{
|
||||||
|
name: 'one_to_many',
|
||||||
|
relation: 'oneToMany',
|
||||||
|
targetAttribute: 'many_to_one',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'many_to_one',
|
||||||
|
relation: 'manyToOne',
|
||||||
|
targetAttribute: 'one_to_many',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cover',
|
||||||
|
type: 'media',
|
||||||
|
multiple: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: {},
|
||||||
|
initialComponents: {},
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
relation: 'oneToMany',
|
||||||
|
targetAttribute: 'many_to_one',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
name: 'one_to_many',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'contentType',
|
||||||
|
targetUid: contentTypeUID,
|
||||||
|
initialAttribute: {
|
||||||
|
relation: 'oneToMany',
|
||||||
|
targetAttribute: 'many_to_one',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
name: 'one_to_many',
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: {},
|
||||||
|
initialComponents: {},
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {},
|
||||||
|
contentType: {
|
||||||
|
...contentType,
|
||||||
|
schema: {
|
||||||
|
...contentType.schema,
|
||||||
|
attributes: [
|
||||||
|
{ name: 'postal_code', type: 'string' },
|
||||||
|
{
|
||||||
|
name: 'one_to_many',
|
||||||
|
relation: 'oneToMany',
|
||||||
|
targetAttribute: 'many_to_one',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'many_to_one',
|
||||||
|
relation: 'manyToOne',
|
||||||
|
targetAttribute: 'one_to_many',
|
||||||
|
target: contentTypeUID,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cover',
|
||||||
|
type: 'media',
|
||||||
|
multiple: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should save pluginOptions if the relation is nested inside a component', () => {
|
||||||
|
const contentTypeUID = 'api::address.address';
|
||||||
|
const componentUID = 'default.dish';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'dishes',
|
||||||
|
component: componentUID,
|
||||||
|
type: 'component',
|
||||||
|
repeatable: true,
|
||||||
|
},
|
||||||
|
{ name: 'dynamiczone', type: 'dynamiczone', components: [componentUID] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const component = {
|
||||||
|
uid: componentUID,
|
||||||
|
category: 'default',
|
||||||
|
schema: {
|
||||||
|
icon: 'book',
|
||||||
|
name: 'dish',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: 'components_dishes',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'components',
|
||||||
|
targetUid: componentUID,
|
||||||
|
initialAttribute: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {
|
||||||
|
[componentUID]: {
|
||||||
|
...component,
|
||||||
|
schema: {
|
||||||
|
...component.schema,
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should preserve pluginOptions if the relation is nested inside a component', () => {
|
||||||
|
const contentTypeUID = 'api::address.address';
|
||||||
|
const componentUID = 'default.dish';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'dishes',
|
||||||
|
component: componentUID,
|
||||||
|
type: 'component',
|
||||||
|
repeatable: true,
|
||||||
|
},
|
||||||
|
{ name: 'dynamiczone', type: 'dynamiczone', components: [componentUID] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const component = {
|
||||||
|
uid: componentUID,
|
||||||
|
category: 'default',
|
||||||
|
schema: {
|
||||||
|
icon: 'book',
|
||||||
|
name: 'dish',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: 'components_dishes',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
name: 'category-new',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'components',
|
||||||
|
targetUid: componentUID,
|
||||||
|
initialAttribute: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {
|
||||||
|
[componentUID]: {
|
||||||
|
...component,
|
||||||
|
schema: {
|
||||||
|
...component.schema,
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category-new',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should save pluginOptions if the relation is nested inside a dynamic zone', () => {
|
||||||
|
const contentTypeUID = 'api::address.address';
|
||||||
|
const componentUID = 'default.dish';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [{ name: 'dynamiczone', type: 'dynamiczone', components: [componentUID] }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const component = {
|
||||||
|
uid: componentUID,
|
||||||
|
category: 'default',
|
||||||
|
schema: {
|
||||||
|
icon: 'book',
|
||||||
|
name: 'dish',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: 'components_dishes',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'components',
|
||||||
|
targetUid: componentUID,
|
||||||
|
initialAttribute: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {
|
||||||
|
[componentUID]: {
|
||||||
|
...component,
|
||||||
|
schema: {
|
||||||
|
...component.schema,
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should preserve pluginOptions if the relation is nested inside a dynamic zone', () => {
|
||||||
|
const contentTypeUID = 'api::address.address';
|
||||||
|
const componentUID = 'default.dish';
|
||||||
|
const contentType = {
|
||||||
|
uid: contentTypeUID,
|
||||||
|
schema: {
|
||||||
|
name: 'address',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: '',
|
||||||
|
attributes: [{ name: 'dynamiczone', type: 'dynamiczone', components: [componentUID] }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const component = {
|
||||||
|
uid: componentUID,
|
||||||
|
category: 'default',
|
||||||
|
schema: {
|
||||||
|
icon: 'book',
|
||||||
|
name: 'dish',
|
||||||
|
description: '',
|
||||||
|
connection: 'default',
|
||||||
|
collectionName: 'components_dishes',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: EDIT_ATTRIBUTE,
|
||||||
|
attributeToSet: {
|
||||||
|
name: 'category-new',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forTarget: 'components',
|
||||||
|
targetUid: componentUID,
|
||||||
|
initialAttribute: {
|
||||||
|
name: 'category',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shouldAddComponentToData: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
...initialState,
|
||||||
|
components: { [componentUID]: component },
|
||||||
|
initialComponents: { [componentUID]: component },
|
||||||
|
contentTypes: { [contentTypeUID]: contentType },
|
||||||
|
initialContentTypes: { [contentTypeUID]: contentType },
|
||||||
|
modifiedData: {
|
||||||
|
components: {
|
||||||
|
[componentUID]: {
|
||||||
|
...component,
|
||||||
|
schema: {
|
||||||
|
...component.schema,
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'My super dish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'price',
|
||||||
|
type: 'float',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'category-new',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'api::category.category',
|
||||||
|
targetAttribute: null,
|
||||||
|
type: 'relation',
|
||||||
|
pluginOptions: {
|
||||||
|
myplugin: {
|
||||||
|
example: 'first',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
contentType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -259,6 +259,7 @@ const generateRelation = ({ key, attribute, uid, targetAttribute = {} }) => {
|
|||||||
target: uid,
|
target: uid,
|
||||||
autoPopulate: targetAttribute.autoPopulate,
|
autoPopulate: targetAttribute.autoPopulate,
|
||||||
private: targetAttribute.private || undefined,
|
private: targetAttribute.private || undefined,
|
||||||
|
pluginOptions: targetAttribute.pluginOptions || undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (attribute.relation) {
|
switch (attribute.relation) {
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
"@babel/cli": "7.18.10",
|
"@babel/cli": "7.18.10",
|
||||||
"@babel/core": "7.18.10",
|
"@babel/core": "7.18.10",
|
||||||
"@babel/generator": "7.18.7",
|
"@babel/generator": "7.18.7",
|
||||||
"@babel/parser": "7.18.10",
|
"@babel/parser": "7.18.13",
|
||||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||||
"@babel/plugin-transform-modules-commonjs": "7.18.6",
|
"@babel/plugin-transform-modules-commonjs": "7.18.6",
|
||||||
"@babel/plugin-transform-runtime": "7.18.10",
|
"@babel/plugin-transform-runtime": "7.18.10",
|
||||||
|
17
yarn.lock
17
yarn.lock
@ -648,21 +648,16 @@
|
|||||||
chalk "^2.0.0"
|
chalk "^2.0.0"
|
||||||
js-tokens "^4.0.0"
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
"@babel/parser@7.18.10", "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.17.9", "@babel/parser@^7.18.10", "@babel/parser@^7.18.5", "@babel/parser@^7.18.9", "@babel/parser@^7.7.0", "@babel/parser@^7.8.3":
|
"@babel/parser@7.18.13":
|
||||||
version "7.18.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.10.tgz#94b5f8522356e69e8277276adf67ed280c90ecc1"
|
|
||||||
integrity sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==
|
|
||||||
|
|
||||||
"@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.19.0":
|
|
||||||
version "7.19.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
|
|
||||||
integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
|
|
||||||
|
|
||||||
"@babel/parser@^7.18.13":
|
|
||||||
version "7.18.13"
|
version "7.18.13"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4"
|
||||||
integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==
|
integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==
|
||||||
|
|
||||||
|
"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.17.9", "@babel/parser@^7.18.10", "@babel/parser@^7.18.13", "@babel/parser@^7.18.5", "@babel/parser@^7.18.9", "@babel/parser@^7.19.0", "@babel/parser@^7.7.0", "@babel/parser@^7.8.3":
|
||||||
|
version "7.19.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
|
||||||
|
integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
|
||||||
|
|
||||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
|
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user