mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +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;
|
||||
}
|
||||
|
||||
if (rest.pluginOptions) {
|
||||
toSet.pluginOptions = rest.pluginOptions;
|
||||
}
|
||||
|
||||
const currentAttributeIndex = updatedAttributes.findIndex(
|
||||
({ name }) => name === initialAttribute.name
|
||||
);
|
||||
@ -323,6 +327,7 @@ const reducer = (state = initialState, action) =>
|
||||
let oppositeAttributeNameToRemove = null;
|
||||
let oppositeAttributeNameToUpdate = null;
|
||||
let oppositeAttributeToCreate = null;
|
||||
let initialOppositeAttribute = null;
|
||||
|
||||
const currentUid = get(state, ['modifiedData', ...pathToDataToEdit, 'uid']);
|
||||
const didChangeTargetRelation = initialAttribute.target !== rest.target;
|
||||
@ -378,6 +383,29 @@ const reducer = (state = initialState, action) =>
|
||||
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
|
||||
if (
|
||||
shouldCreateOppositeAttributeBecauseOfRelationTypeChange ||
|
||||
@ -395,6 +423,10 @@ const reducer = (state = initialState, action) =>
|
||||
oppositeAttributeToCreate.private = rest.private;
|
||||
}
|
||||
|
||||
if (initialOppositeAttribute && initialOppositeAttribute.pluginOptions) {
|
||||
oppositeAttributeToCreate.pluginOptions = initialOppositeAttribute.pluginOptions;
|
||||
}
|
||||
|
||||
const indexOfInitialAttribute = updatedAttributes.findIndex(
|
||||
({ name }) => name === initialAttribute.name
|
||||
);
|
||||
@ -424,6 +456,10 @@ const reducer = (state = initialState, action) =>
|
||||
oppositeAttributeToCreate.private = rest.private;
|
||||
}
|
||||
|
||||
if (initialOppositeAttribute && initialOppositeAttribute.pluginOptions) {
|
||||
oppositeAttributeToCreate.pluginOptions = initialOppositeAttribute.pluginOptions;
|
||||
}
|
||||
|
||||
if (oppositeAttributeNameToUpdate) {
|
||||
const indexToUpdate = updatedAttributes.findIndex(
|
||||
({ name }) => name === oppositeAttributeNameToUpdate
|
||||
|
@ -1366,5 +1366,851 @@ describe('CTB | components | DataManagerProvider | reducer | EDIT_ATTRIBUTE', ()
|
||||
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,
|
||||
autoPopulate: targetAttribute.autoPopulate,
|
||||
private: targetAttribute.private || undefined,
|
||||
pluginOptions: targetAttribute.pluginOptions || undefined,
|
||||
};
|
||||
|
||||
switch (attribute.relation) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
"@babel/cli": "7.18.10",
|
||||
"@babel/core": "7.18.10",
|
||||
"@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-transform-modules-commonjs": "7.18.6",
|
||||
"@babel/plugin-transform-runtime": "7.18.10",
|
||||
|
17
yarn.lock
17
yarn.lock
@ -648,21 +648,16 @@
|
||||
chalk "^2.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":
|
||||
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":
|
||||
"@babel/parser@7.18.13":
|
||||
version "7.18.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4"
|
||||
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":
|
||||
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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user